--- title: KeepAlive Router Navigation Fresh vs Cached Problem impact: MEDIUM impactDescription: When using KeepAlive with Vue Router, users may get cached pages when they expect fresh content type: gotcha tags: [vue3, keepalive, vue-router, navigation, cache, ux] --- # KeepAlive Router Navigation Fresh vs Cached Problem **Impact: MEDIUM** - When using KeepAlive with Vue Router, navigation from menus or breadcrumbs may show cached (stale) content when users expect a fresh page. This creates confusing UX where the page appears "stuck" on old data. ## Task Checklist - [ ] Define clear rules for when to use cached vs fresh pages - [ ] Use route keys strategically to control freshness - [ ] Implement `onActivated` to refresh stale data - [ ] Consider navigation source when deciding cache behavior ## The Problem ```vue ``` **Scenario:** 1. User visits `/products?category=shoes` - sees shoes 2. User navigates to `/products?category=hats` - sees hats 3. User clicks "Products" nav link (to `/products`) 4. **Expected:** Fresh products page or default category 5. **Actual:** Still shows hats (cached state)! Users clicking navigation expect a "fresh start" but get the cached state. ## Solutions ### Solution 1: Use Route Full Path as Key ```vue ``` **Tradeoff:** Creates separate cache entry for each unique URL. May increase memory usage. ### Solution 2: Refresh Data on Activation ```vue ``` ### Solution 3: Navigation-Aware Cache Control Different behavior based on how user navigated: ```vue ``` ### Solution 4: Don't Cache Route-Dependent Pages ```vue ``` ### Solution 5: Use Route Meta for Fresh Navigation ```javascript // router.js const routes = [ { path: '/products', component: Products, meta: { keepAlive: true, refreshOnDirectNavigation: true } } ] ``` ```vue ``` ## Best Practice: Be Explicit About Cache Behavior Document your caching rules: ```javascript // cacheRules.js export const CACHE_RULES = { // Always cached - static content, user preferences ALWAYS: ['Dashboard', 'Settings', 'Profile'], // Never cached - dynamic search/filter results NEVER: ['SearchResults', 'FilteredProducts'], // Cached but refreshes on activation STALE_WHILE_REVALIDATE: ['Notifications', 'Messages'] } ``` ## Key Points 1. **User expectation mismatch** - Nav links often imply "fresh" but get cached 2. **Use `fullPath` key carefully** - Prevents reuse but increases memory 3. **Implement `onActivated` refresh** - Check if data needs updating 4. **Don't cache filter/search pages** - These are highly query-dependent 5. **Document cache behavior** - Make rules explicit for your team ## Reference - [Vue.js KeepAlive Documentation](https://vuejs.org/guide/built-ins/keep-alive.html) - [Vue Router Navigation](https://router.vuejs.org/guide/essentials/navigation.html) - [Stack Keep-Alive Library](https://github.com/Zippowxk/stack-keep-alive)