This is the second post on my new blog and it feels so good to be back at writing! Thanks a lot for all the positive feedback on my previous article. Also, don't forget to join the big open source launch party this Thursday (Sept 28th, 2023) on my Twitch channel, starting 15:30! But now back to the topic!
In Nuxt 2, you could already selectively enable SSR or SPA mode based on the page URL with a little trick. However, this approach doesn't work anymore in Nuxt 3. But don't worry, in this article, we will cover three different ways to selectively switch SSR on or off for your site!
A common solution to render parts of your application only on the client is the
<ClientOnly>
This content will not be rendered on the server side
</ClientOnly>
You can even set a few options on the component to control the behavior, such as the content for the server-side fallback, either via props (
<ClientOnly>
This content will not be rendered on the server side
<template #fallback>
This content will be rendered on the server side, ideally this should be some loading state
</template>
</ClientOnly>
While using the
Since the introduction of
export default defineNuxtConfig({
routeRules: {
'/spa-route-rule': { ssr: false }
}
})
This also works for all routes that match a certain pattern, using a wildcard. Then you also have to add the index URL manually though:
export default defineNuxtConfig({
routeRules: {
'/spa-route-rule': { ssr: false },
'/spa-route-rule/**': { ssr: false }
}
})
This is the recommended approach. But sometimes, just choosing the route might not be enough!
Another way to disable SSR, this time for the whole request and not bound to a path, is to set the
export default defineNuxtConfig({
experimental: {
respectNoSSRHeader: true,
},
})
Using the header is a rather uncommon solution, but it might be useful for debugging a staging environment. Also, be aware that this is an experimental feature and could be adapted/changed in the future without a major version bump. As a last note: You might not want to enable this feature in production, as it could be used to disable SSR for all pages.
If you really want some fine-grained control over the SSR/SPA mode, you can always write your own Nitro middleware, very similar to the
export default defineEventHandler((event) => {
if (!event.path.includes('/spa-header-custom')) {
return
}
event.context.nuxt = event.context.nuxt || {}
event.context.nuxt.noSSR = true
})
Be aware that this approach relies on internals, though breaking changes are unlikely to happen here. Also, the
There are many ways to selectively enable or disable SSR in your Nuxt 3 application. And you can see them all in use in this StackBlitz.
The recommended way is to use
I hope this article was helpful to you. If you have any questions, feel free to reach out to me on any of the social networks below. And as usual, please share this article with your friends and colleagues if you liked it. Happy hacking!

I'm Alex, a German web engineering consultant and content creator. Helping companies with my experience in TypeScript, Vue.js, and Nuxt.js is my daily business.
More about meLoading images with a dynamic source often confuses developers that are new to Vue and Nuxt.js. In the following article, I want to demystify the process of dynamic image loading in Vue and Nuxt, and explain why static images can be loaded easily...
Sentry is a great tool to track errors and performance issues in your application - but the Nuxt module is not Nuxt 3 compatible yet. In this article, I'll show you how to integrate Sentry into your Nuxt 3 application, even before the module is ready and also share why it takes longer than you might think to build the module.