sveltesveltekitsvelte-5

How to invalidate an arbitrary cache?


I have a simple +page.ts showing the data string and providing the "Update" button:

<script lang="ts">
    import { invalidateAll } from '$app/navigation';

    const { data } = $props();
</script>

<p>Data: {data.data}</p>
<button onclick={() => invalidateAll()}>Update</button>

I have a universal load in +page.ts which prefers to use some sort of Cache - here it's just a static field in a class:

export async function load() {
    let data = Cache.getData();
    if (data) {
        console.log('Found cached data');
    } else {
        console.log('No cached data - fetching');
        data = 'Fresh new data';
        Cache.setData(data);
    }

    return {
        data
    };
}

class Cache {
    static data?: string;

    static getData() {
        return this.data;
    }

    static setData(data: string) {
        this.data = data;
    }

    static clear() {
        this.data = undefined;
    }
}

console.log('Initializing cache');
Cache.setData('Old cached data');

By design the only way to circumvent this Cache is for the user to explicitly request it by pressing the "Update" button. But how do I tell when the load is caused by invalidation and not by the initial page load in order to clear the cache? Or perhaps even more specifically by pressing the "Update" button? In other words what can I put in the if here:

export async function load() {
    if (/* what goes here? */) {
        Cache.clear();
    }

    ...

Ideally I'm looking for a universal way, not something hacky like setting a window field for CSR or a request header for SSR. Could it be something route related, a query parameter? But how to set these for the invalidate or invalidateAll call?


Solution

  • You should be able to use goto with a query parameter. The function has an options argument where you can set invalidateAll.

    await goto('/route?update', { invalidateAll: true })
    

    (You could also use replaceState afterwards to remove the parameter again.)