N
Nuxt2w ago
Ryan

Do Nuxt server plugins (example.server.ts) execute on every request for a SWR cached route?

Hello, during development and in my local production build I can see that the Nuxt server plugin I've created is executing on every request I make (even if the route is cached), however in my Vercel deployment it does not. This results in sensitive data being leaked across requests. It would be great to know if this is correct behaviour or if I've missed something. Any help would be greatly appreciated! Route rule:
'/': { swr: 3600, cache: { varies: ['x-variant'] } }
'/': { swr: 3600, cache: { varies: ['x-variant'] } }
Example plugin:
import { defineNuxtPlugin, useCookie, useRuntimeConfig, useState } from '#app'

export default defineNuxtPlugin({
name: 'test-server-plugin',
enforce: 'pre',
setup: async (nuxtApp) => {
const identity = useCookie('test-cookie-id', { default: () => '' })

if (nuxtApp.ssrContext?.event.context.exampleId) {
identity.value = exampleId
}

useState<Record<string, boolean | string> | undefined>('test-state-server', () => nuxtApp.ssrContext?.event.context.exampleFlags)
},
})
import { defineNuxtPlugin, useCookie, useRuntimeConfig, useState } from '#app'

export default defineNuxtPlugin({
name: 'test-server-plugin',
enforce: 'pre',
setup: async (nuxtApp) => {
const identity = useCookie('test-cookie-id', { default: () => '' })

if (nuxtApp.ssrContext?.event.context.exampleId) {
identity.value = exampleId
}

useState<Record<string, boolean | string> | undefined>('test-state-server', () => nuxtApp.ssrContext?.event.context.exampleFlags)
},
})
Further context: Supporting SSR & caching with feature flags. We want to cache depending on the feature flag variant used on that page. Server middleware: - Read ID from cookie or generate ID in server middleware - Load flags with the ID - If a flag matches the route, set that value in a custom header so we can generate new cached responses from it using varies. - Set ID & flags we want to use to generate the page(s) from in the event context so we can use it in the server context without refetching Nuxt server-side plugin: - Read ID and flags, set ID in the cookie & flags into state Client side: - Use state to generate page
2 Replies
kapa.ai
kapa.ai2w ago
Hi @Ryan. 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 information provided in the knowledge sources, I can offer some insights into your question about Nuxt server plugins and SWR cached routes. However, it's important to note that the specific behavior you're describing isn't directly addressed in the given documents. Nuxt server plugins, like the one you've shown (example.server.ts), are typically executed on every server-side request. This is because they're part of the server-side rendering process. However, when it comes to cached routes, especially those using SWR (Stale-While-Revalidate), the behavior can be different. According to the Nuxt documentation on Route Rules (https://nuxt.com/docs/guide/concepts/rendering#route-rules), when you use SWR caching:
When the TTL expired, the cached response will be sent while the page will be regenerated in the background.
When the TTL expired, the cached response will be sent while the page will be regenerated in the background.
This suggests that for a cached route, the server might not always execute the full rendering process (including plugins) for every request. The difference you're seeing between your local environment and Vercel deployment could be related to how caching is implemented in these different environments. Vercel might be more aggressive in serving cached content without re-executing server-side code. Regarding your specific use case with sensitive data, it's crucial to be cautious when using caching with data that shouldn't be shared across requests. The Nitro caching documentation (https://nitro.unjs.io/guide/cache#cached-event-handlers) mentions:
All incoming request headers are dropped when handling cached responses. If you define the varies option, only the specified headers will be considered when caching and serving the responses.
All incoming request headers are dropped when handling cached responses. If you define the varies option, only the specified headers will be considered when caching and serving the responses.
This aligns with your route rule where you're using varies: ['x-variant']. To address your concern about sensitive data leakage, you might want to consider: 1. Adjusting your caching strategy, possibly using more granular route rules. 2. Moving sensitive data handling to a non-cached middleware or API route. 3. Using the varies option more extensively to ensure different cache versions for different users/scenarios. It's also worth noting that the behavior of plugins and caching can be complex, especially in a hybrid rendering setup. As mentioned in the Nuxt documentation on Hybrid Rendering (https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering), different routes can have different rendering and caching behaviors. Given the complexity of your setup and the discrepancy between local and production behavior, it might be beneficial to reach out to Nuxt or Vercel support for more specific guidance on how their caching mechanisms interact with server plugins in production environments. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@140617664119832576> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server