预渲染
使用 NuxtHub 时,您需要使用 nuxt build
构建您的应用程序,以便在部署应用程序时保持服务器。
但是,您也可以在构建时预渲染页面,以提高性能并避免服务器上的 CPU 使用率。
路由规则
全局
您可以在 nuxt.config.ts
文件中定义路由规则,以指定每个路由应如何渲染。
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }
}
})
运行 nuxt build
时,Nuxt 将预渲染 /
路由并将 index.html
文件保存在输出目录中。
页面级
也可以使用页面组件中的 defineRouteRules
实用程序在页面级别定义路由规则。
<script setup lang="ts">
defineRouteRules({
prerender: true
})
</script>
<template>
<h1>Hello world!</h1>
</template>
这等效于我们在上面 nuxt.config.ts
文件中的示例。
注意
- 在
~/pages/foo/bar.vue
中定义的规则将应用于/foo/bar
请求。 - 在
~/pages/foo/[id].vue
中的规则将应用于/foo/**
请求。
动态预渲染
在某些情况下,您可能希望 Nuxt 在预渲染特定页面时预渲染其他页面。
这在预渲染博客索引页面时预渲染所有博客文章时很有用。要实现这一点,我们可以在页面组件中使用 prerenderRoutes
实用程序。
<script setup lang="ts">
// Pre-render the /blog page
defineRouteRules({ prerender: true })
const { data: posts } = await useFetch('/api/posts')
// Tell Nuxt to pre-render all blog posts
prerenderRoutes(posts.value.map(post => `/blog/${post.slug}`))
</script>
重要的是告诉 Nuxt 使用 defineRouteRules
预渲染 /blog
,我们也可以在 nuxt.config.ts
文件中全局执行此操作。
export default defineNuxtConfig({
routeRules: {
// If not using `defineRouteRules` in the page component
'/blog': { prerender: true }
}
})
使用 Nuxt 模块
您还可以使用 本地 Nuxt 模块 来预渲染动态页面,如果您没有单个根页面(例如 /blog
)但仍然需要预渲染特定路由(例如 /page-1
、/parent/page-2
等),这特别有用。
import { defineNuxtModule, addPrerenderRoutes } from '@nuxt/kit'
export default defineNuxtModule({
meta: {
name: 'nuxt-prerender-routes',
},
async setup() {
const pages = await getDynamicPages()
addPrerenderRoutes(pages)
},
})
async function getDynamicPages(): string[] {
// Replace this function with the logic for retrieving the slugs for your pages.
return ['/page-1', '/parent/page-2']
}
预渲染所有页面
要拥有与 nuxt generate
相同的行为,同时保持服务器部分,您可以通过配置 nuxt.config.ts
中的 nitro.prerender
选项来预渲染所有页面。
export default defineNuxtConfig({
nitro: {
prerender: {
// Pre-render the homepage
routes: ['/'],
// Then crawl all the links on the page
crawlLinks: true
}
}
})
运行 nuxt build
时,Nuxt 将预渲染所有页面并将 index.html
文件保存在 dist/
目录中。
Cloudflare 100 路由限制
NuxtHub 将为 Cloudflare Pages 生成 dist/_routes.json
,但它有 100 个排除路由(用于静态资产)的限制。
由于每个预渲染的页面都将添加到排除列表中,我们建议您在 nitro.cloudflare.pages.routes.exclude
选项中添加您已知的预渲染模式。
export default defineNuxtConfig({
// ...
nitro: {
cloudflare: {
pages: {
routes: {
exclude: [
// we know that all docs and blog pages are pre-rendered
'/docs/*',
'/blog/*'
]
}
}
}
}
})
警告
如果您在应用程序中使用身份验证,例如 nuxt-auth-utils
,您需要记住,身份验证状态在预渲染过程中将不可用。
例如,如果您有一个标题组件,它要么显示已登录的用户,要么显示登录按钮,您需要将逻辑包装在 <AuthState>
组件中,以便在页面被预渲染时显示占位符。
<script setup lang="ts">
const { loggedIn, user } = useUserSession()
const links = [
{ label: 'Docs', to: '/docs' },
{ label: 'Blog', to: '/blog' }
]
</script>
<template>
<UHeader title="ACME" :links="links">
<template #right>
<AuthState>
<UButton v-if="loggedIn" to="/profile">{{ user.name }}</UButton>
<UButton v-else to="/login">Login</UButton>
<template #placeholder>
<!-- Display loading state -->
<UButton :loading="true" />
</template>
</AuthState>
</template>
</template>