Hybrid Rendering & SSR
Relevant source files
The following files were used as context for generating this wiki page:
Nuxt provides a versatile rendering architecture that supports Server-Side Rendering (SSR), Static Site Generation (SSG), and Hybrid Rendering. This allows developers to toggle between server-side execution and client-side single-page application (SPA) behavior on a per-route basis. The framework automates repetitive tasks such as routing, code-splitting, and pre-fetching to ensure performant, SEO-friendly applications.
Sources: README.md:12-16, test/basic.test.ts:74-88
Rendering Modes and Route Rules
Hybrid rendering is achieved through the definition of route rules that dictate how specific paths should be handled by the Nitro server. These rules allow for granular control, such as disabling SSR for specific routes to enable SPA mode or configuring Incremental Static Regeneration (ISR).
SPA Mode vs. SSR
In SPA mode (ssr: false), Nuxt avoids server-side rendering of the component tree, instead delivering an empty shell (e.g., <div id="__nuxt"></div>) and relying on the client-side bundle to render the application. Conversely, SSR executes the Vue application on the server to generate HTML, which is then hydrated on the client.
Sources: test/basic.test.ts:74-95, packages/nuxt/src/pages/module.ts:684-704
Route Rule Configuration
Route rules are integrated into the Nitro server configuration. If experimental inline route rules are enabled, Nuxt extracts these rules from page metadata via defineRouteRules.
Sources: packages/nuxt/src/pages/module.ts:72-88, packages/nuxt/src/pages/module.ts:119-126
| Rule Option | Description |
|---|---|
ssr | Boolean to enable/disable Server-Side Rendering for a route. |
prerender | Boolean to hint that a route should be generated at build time. |
isr | Enables Incremental Static Regeneration (caching). |
redirect | Configures server-side redirects (e.g., 301, 307). |
Sources: packages/nuxt/src/pages/module.ts:690-704, test/basic.test.ts:74-88, packages/nuxt/src/core/templates.ts:550-570
Architecture and Data Flow
The following diagram illustrates the lifecycle of a request in a hybrid rendering environment:
The data flow involves matching incoming requests against route rules, executing the appropriate rendering engine (SSR or SPA), and returning the resulting assets to the browser.
Sources: packages/nuxt/src/pages/module.ts:600-640, test/basic.test.ts:74-88
Component Islands and Server Components
Nuxt introduces "Component Islands" to allow rendering specific components exclusively on the server, even within an otherwise interactive client-side application. This is particularly useful for reducing client-side bundle sizes and handling sensitive data.
.server Components
Components with the .server.vue extension are rendered only on the server. If a corresponding .client.vue component does not exist, Nuxt treats it as a server-only "island". These components are requested via the /__nuxt_island/ endpoint.
Sources: packages/nuxt/src/components/templates.ts:108-115, test/server-components.test.ts:21-28
Island Implementation Logic
The islandRendererTemplate generates the logic for rendering islands. On the server, it uses defineAsyncComponent to load the component, while on the client, it defaults to a placeholder unless selective hydration is active.
Sources: packages/nuxt/src/core/templates.ts:55-68, packages/nuxt/src/components/templates.ts:125-140
The sequence demonstrates how the client fetches a rendered island from the server using a unique hash based on props and context.
Sources: test/server-components.test.ts:21-28, packages/nuxt/src/components/templates.ts:108-140
Implementation Details
Payload Extraction
For routes that are prerendered or cached (ISR/SWR), Nuxt can extract the state into a _payload.json file. This prevents re-fetching data that was already resolved during the server-side rendering process.
Sources: test/basic.test.ts:951-970, packages/nuxt/src/core/templates.ts:550-560
Template Generation
Nuxt generates various internal modules to support the rendering lifecycle:
routes.mjs: Contains the normalized route tree, including mode metadata (_spaOnly,_noScripts).nitro.client.mjs: ProvidesuseRuntimeConfigfor the client, accessing state injected during SSR viawindow.__NUXT__.fetch.server.mjs: Configures$fetchon the server to route internal requests through Nitro.
Sources: packages/nuxt/src/pages/module.ts:718-732, packages/nuxt/src/core/templates.ts:400-410, packages/nuxt/src/core/templates.ts:500-515
Conclusion
Hybrid rendering and SSR in Nuxt provide a flexible framework for optimizing performance and SEO. By leveraging route rules, developers can mix static generation, server rendering, and client-side navigation. The introduction of server components and islands further refines this by allowing granular control over which parts of a page carry a JavaScript overhead.
Sources: README.md:12-25, packages/nuxt/src/pages/module.ts:850-865