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!
Prelude - The <ClientOnly> component
A common solution to render parts of your application only on the client is the <ClientOnly>
<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 (
fallback-tag
for the tag and
fallback
for content) or via template:
<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
<ClientOnly>
component is a great solution for rendering parts of your application only on the client side, it can be applied only at the component level. Of course, now one could start wrapping the
<NuxtPage>
component in their
app.vue
, which is actually a valid pattern if done for all pages, but not a proper solution when you only want to selectively enable or disable SSR for a few pages. Let's have a look at some solutions now!
Solution 1 - routeRules
routeRules
Since the introduction of routeRoules
routeRule
to your
nuxt.config.ts
:
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
x-nuxt-no-ssr
header to a truthy value, like
true
or
1
when opening the page. If you try this with a default Nuxt application, nothing will happen. This is because the header is not handled by Nuxt by default. However, you can enable it by setting the
experimental.respectNoSSRHeader
option to
true
in your
nuxt.config.ts
:
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.
Solution 3 - A custom Nitro middleware
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 serverMiddleware
/spa-header-custom
:
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
x-nuxt-no-ssr
header is
implemented the same way internally.
Conclusion
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
routeRules
, as it is the most straightforward and future-proof solution. However, if you need more control, you can always use the
x-nuxt-no-ssr
header or write your own Nitro middleware.
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!
Comments
Nothing yet. Say the first thing.
Sign in to join the conversation.