Rendering modes: SSR, static generation, and hybrid
Nuxt supports multiple rendering modes: server-side rendering (default), static rendering via nuxt generate, disabling SSR globally with ssr: false option, and hybrid rendering using the routeRules option.
Nuxt server-side rendering benefits
Nuxt comes with built-in server-side rendering (SSR) by default, providing benefits including faster initial page load time with fully rendered HTML, improved SEO for search engine indexing, reduced JavaScript requirements for low-powered devices, better accessibility for screen readers and assistive technologies, and easier server-side caching.
Vite new URL pattern does not work with SSR
Vite's 'new URL(..., import.meta.url)' pattern does not work with server-side rendering. Await a lazy import before using its URL in server-rendered markup.
Nuxt-specific route rules
Some route rules are Nuxt-specific and control behavior when rendering pages to HTML: ssr, appMiddleware, and noScripts. Some route rules (appMiddleware, redirect, and prerender) also affect client-side behavior.
routeRules example configuration
```ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/api/*': { cache: { maxAge: 60 * 60 } },
'/old-page': {
redirect: { to: '/new-page', status: 302 },
},
},
})
```
This shows prerender for SEO, caching for 1 hour, and redirect rules.
routeRules for hybrid rendering in nuxt.config.ts
routeRules is a Nitro feature that allows customization of how each route is rendered. It is configured in nuxt.config.ts under the routeRules object. Common rule options include prerender (generate at build time), cache (with maxAge in seconds), and redirect (with to and status properties).
Client-only comment placeholders in Nuxt 5
With `compatibilityVersion: 5`, client-only components (`.client.vue` files and `createClientOnly()` wrappers) render an HTML comment (`<!--placeholder-->`) on the server instead of an empty `<div>`. This fixes scoped styles hydration issues when placeholder and component share the same tag name. If relying on placeholder `<div>` for layout, wrap component in `<ClientOnly>` with a `#fallback` slot. Set `experimental.clientNodePlaceholder: false` to revert to previous `<div>` behavior.
No dynamic updates or DOM operations on server during SSR
During server-side rendering, there are no dynamic updates and no DOM operations occur on the server. By default, Vue pauses dependency tracking during SSR for better performance.
Vue app mounting and hydration process
The Vue application is mounted to the DOM by calling app.mount('#__nuxt'). If the application uses SSR or SSG mode, Vue performs a hydration step to make the client-side application interactive. During hydration, Vue recreates the application (excluding Server Components), matches each component to its corresponding DOM nodes, and attaches DOM event listeners.
No reactivity on server side during SSR
There is no reactivity on the server side during SSR because Vue SSR renders the app top-down as static HTML, making it impossible to go back and modify content that has already been rendered.
Avoid side effects in script setup root scope during SSR
You should avoid code that produces side effects needing cleanup in the root scope of <script setup>. For example, setting up timers with setInterval in root scope will persist forever during SSR because unmount hooks are never called. Move side-effect code into onMounted instead.
Vue lifecycle hooks not executed during SSR
During server-side rendering, Vue lifecycle hooks such as onBeforeMount, onMounted, and subsequent hooks are NOT executed. Vue SSR renders the app top-down as static HTML, making it impossible to go back and modify content that has already been rendered.