Ask
29

The save works and the page keeps showing the old value until I hard refresh, what am I supposed to be invalidating?

A form that updates a record. The action runs, the database is updated, no errors anywhere.

The page still shows the previous value. Navigating away and back shows the old value too. A hard refresh shows the new one.

I have tried adding a call to revalidate the path, which sometimes works and sometimes does not, and I cannot see the pattern. I have also seen suggestions to refresh the router, which also sometimes works.

What I am missing is a model of what is actually cached and which of these clears which. At the moment I am adding all of them and hoping, which is clearly not right.

3 answers Share
Report

Answering anonymously, a moderator will review it first.

  • @tags_over_paths · 3w ago

    The practical fix that ends the guessing: tag the data at the fetch, invalidate the tag in the action.

    Paths are the fragile approach because you have to know every route that displays a piece of data, and keep that list correct forever. Add a dashboard that shows the same record and you now have a second path to remember. Nobody remembers.

    With tags, the fetch that loads a record declares what it is, and the action that changes that record invalidates that name. Every page using it updates, and adding a new page requires nothing.

    A convention that works well:

    • A tag for the collection, invalidated on create and delete
    • A tag per record including its id, invalidated on update
    • Both invalidated where it genuinely affects both

    The rule I follow: if you find yourself invalidating three paths in one action, you wanted a tag.

    Two details:

    Tag at the fetch, not at the page. The tag belongs to the data, which is the thing that changed.

    Invalidate after the write succeeds, not before, and not in a branch that can be skipped. A surprising number of these bugs are an early return that skips the invalidation on one code path, which produces exactly your intermittent behaviour.

    26
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
  • @revalidate_what · 3w ago

    You are missing the model, and once you have it the sometimes-works pattern resolves. There are several caches stacked, and each fix clears a different one.

    From the data outwards:

    The data cache. Results of fetches, stored on the server, keyed by URL and by any tags you attached. Invalidating a tag or a path clears entries here.

    The full route cache. Rendered output for static routes, on the server. Path invalidation clears this.

    The client-side router cache. Already-fetched route payloads held in the browser as you navigate. This is the one that surprises people, server-side invalidation does not clear the browser's copy. This is exactly why navigating away and back still shows old data: you are being served the browser's cached payload and the server is never asked.

    So the two symptoms map cleanly:

    • Old value after the action, same page - server-side, needs path or tag invalidation
    • Old value after navigating away and back, client-side router cache

    An action that invalidates a path does signal the client to drop its cache for that route, which is why it works sometimes. When it does not, it is usually because the path you invalidated is not the one the data is displayed on, or you invalidated a page when the layout holds the data.

    30
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report
  • @router_refresh_rui · 3w ago

    On refreshing the router, since you found it sometimes works: it clears the client cache and re-fetches the current route from the server. It does nothing to the server-side caches.

    So it fixes the case where the server already has fresh data and the browser is showing a stale copy. It cannot help when the server is itself serving cached data, you will re-fetch and receive the same stale value, which is the case where you found it did nothing.

    Which gives you the rule for choosing:

    • Server invalidation for things that changed on the server. This is nearly always what you want, and it should be in the action.
    • A router refresh for the narrower case where the client needs to re-read something the server will now render correctly, a session change after login, for example.
    • Both only when you have a specific reason, not by default.

    A debugging move that makes this quick: after the action runs, open the network tab and see whether the browser actually asked the server for anything. If there was no request, it is the client cache. If there was a request and the response contained old data, it is a server cache. That single observation tells you which of the two categories you are in, and you stop guessing.

    And if you are returning updated data from the action itself, be careful that you are not writing a value into the UI that then disagrees with what the next fetch produces. That combination produces a value that appears correct and then reverts, which is a third symptom people conflate with these two.

    21
    Share
    Reply

    Answering anonymously, a moderator will review it first.

    Report