预渲染
使用 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>