六维教程

Nuxt4 网站配置

Nuxt 的配置散落在三个地方:nuxt.config.tsapp.config.tsruntimeConfig,新手最容易糊涂的就是「这个值到底该写哪」。

综合对比

三个文件职责不同,先用一句话区分:

  • nuxt.config.ts 管「项目怎么搭、怎么跑」(模块、渲染模式、全局样式、head 等构建配置)。
  • app.config.ts 管「部署后基本不变的展示数据」(站点名、主题色、功能开关)。
  • runtimeConfig 管「会随环境变、或要保密」的值(密钥、接口地址),写在 nuxt.config.tsruntimeConfig 字段里。

下面这张表覆盖更细的维度:

维度 nuxt.config app.config runtimeConfig
写在哪 nuxt.config.ts app.config.ts nuxt.config.tsruntimeConfig 字段
何时确定 构建 + 运行 构建时打包进产物 运行时,可被 .env 覆盖
能用环境变量改吗 部分模块配置可以 不能,改了要重新构建
适合放什么 模块、渲染模式、全局样式、head、各模块参数 站点名、主题色等固定展示数据 API 密钥、会随环境变的接口地址
怎么读 直接写配置项 useAppConfig() useRuntimeConfig()

拿不准时,按这三步判断:

  1. 是「项目怎么搭、怎么跑」的开关吗(模块、SSR、全局样式、head)?→ nuxt.config.ts
  2. 是「全局共享、部署后基本不变」的展示数据吗(站点名、主题色、功能开关)?→ app.config.ts
  3. 是「随环境变化、或不能写进代码库」的敏感 / 可变值吗(密钥、不同环境的 API 地址)?→ runtimeConfig,私密放顶层,前端也要用的放 public 下。

这里有一个常见疑问:head 为什么写在 nuxt.config 而不是 app.config

初学者常以为「站点名、标题」该统一放进 app.config.ts,但 head 相关配置(页面 <title><meta><link>)只能写在 nuxt.config.tsapp.head 里,原因有两点:

  1. Nuxt 只认 nuxt.config.tsapp.head 来生成 HTML 的 <head> 这是框架约定的机制,构建时 Nuxt 读取它往每个页面注入标题、描述、图标等标签。
  2. app.config.ts 只是你自己的全局数据,Nuxt 不会自动拿它填 head。 它导出的对象只有你在组件里主动 useAppConfig() 读取才有意义(比如页脚显示站点名),并没有「head」这个约定字段,写进去浏览器也不会生成任何 <head> 标签。

文章里出现两次 title 容易混淆,注意区分:

  • nuxt.config.tsapp.head.title 是真正生成的页面 <title>(进 SEO、进浏览器标签)。
  • app.config.tstitle 只是你存着在组件里展示用的数据,例如 {{ appConfig.title }} 渲染到页脚,跟 HTML head 无关。

nuxt.config.ts 常用配置

nuxt.config.ts 是整个项目的配置中枢,所有 Nuxt 配置都写在这个根目录文件里,以下是新手最常用的几个配置项:

// nuxt.config.ts
export default defineNuxtConfig({
  // 渲染模式,默认 SSR,设为 false 则纯客户端渲染(SPA)
  ssr: true,

  // 模块,按需添加,比如 @pinia/nuxt、@nuxt/content
  modules: ['@pinia/nuxt'],

  // 全局样式,项目里直接可用
  css: ['~/assets/css/main.css'],

  // 开发工具,浏览器里查看组件树与状态
  devtools: { enabled: true },

  // 兼容性日期,控制新特性的默认开启范围
  compatibilityDate: '2024-10-01',

  // 全局 head 配置(页面里用 useHead / useSeoMeta 覆盖,见 SEO 篇)
  app: {
    head: {
      // <html> 标签上的属性,比如语言
      htmlAttrs: { lang: 'zh-CN' },
      // %s 会被页面自身标题替换,例如页面标题「关于」→ 浏览器标签显示「关于 | 在线工具」
      titleTemplate: '%s | 在线工具',
      title: '在线工具',
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
        { name: 'theme-color', content: '#2563eb' },
        { name: 'description', content: '网站描述' }
      ],
      // 站点图标,文件放在 public/ 下,用根路径 / 引用
      link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
      // 内联脚本:在 <head> 里首屏渲染前执行,避免暗色模式闪烁
      script: [
        {
          innerHTML:
            "(function(){try{var t=localStorage.getItem('theme');var d=t?t==='dark':window.matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.classList.toggle('dark',d);}catch(e){}})();",
          tagPosition: 'head'
        }
      ]
    }
  },

  // 构建引擎 Nitro 的配置,比如部署预设
  nitro: {
    preset: 'node-server'
  }
})

上面的 app.head 里每个字段都是真实会写进 HTML <head> 的,逐个说明:

  • htmlAttrs<html> 标签加属性,这里加了 lang="zh-CN",对 SEO 和无障碍都有好处。
  • title 是整站的兜底标题,页面没单独设置时会用它。
  • titleTemplate%s 占位,页面自己的标题会填进去,比如某页标题是「关于」,浏览器标签最终显示「关于 | 在线工具」。这样既能统一品牌后缀,又不用每页手写。
  • meta 数组里放 <meta> 标签:charset 声明编码、viewport 控制移动端缩放、theme-color 设置浏览器地址栏颜色、description 是给搜索引擎看的站点描述(具体每页的描述在 SEO 篇用 useSeoMeta 设置)。
  • link 数组放 <link> 标签,这里引用站点图标 favicon.ico,文件要放在 public/ 目录下,用根路径 / 引用(静态资源的用法见静态资源篇)。
  • script 数组可以内联或外链脚本,这里用 innerHTML 内联一段暗色模式初始化代码,并用 tagPosition: 'head' 让它在 <head> 里首屏渲染前执行,避免刷新时白底闪一下。

页面内部还可用 useHead / useSeoMeta 覆盖或追加这些配置(见 SEO 篇),nuxt.config 里写的是全站默认值。

除了上面这些,还有 imports(自动导入)、components(组件注册)、dirs(目录别名)、devServer(开发服务器端口)等配置项,需要时可以查阅 Nuxt 配置文档,配置改动后需要重启开发服务器(npm run dev)才会生效。

app.config 与 useAppConfig

app.config.ts 用于存放纯静态的全局数据,比如站点名称、主题色、功能开关。它和 runtimeConfig 的区别见上面的表:构建时确定、不能用环境变量覆盖、改了要重新构建。

// app.config.ts
export default defineAppConfig({
  title: '我的网站',
  themeColor: '#3b82f6',
  features: {
    comment: true
  }
})

在任意组件里用 useAppConfig 读取,它是响应式的,也支持类型推导:

<script setup>
const appConfig = useAppConfig()
</script>

<template>
  <p>{{ appConfig.title }}</p>
</template>

runtimeConfig 与环境变量

敏感信息和环境相关的配置不要硬编码在代码里,用 runtimeConfig

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // 服务端专用,不会暴露给浏览器
    apiSecret: '超级秘密',
    // public 前缀下的内容客户端也能访问
    public: {
      apiBase: 'https://api.example.com'
    }
  }
})

代码中通过 useRuntimeConfig 读取:

// 服务端代码(server/api/ 下)
const config = useRuntimeConfig()
console.log(config.apiSecret)  // 服务端可用

// 客户端代码
const config = useRuntimeConfig()
console.log(config.public.apiBase)  // 客户端读 public 部分

不同环境(本地、线上)用 .env 文件注入,规则是运行时配置名转大写加前缀:

# .env
NUXT_API_SECRET=生产环境的秘密
NUXT_PUBLIC_API_BASE=https://prod-api.example.com

runtimeConfig 中的值只是默认值,同名的环境变量会覆盖它。.env 文件在开发环境自动加载,生产环境通常在部署平台设置,不要提交到 git 仓库。

runtimeConfig 是运行时配置,改值不用重新构建,且敏感值不会暴露给浏览器。

上一篇
Nuxt4 自动导入机制
下一篇
Nuxt4 文件系统路由