Nuxt.js静态生成SSG #
一、SSG概述 #
静态站点生成(Static Site Generation)是在构建时预先生成 HTML 文件的技术。Nuxt.js 支持完整的静态生成能力。
1.1 SSG优势 #
- 极快加载:静态文件直接由 CDN 提供
- 低成本托管:可部署在任何静态托管服务
- 高安全性:无服务端攻击面
- SEO友好:预渲染的完整 HTML
1.2 适用场景 #
- 博客和文档站点
- 营销页面
- 产品展示网站
- 个人简历
二、生成静态站点 #
2.1 生成命令 #
bash
npx nuxi generate
2.2 输出目录 #
生成的文件位于 .output/public/ 目录。
2.3 预览静态站点 #
bash
npx nuxi preview
三、预渲染配置 #
3.1 预渲染路由 #
nuxt.config.ts:
typescript
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/', '/about', '/contact']
}
}
})
3.2 爬取链接 #
typescript
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true
}
}
})
3.3 动态路由预渲染 #
typescript
export default defineNuxtConfig({
nitro: {
prerender: {
routes: async () => {
const posts = await $fetch('/api/posts')
return posts.map(post => `/blog/${post.slug}`)
}
}
}
})
3.4 忽略路由 #
typescript
export default defineNuxtConfig({
nitro: {
prerender: {
ignore: [
'/admin/**',
'/api/**'
]
}
}
})
四、增量静态再生(ISR) #
4.1 ISR概述 #
ISR 允许在部署后更新静态页面,无需重新构建整个站点。
4.2 配置ISR #
typescript
export default defineNuxtConfig({
routeRules: {
'/blog/**': { isr: 3600 },
'/products/**': { isr: true },
'/': { isr: 1800 }
}
})
4.3 ISR选项 #
| 值 | 说明 |
|---|---|
true |
启用 ISR,永不过期 |
false |
禁用 ISR |
| 数字 | 缓存时间(秒) |
4.4 按需重新验证 #
typescript
export default defineNuxtConfig({
routeRules: {
'/blog/**': {
isr: {
allowQuery: ['preview']
}
}
}
})
五、混合渲染 #
5.1 路由规则 #
typescript
export default defineNuxtConfig({
routeRules: {
'/': { isr: 3600 },
'/blog': { isr: 1800 },
'/blog/**': { isr: 7200 },
'/admin/**': { ssr: false },
'/api/**': { cache: { maxAge: 60 } }
}
})
5.2 规则优先级 #
更具体的规则优先:
typescript
export default defineNuxtConfig({
routeRules: {
'/blog/**': { isr: 3600 },
'/blog/featured': { isr: 1800 }
}
})
六、数据获取 #
6.1 预渲染数据 #
vue
<script setup lang="ts">
const { data } = await useFetch('/api/posts')
const posts = computed(() => data.value || [])
</script>
6.2 动态数据 #
vue
<script setup lang="ts">
const { data } = await useFetch('/api/posts', {
key: 'posts',
getCachedData: (key) => {
const nuxtApp = useNuxtApp()
return nuxtApp.payload.data[key]
}
})
</script>
6.3 客户端数据 #
vue
<script setup lang="ts">
const { data } = await useFetch('/api/user-preferences', {
server: false
})
</script>
七、部署配置 #
7.1 静态托管 #
typescript
export default defineNuxtConfig({
ssr: true,
nitro: {
preset: 'static'
}
})
7.2 Netlify #
typescript
export default defineNuxtConfig({
nitro: {
preset: 'netlify'
}
})
7.3 Vercel #
typescript
export default defineNuxtConfig({
nitro: {
preset: 'vercel'
}
})
7.4 GitHub Pages #
typescript
export default defineNuxtConfig({
app: {
baseURL: '/repo-name/'
},
nitro: {
preset: 'github-pages'
}
})
八、404页面 #
8.1 自定义404 #
error.vue:
vue
<template>
<div class="error-page">
<h1>404</h1>
<p>页面不存在</p>
<NuxtLink to="/">返回首页</NuxtLink>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{
error: {
statusCode: number
message: string
}
}>()
const handleError = () => clearError({ redirect: '/' })
</script>
8.2 静态404 #
typescript
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/404']
}
}
})
九、优化策略 #
9.1 图片优化 #
vue
<script setup lang="ts">
useHead({
link: [
{ rel: 'preload', as: 'image', href: '/hero-image.webp' }
]
})
</script>
9.2 字体优化 #
typescript
export default defineNuxtConfig({
app: {
head: {
link: [
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true }
]
}
}
})
9.3 代码分割 #
Nuxt 自动进行代码分割,无需额外配置。
十、完整示例 #
10.1 博客站点配置 #
nuxt.config.ts:
typescript
export default defineNuxtConfig({
ssr: true,
nitro: {
preset: 'static',
prerender: {
crawlLinks: true,
routes: async () => {
const posts = await $fetch('/api/posts')
const routes = ['/', '/blog', '/about']
posts.forEach((post: any) => {
routes.push(`/blog/${post.slug}`)
})
return routes
}
}
},
routeRules: {
'/': { isr: 3600 },
'/blog': { isr: 1800 },
'/blog/**': { isr: 7200 }
},
app: {
head: {
title: 'My Blog',
meta: [
{ name: 'description', content: 'A static blog built with Nuxt' }
]
}
}
})
10.2 博客文章页面 #
pages/blog/[slug].vue:
vue
<script setup lang="ts">
const route = useRoute()
const slug = route.params.slug as string
const { data: article } = await useFetch(`/api/articles/${slug}`)
if (!article.value) {
throw createError({
statusCode: 404,
message: 'Article not found'
})
}
useHead({
title: article.value.title,
meta: [
{ name: 'description', content: article.value.excerpt },
{ property: 'og:title', content: article.value.title },
{ property: 'og:description', content: article.value.excerpt },
{ property: 'og:image', content: article.value.coverImage }
]
})
</script>
<template>
<article>
<header>
<h1>{{ article.title }}</h1>
<p>{{ article.date }}</p>
</header>
<div v-html="article.content" />
</article>
</template>
十一、最佳实践 #
11.1 构建优化 #
- 使用 ISR 减少构建时间
- 预渲染关键页面
- 懒加载非关键内容
11.2 数据策略 #
- 预渲染静态内容
- 使用 ISR 更新动态内容
- 客户端获取用户特定数据
11.3 缓存策略 #
typescript
export default defineNuxtConfig({
routeRules: {
'/': { isr: 3600 },
'/blog/**': { isr: 86400 },
'/assets/**': { headers: { 'cache-control': 'max-age=31536000' } }
}
})
十二、总结 #
本章介绍了 Nuxt.js 静态站点生成:
- SSG 原理和优势
- 预渲染配置
- 增量静态再生(ISR)
- 混合渲染策略
- 部署配置
- 优化策略
SSG 适合内容型网站,可以提供极致的性能体验,下一章我们将学习部署与最佳实践。
最后更新:2026-03-28