Skip to content

Commit 91b0910

Browse files
committed
docs: add pre-rendering page
1 parent 839123b commit 91b0910

File tree

1 file changed

+118
-0
lines changed

1 file changed

+118
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
title: Pre-rendering
3+
description: Pre-render pages at build time for maximum performance and avoid CPU usage on the server.
4+
---
5+
6+
When using NuxtHub, you need to build your application with the [`nuxt build`](https://nuxt.com/docs/api/commands/build) in order to keep your server when deploying your application.
7+
8+
However, you can also pre-render your pages at build time to improve performance and avoid CPU usage on the server.
9+
10+
::tip{to="https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering"}
11+
This is possible thanks to **Nuxt's Hybrid Rendering** to allow different caching rules per route.
12+
::
13+
14+
## Route Rules
15+
16+
### Globally
17+
18+
You can define route rules in your `nuxt.config.ts` to specify how each route should be rendered:
19+
20+
```ts [nuxt.config.ts]
21+
export default defineNuxtConfig({
22+
routeRules: {
23+
'/': { prerender: true }
24+
}
25+
})
26+
```
27+
28+
When running `nuxt build`, Nuxt will pre-render the `/` route and save the `index.html` file in the output directory.
29+
30+
::callout{icon="i-ph-rocket-launch-duotone"}
31+
When deploying with NuxtHub on Cloudflare Pages, it will serve the pre-rendered HTML file directly from the edge for maximum performance and avoid CPU usage on the server.
32+
::
33+
34+
### Page Level
35+
36+
It is also possible to define route rules at the page level using the [`defineRouteRules`](https://nuxt.com/docs/api/utils/define-route-rules) util in the page component:
37+
38+
```vue [pages/index.vue]
39+
<script setup lang="ts">
40+
defineRouteRules({
41+
prerender: true
42+
})
43+
</script>
44+
45+
<template>
46+
<h1>Hello world!</h1>
47+
</template>
48+
```
49+
50+
This is equivalent of our example above in the `nuxt.config.ts` file.
51+
52+
**Notes:**
53+
- A rule defined in `~/pages/foo/bar.vue` will be applied to `/foo/bar` requests.
54+
- A rule in `~/pages/foo/[id].vue` will be applied to `/foo/**` requests.
55+
56+
::important{to="https://nuxt.com/docs/guide/going-further/experimental-features#inlinerouterules"}
57+
As this is an experimental feature, you need to enable it in your `nuxt.config.ts` files with `experimental: { inlineRouteRules: true }`.
58+
::
59+
60+
## Dynamic Pre-rendering
61+
62+
In some cases, you may want to Nuxt to pre-render other pages when pre-rendering a specific page.
63+
64+
This is useful when pre-rendering all the blog posts when pre-rendering the blog index page. To achieve this, we can use the [`prerenderRoutes`](https://nuxt.com/docs/api/utils/prerender-routes) util in the page component:
65+
66+
```vue [pages/blog/index.vue]
67+
<script setup lang="ts">
68+
// Pre-render the /blog page
69+
defineRouteRules({ prerender: true })
70+
71+
const { data: posts } = await useFetch('/api/posts')
72+
73+
// Tell Nuxt to pre-render all blog posts
74+
prerenderRoutes(posts.value.map(post => `/blog/${post.slug}`))
75+
</script>
76+
```
77+
78+
It is important to tell Nuxt to pre-render the `/blog` using the `defineRouteRules`, we can also do it globally in the `nuxt.config.ts` file.
79+
80+
```ts [nuxt.config.ts]
81+
export default defineNuxtConfig({
82+
routeRules: {
83+
// If not using `defineRouteRules` in the page component
84+
'/blog': { prerender: true }
85+
}
86+
})
87+
```
88+
89+
## Caveats
90+
91+
If you are using authentication in your application such as [`nuxt-auth-utils`](https://github.com/Atinux/nuxt-auth-utils), you need to remember that the authentication state will not be available during the pre-rendering process.
92+
93+
For example, if you have a header component that either display the logged in user or a login button, you need to wrap the logic inside [`<ClientOnly>`](https://nuxt.com/docs/api/components/client-only) component to avoid displaying the login button when the user is already logged in.
94+
95+
```vue [components/AppHeader.vue]
96+
<script setup lang="ts">
97+
const { loggedIn, user } = useUserSession()
98+
99+
const links = [
100+
{ label: 'Docs', to: '/docs' },
101+
{ label: 'Blog', to: '/blog' }
102+
]
103+
</script>
104+
105+
<template>
106+
<UHeader title="ACME" :links="links">
107+
<template #right>
108+
<ClientOnly>
109+
<UButton v-if="loggedIn" to="/profile">{{ user.name }}</UButton>
110+
<UButton v-else to="/login">Login</UButton>
111+
<template #fallback>
112+
<!-- Display loading state -->
113+
<UButton :loading="true" />
114+
</template>
115+
</ClientOnly>
116+
</template>
117+
</template>
118+
```

0 commit comments

Comments
 (0)