N
Nuxt4w ago
Zampa

If I have several routes cached with swr, how do I bypass that cache if the user is authenticated?

I want to be able to page cache certain routes, like:
routeRules: {
'/blog/**': { swr: 600 },
}
routeRules: {
'/blog/**': { swr: 600 },
}
but if the user is authenticated:
const { loggedIn } = useUserSession();
const { loggedIn } = useUserSession();
then those routeRules should be disabled. Is this possible via the nuxt config alone?
8 Replies
kapa.ai
kapa.ai4w ago
Hi @Zampa. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the knowledge sources, there isn't a direct way to conditionally apply route rules based on authentication status through the Nuxt config alone. Route rules are applied at the server level and are determined before knowing if a user is authenticated. However, there are a couple of approaches you could consider: 1. Use the private option with useAsyncData:
A recent feature addition to Nuxt allows you to use the private option with useAsyncData. This option changes the default value of server based on the cache settings of the page, which helps when fetching private data on cached routes.
useAsyncData('userData', () => fetchUserData(), { private: true })

useAsyncData('userData', () => fetchUserData(), { private: true })

This ensures that sensitive data fetches aren't done during SSR on cached pages, preventing private data from being included in cached responses GitHub PR #30181. 2. Protect sensitive API routes with server middleware: Even if the page is cached, you can protect your API routes that serve sensitive data:
// server/api/user/data.get.ts
export default defineEventHandler(async (event) => {
// This will throw a 401 error if not authenticated
const { user } = await requireUserSession(event)

// Return user-specific data
return { /* user data */ }
});

// server/api/user/data.get.ts
export default defineEventHandler(async (event) => {
// This will throw a 401 error if not authenticated
const { user } = await requireUserSession(event)

// Return user-specific data
return { /* user data */ }
});

This ensures that even if the page is cached, the dynamic data fetching will still be protected Nuxt Sessions and Authentication. 3. Use client-side middleware for authenticated routes: For routes that should only be accessible to authenticated users, you can use client-side middleware:
// middleware/authenticated.ts
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()

if (!loggedIn.value) {
return navigateTo('/login')
}
})

// middleware/authenticated.ts
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()

if (!loggedIn.value) {
return navigateTo('/login')
}
})

Then apply this middleware to protected pages:
// pages/protected.vue
<script setup>
definePageMeta({
middleware: ['authenticated']
})
</script>

// pages/protected.vue
<script setup>
definePageMeta({
middleware: ['authenticated']
})
</script>

This ensures that unauthenticated users are redirected, even if the page is cached Nuxt Sessions and Authentication. The knowledge sources don't provide a direct method to conditionally disable route rules based on authentication status in the Nuxt config. You might need to implement a combination of the approaches above to handle both caching for public users and dynamic content for authenticated users. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai4w ago
<@230365865697083404> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Zampa
ZampaOP4w ago
Thanks - this works well for caching a server API response, but I'm wanting to actually cache the entire Nuxt page/route itself... so you hit /blog not logged in, it gets served from cache you hit /blog while logged in, it bypasses cache
Zampa
ZampaOP4w ago
GitHub
Fine-grained config of the SSR renderer's Nitro event handler via h...
Describe the feature Hey all 👋🏻 We have defineCachedEventHandler for custom event handlers from Nitro, e.g. for API endpoints. The only scenario where we can't use these at the moment is the ma...
Zampa
ZampaOP4w ago
Maybe something like this would work as a composable called on a given Nuxt page...?
export function usePageCaching() {
const { loggedIn } = useUserSession();

if (!loggedIn.value) {
defineRouteRules({
cache: {
swr: true,
maxAge: 1,
staleMaxAge: 59
},
});
}
}
export function usePageCaching() {
const { loggedIn } = useUserSession();

if (!loggedIn.value) {
defineRouteRules({
cache: {
swr: true,
maxAge: 1,
staleMaxAge: 59
},
});
}
}
nope - the page is never cached by Nitro I guess this is because Nuxt's compiler can only statically analyze this code during build time and correctly apply these rules to the route. It's not dynamic. It's just a compiler macro
Zampa
ZampaOP4w ago
like, I can see in the .nuxt folder that it caches the maybeCached API response just fine
No description
Zampa
ZampaOP4w ago
but I want the actual route to be cached by nitro, like so
No description
Zampa
ZampaOP4w ago
but Nitro should only serve that cached version if the user is not authenticated maybe instead I can use the defineRouteRules as if it should always be cached, and then bypass the cache using server middleware for all paths

Did you find this page helpful?