question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Invalidate fetched URLs

See original GitHub issue

Is your feature request related to a problem? Please describe. Suppose you were building an e-commerce site. You might have a shopping cart icon in your root src/routes/$layout.svelte component. Inside src/routes/products/[category]/[id].svelte you might have an ‘add to cart’ button. When the user clicks the button, the cart icon should update.

One perfectly valid way to model this would be to put the user’s cart on the session store, and then update the store after the POST triggered by ‘add to cart’ succeeds:

async function submit(e) {
  e.preventDefault(); // because we're progressively enhancing the 'add to cart' <form>

  const product = await fetch(this.action, {
    method: this.method,
    body: new FormData(this)
  });

  $session.cart.products = [...$session.cart.products, product];
}

But you might have valid reasons for not wanting to put that data in session — perhaps the cart is only visible on some parts of the app and you don’t want to always pay the cost of serializing the data. Instead, you might do something like this:

<!-- src/routes/$layout.svelte -->
<script context="module">
  export async function load({ fetch }) {
    const cart = await fetch('/cart.json').then(r => r.json());
    return {
      props: { cart }
    };
  }
</script>

This creates a problem. POSTing to /cart.json will add the product(s) to the cart, but will no longer cause the cart icon to update, because the layout component has no way of knowing that the result of fetching /cart.json has changed.

Describe the solution you’d like Since we’re using the passed-in fetch, we know which URLs the layout component depends on. We could therefore expose an API like this:

+// may not be the best place for this functionality, but we can bikeshed that
+import { invalidate } from '$app/navigation';
+
async function submit(e) {
  e.preventDefault(); // because we're progressively enhancing the 'add to cart' <form>

  const product = await fetch(this.action, {
    method: this.method,
    body: new FormData(this)
  });

-  $session.cart.products = [...$session.cart.products, product];
+  invalidate('/cart.json');
}

SvelteKit could straightforwardly keep track of which load functions fetched the invalidated URL, and rerun them (assuming the components they belong to are still mounted), much as we already do for load functions that use session when that store changes value.

Describe alternatives you’ve considered This is a somewhat low-tech solution. A more common approach might be to use a full-blown fat-client state management system that has a copy of the model in memory (see e.g. Firebase). One possibility would be to integrate more closely with such systems or even build one ourselves.

Personally I’m more inclined towards simple, explicit mechanisms that are easy to implement and understand; in any case this would be complementary towards the more full-blown solutions (or at the very least, not in conflict).

Other possibilities that I’m not keen on:

  • Intercepting all non-GET fetches and invalidating all load functions automatically
  • Offering a way to invalidate everything in one go, rather than invalidating specific URLs

How important is this feature to you? It’s a nice-to-have — it solves a problem that can already be solved in various ways, but arguably in a more elegant way. And it’s the one feature I’ve seen in Remix that we don’t already have a (more elegant, IMHO 💅 ) equivalent of that I’m aware of 😃

(Their version re-runs all loaders indiscriminately whenever an ‘action’ — their word for POST/PUT/PATCH/DELETE etc requests — takes place. AFAICT it wouldn’t work with external APIs, just the app’s own endpoint. But it does have the nice characteristic that it runs automatically.)

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
pzuraqcommented, Nov 11, 2021

I have a similar use case, we have some pretty complex fetch statements we’re making base on the query params on the page, and it’s a pain to have reconstruct the entire query string for each invalidate.

1reaction
rodryquinterocommented, May 23, 2022

Does invalidate also updates the URL of the current page? It appears it doesn’t. I have a use case where I would like to share the URL of the page after invalidation. @Rich-Harris @Conduitry

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fetch API cannot load the url. Response for preflight is ...
In my case I was requesting a resource trough http instead of https , so the server was responding with a redirect to...
Read more >
Invalidating files - Amazon CloudFront
Invalidate the file from edge caches. The next time a viewer requests the file, CloudFront returns to the origin to fetch the latest...
Read more >
Can you invalidate cache of transformations from Fetched ...
I currently use the upload API to upload new images to Cloudinary Media Library. I use the API to also invalidate cache of...
Read more >
Automated Re-fetching
Invalidating tags​ ... A mutation can invalidate specific cached data based on the tags. Doing so determines which cached data will be either ......
Read more >
Invalidation — FOSHttpCacheBundle Documentation
By invalidating a piece of content, you tell your HTTP caching proxy to no longer serve it to clients. When next requested, the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found