Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add docs page for prerendering #27286

Merged
merged 2 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 1 addition & 56 deletions docs/1.getting-started/10.deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,62 +71,7 @@ There are two ways to deploy a Nuxt application to any static hosting services:
- Static site generation (SSG) with `ssr: true` pre-renders routes of your application at build time. (This is the default behavior when running `nuxi generate`.) It will also generate `/200.html` and `/404.html` single-page app fallback pages, which can render dynamic routes or 404 errors on the client (though you may need to configure this on your static host).
- Alternatively, you can prerender your site with `ssr: false` (static single-page app). This will produce HTML pages with an empty `<div id="__nuxt"></div>` where your Vue app would normally be rendered. You will lose many SEO benefits of prerendering your site, so it is suggested instead to use [`<ClientOnly>`](/docs/api/components/client-only) to wrap the portions of your site that cannot be server rendered (if any).

### Crawl-based Pre-rendering

Use the [`nuxi generate` command](/docs/api/commands/generate) to build and pre-render your application using the [Nitro](/docs/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`.

```bash [Terminal]
npx nuxi generate
```

That's it! 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 (`<a href="...">`) 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.

::read-more{to="/docs/api/commands/generate#nuxi-generate"}
Read more about the `nuxi generate` command.
::

### Selective Pre-rendering

You can manually specify routes that [Nitro](/docs/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]
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]
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.unjs.io/config#prerender"}
Read more about pre-rendering in the Nitro documentation.
::
:read-more{title="Nuxt prerendering" to="/docs/getting-started/prerendering"}

### Client-side Only Rendering

Expand Down
177 changes: 177 additions & 0 deletions docs/1.getting-started/9.prerendering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
---
title: "Prerendering"
description: Nuxt allows pages to be statically rendered at build time to improve certain performance or SEO metrics
navigation.icon: i-ph-code-block-duotone
---

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/guide/concepts/rendering"}

## Crawl-based Pre-rendering

Use the [`nuxi generate` command](/docs/api/commands/generate) to build and pre-render your application using the [Nitro](/docs/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.

```bash [Terminal]
npx nuxi 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 (`<a href="...">`) 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.

::read-more{to="/docs/api/commands/generate#nuxi-generate"}
Read more about the `nuxi generate` command.
::

### Selective Pre-rendering

You can manually specify routes that [Nitro](/docs/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]
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]
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.unjs.io/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.unjs.io/config/#routerules"}
Read more about Nitro's `routeRules` configuration.
::

As a shorthand, you can also configure this in a page file using [`defineRouteRules`](/docs/api/utils/define-route-rules).

::read-more{to="/docs/guide/going-further/experimental-features#inlinerouterules" icon="i-ph-star-duotone"}
This feature is experimental and in order to use it you must enable the `experimental.inlineRouteRules` option in your `nuxt.config`.
::

```vue [pages/index.vue]
<script setup>
// Or set at the page level
defineRouteRules({
prerender: true,
});
</script>

<template>
<div>
<h1>Homepage</h1>
<p>Pre-rendered at build time</p>
</div>
</template>
```

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/guide/going-further/nuxt-app#the-nuxt-context) to add more routes for Nitro to prerender.

```vue [pages/index.vue]
<script setup>
prerenderRoutes(["/some/other/url"]);
</script>

<template>
<div>
<h1>This will register other routes for prerendering when prerendered</h1>
</div>
</template>
```

:read-more{title="prerenderRoutes" to="/docs/api/utils/prerender-routes"}

### `prerender:routes` Nuxt hook

This is called before prerendering for additional routes to be registered.

```ts [nitro.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 [nitro.config.ts]
export default defineNuxtConfig({
nitro: {
hooks: {
"prerender:generate"(route) {
if (route.route?.includes("private")) {
route.skip = true;
}
},
},
},
});
```