--- title: "Prerendering" description: Nuxt allows pages to be statically rendered at build time to improve certain performance or SEO metrics navigation.icon: i-lucide-file-code-2 --- Nuxt allows for select pages from your application to be rendered at build time. Nuxt will serve the prebuilt pages when requested instead of generating them on the fly. :read-more{title="Nuxt rendering modes" to="/docs/4.x/guide/concepts/rendering"} ## Crawl-based Pre-rendering Use the [`nuxt generate` command](/docs/4.x/api/commands/generate) to build and pre-render your application using the [Nitro](/docs/4.x/guide/concepts/server-engine) crawler. This command is similar to `nuxt build` with the `nitro.static` option set to `true`, or running `nuxt build --prerender`. This will build your site, stand up a nuxt instance, and, by default, prerender the root page `/` along with any of your site's pages it links to, any of your site's pages they link to, and so on. ::code-group{sync="pm"} ```bash [npm] npx nuxt generate ``` ```bash [yarn] yarn nuxt generate ``` ```bash [pnpm] pnpm nuxt generate ``` ```bash [bun] bun x nuxt generate ``` ```bash [deno] deno x nuxt generate ``` :: You can now deploy the `.output/public` directory to any static hosting service or preview it locally with `npx serve .output/public`. Working of the Nitro crawler: 1. Load the HTML of your application's root route (`/`), any non-dynamic pages in your `~/pages` directory, and any other routes in the `nitro.prerender.routes` array. 2. Save the HTML and `payload.json` to the `~/.output/public/` directory to be served statically. 3. Find all anchor tags (``) in the HTML to navigate to other routes. 4. Repeat steps 1-3 for each anchor tag found until there are no more anchor tags to crawl. This is important to understand since pages that are not linked to a discoverable page can't be pre-rendered automatically. ### Payload Extraction Nuxt generates `_payload.json` alongside HTML for: - Prerendered routes (at build time) - ISR/SWR routes (on first request) Payloads contain serialized data from `useAsyncData` and `useFetch`. Client-side navigation loads these cached payloads instead of re-fetching data. Configure dynamic routes like `pages/[...slug].vue` with route rules: `'/**': { isr: true }`. ::read-more{to="/docs/4.x/api/commands/generate#nuxt-generate"} Read more about the `nuxt generate` command. :: ### Selective Pre-rendering You can manually specify routes that [Nitro](/docs/4.x/guide/concepts/server-engine) will fetch and pre-render during the build or ignore routes that you don't want to pre-render like `/dynamic` in the `nuxt.config` file: ```ts twoslash [nuxt.config.ts] // @errors: 2353 export default defineNuxtConfig({ nitro: { prerender: { routes: ['/user/1', '/user/2'], ignore: ['/dynamic'], }, }, }) ``` You can combine this with the `crawlLinks` option to pre-render a set of routes that the crawler can't discover like your `/sitemap.xml` or `/robots.txt`: ```ts twoslash [nuxt.config.ts] // @errors: 2353 export default defineNuxtConfig({ nitro: { prerender: { crawlLinks: true, routes: ['/sitemap.xml', '/robots.txt'], }, }, }) ``` Setting `nitro.prerender` to `true` is similar to `nitro.prerender.crawlLinks` to `true`. ::read-more{to="https://nitro.build/config#prerender"} Read more about pre-rendering in the Nitro documentation. :: Lastly, you can manually configure this using routeRules. ```ts twoslash [nuxt.config.ts] export default defineNuxtConfig({ routeRules: { // Set prerender to true to configure it to be prerendered '/rss.xml': { prerender: true }, // Set it to false to configure it to be skipped for prerendering '/this-DOES-NOT-get-prerendered': { prerender: false }, // Everything under /blog gets prerendered as long as it // is linked to from another page '/blog/**': { prerender: true }, }, }) ``` ::read-more{to="https://nitro.build/config#routerules"} Read more about Nitro's `routeRules` configuration. :: As a shorthand, you can also configure this in a page file using [`defineRouteRules`](/docs/4.x/api/utils/define-route-rules). ::read-more{to="/docs/4.x/guide/going-further/experimental-features#inlinerouterules" icon="i-lucide-star"} This feature is experimental and in order to use it you must enable the `experimental.inlineRouteRules` option in your `nuxt.config`. :: ```vue [app/pages/index.vue] ``` This will be translated to: ```ts [nuxt.config.ts] export default defineNuxtConfig({ routeRules: { '/': { prerender: true }, }, }) ``` ## Runtime Prerender Configuration ### `prerenderRoutes` You can use this at runtime within a [Nuxt context](/docs/4.x/guide/going-further/nuxt-app#the-nuxt-context) to add more routes for Nitro to prerender. ```vue [app/pages/index.vue] ``` :read-more{title="prerenderRoutes" to="/docs/4.x/api/utils/prerender-routes"} ### `prerender:routes` Nuxt hook This is called before prerendering for additional routes to be registered. ```ts [nuxt.config.ts] export default defineNuxtConfig({ hooks: { async 'prerender:routes' (ctx) { const { pages } = await fetch('https://api.some-cms.com/pages').then( res => res.json(), ) for (const page of pages) { ctx.routes.add(`/${page.name}`) } }, }, }) ``` ### `prerender:generate` Nitro hook This is called for each route during prerendering. You can use this for fine-grained handling of each route that gets prerendered. ```ts [nuxt.config.ts] export default defineNuxtConfig({ nitro: { hooks: { 'prerender:generate' (route) { if (route.route?.includes('private')) { route.skip = true } }, }, }, }) ```