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