add-caching
Add client-side caching with stale-while-revalidate strategy. Use when optimizing page load performance or reducing server requests.
Installation
Suivez les instructions du dépôt pour votre agent. Consultez les fichiers et dépendances avant l’installation.
Voir la source ↗GuidesInstructions
Add Caching
Adds client-side caching using remix-client-cache with a stale-while-revalidate (SWR) strategy.
When to Use
- Improving page load performance
- Reducing server requests for frequently accessed data
- Caching loader data across navigations
- User asks to "add caching", "improve performance", or "cache data"
How SWR Works
- Returns cached (stale) data immediately
- Refreshes data in the background
- Hot-swaps updated data when available
Step 1: Configure Global Storage
Location: app/entry.client.tsx
import { configureGlobalCache } from "remix-client-cache";
// Use localStorage for persistent cache
configureGlobalCache(() => localStorage);
// Or sessionStorage (cleared when tab closes)
configureGlobalCache(() => sessionStorage);
Step 2: Create Cached Client Loader
import { createClientLoaderCache } from "remix-client-cache";
import type { Route } from "./+types/my-route";
export async function loader({ request }: Route.LoaderArgs) {
const data = await fetchData();
return { data };
}
// Generate cached client loader
export const clientLoader = createClientLoaderCache({
loader,
// Optional: custom cache key
key: (args) => `products-${args.params.id}`,
});
// Enable client loader hydration
clientLoader.hydrate = true;
Step 3: Use Cached Data in Component
Option A: useCachedLoaderData Hook
import { useCachedLoaderData } from "remix-client-cache";
import type { Route } from "./+types/my-route";
export default function MyRoute() {
const data = useCachedLoaderData<typeof loader>();
return (
<div>
<h1>{data.title}</h1>
</div>
);
}
Option B: CacheRoute Wrapper
import { CacheRoute } from "remix-client-cache";
import type { Route } from "./+types/my-route";
export default function MyRoute() {
return (
<CacheRoute>
{(data) => (
<div>
<h1>{data.title}</h1>
</div>
)}
</CacheRoute>
);
}
Cache Invalidation
After Mutations
import { decacheClientLoader } from "remix-client-cache";
import type { Route } from "./+types/my-route";
export async function clientAction({ request }: Route.ClientActionArgs) {
const result = await submitForm(request);
// Clear the cache for this route
await decacheClientLoader();
return result;
}
Manual Invalidation
import { invalidateCache, useCacheInvalidator } from "remix-client-cache";
// Direct invalidation
await invalidateCache("my-cache-key");
await invalidateCache(["key1", "key2"]);
// Hook-based invalidation
function RefreshButton() {
const invalidate = useCacheInvalidator();
return (
<button onClick={() => invalidate("my-cache-key")}>
Refresh
</button>
);
}
Manual Cache Wrapper
For more control:
import { cacheClientLoader } from "remix-client-cache";
import type { Route } from "./+types/my-route";
export async function clientLoader(args: Route.ClientLoaderArgs) {
return cacheClientLoader(args, {
key: `user-${args.params.id}`,
adapter: () => sessionStorage,
});
}
clientLoader.hydrate = true;
Storage Options
| Storage | Persistence | Use Case |
|---|---|---|
| localStorage | Persists across sessions | User preferences, stable data |
| sessionStorage | Cleared when tab closes | Sensitive or session-specific data |
| In-memory | Cleared on reload | Development, testing |
Best Practices
-
Configure storage early - Set up in
entry.client.tsxbefore hydration -
Use meaningful cache keys - Include dynamic parameters:
products-${productId} - Invalidate after mutations - Always clear cache in clientAction
- Set hydrate = true - Enable proper hydration for cached data
- Consider data freshness - Not all data should be cached
When NOT to Cache
- Real-time data that changes frequently
- User-specific sensitive data (with localStorage)
- Data that must always be fresh
- Small, fast API responses
Anti-Patterns
- Forgetting to invalidate cache after mutations
- Using localStorage for sensitive data
- Caching without considering data freshness
- Not setting
hydrate = trueon clientLoader
Full Reference
See .github/instructions/client-side-caching.instructions.md for comprehensive documentation.
Exemples
Consultez les exemples du dépôt source.
Voir la source ↗Historique source
- Date d’indexation
- 2026-01-20
- Mise à jour de l’index
- 2026-01-26
- Branch
- main
Les dates concernent ce répertoire. Consultez le dépôt pour l’historique du code.
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!