Module Options

所有配置均在 nuxt.config.ts 的 swiftConfig 键下声明。框架会在 Nuxt 模块初始化阶段读取这些配置,按需启用对应能力。

配置项总览

配置项类型默认值说明
theme{ mode: 'system' | 'toggle' | 'dark' | 'light', default?: 'auto' | 'light' | 'dark', toggleStates?: 2 | 3 }{ mode: 'toggle', default: 'auto', toggleStates: 3 }主题模式单旋钮。system=跟随系统(无切换器)/toggle=用户可切(挂 useTheme() + SwThemeSwitch)/dark/light=固定单主题({ mode: 'light' } / { mode: 'dark' })
i18nboolean | { enabled: boolean, defaultLocale: string, locales: string[] }{ enabled: true, defaultLocale: 'zh-CN', locales: ['zh-CN'] }多语言。启用后集成 @nuxtjs/i18n 自动注册语言文件。默认仅 zh-CN,多语言项目通过 cli 创建时多选或显式传 locales 数组扩展
pwabooleantruePWA 总开关(Service Worker + manifest)。纯布尔 —— manifest 内容写在 nuxt.config.ts 顶层 pwa.manifest
addToHomescreenboolean | AddToHomescreenOptions跟随 pwa「添加到主屏」引导浮层行为。⚠️ pwa 为 false 时完全不生效(引导内部有独立硬闸)
authboolean | { enabled?: boolean, deviceLogin?: boolean, guardedPaths: string[], guestPaths: string[] }{ deviceLogin: true, guardedPaths: ['/mine'], guestPaths: ['/login', '/register'] }路由守卫 + client auth init。false = 整站关闭(docs 等无 backend 场景);deviceLogin: false = 只关 /login/device 设备登录
obfuscatebooleanprocess.env.NODE_ENV === 'production'JS 混淆(仅 client 产物)。生产默认开启,调试时设 false
websocketbooleantrueWebSocket 插件。启用后注册 $ws
errorHandlerboolean | { enabled?: boolean, endpoint?: string, toast?: boolean }{ enabled: true, endpoint: '/_error-report', toast: false }全局错误监控。捕获 Vue 运行时错误 + unhandledrejection 并上报
stylesboolean | { reset?: boolean, responsive?: boolean, modal?: boolean, toast?: boolean }{ reset: true, responsive: true, modal: true, toast: true }CSS 基础层注入。tokens 永远注入;theme 层按 theme.mode 装配(见 theme 详解)
systemInfoboolean | { enabled?: boolean, endpoint?: string, ignorePaths?: string[], onError?: 'throw' | 'silent', clientRefreshTtl?: number }true(clientRefreshTtl 缺省 300)/system/info 拉取。false = 整站不拉;对象支持自定义端点 + 路径级豁免 + SSR 失败策略(onError,默认 'throw')+ 客户端重拉复用窗口(clientRefreshTtl 秒,0 = 每次整页加载都拉)
suppressConsolebooleantrue生产环境禁用 console.log/warn。false 保留输出
image{ provider?: string, providers?: object, originRules?: array }{ provider: 'noop', providers: {}, originRules: [] }SwImage 外链图 provider 路由。provider 选默认处理器(noop / cf-image / oss-aliyun / cos-tencent / qiniu / imgproxy)。图片质量框架内硬编码(quality=80),不在此处也不是 SwImage prop
manualChunksRecord<string, string[]>{}追加 Vite 自定义分包规则。key = chunk 名,value = 包名片段数组
request{ timeout?: number, uploadTimeout?: number, headers?: Record<string, string>, mock?: { enabled?: boolean, builtins?: boolean, systemInfo?: object }, transport?: 'base64' | 'binary' }{}$request 全局配置:请求超时(默认 20s)、上传超时(默认 600s)、全局 headers、dev 期请求 mock(mock)与加密报文传输编码(transport,默认 'base64')。详见下方 ### request 与 dev 期请求 mock
seo{ aiBotPolicy?: 'allow' | 'disallow', sitemap?: { exclude?: string[], mandatorySources?: string[] } }{ aiBotPolicy: 'allow', sitemap: { exclude: [] } }SEO 套件永久启用。aiBotPolicy 控制 AI 训练 bot(GPTBot/ClaudeBot/CCBot/PerplexityBot)抓取;sitemap.exclude 追加 sitemap.xml 私有路径排除(glob,与 framework 默认合并不替换)。siteUrl 由 NUXT_PUBLIC_SITE_URL 锁定,不在此处暴露。详见下方 ### seo
ad{ showLabel?: boolean }{ showLabel: true }SwAd* 广告家族配置。showLabel 是「广告」合规角标全站默认——组件不传 showAdLabel 时跟随它;组件级显式传值始终优先。详见下方 ### ad
trackerboolean | { enabled?: boolean, autoPageView?: boolean, heartbeatInterval?: number }{ enabled: true, autoPageView: true, heartbeatInterval: 30000 }统一埋点底座(集团 WebSDK / 自建通道)。配置缺失时自动降级静默,无需手动关。详见下方 ### tracker
apiDocs{ source: 'yapi' | 'openapi', url: string, project?: string | number, pathVars?: Record<string,string> }无pnpm generate-api 的接口文档源(构建工具用,模块运行时不读)。接后端时在这里配 source / url(yapi 再加 project),token 放 .env 的 API_DOCS_TOKEN。不进 swift.config.json——那里只放 sw create 那一刻能定的项。详见 Codegen
guardsRecord<护栏名, 'error' | 'warn' | 'off'>全部 error构建期护栏的降级逃生舱:护栏误报时当场解锁(构建日志仍留一行,不会静默)。不进 swift.config.json、CLI 也不管,只能写在 nuxt.config.ts 的 swiftConfig 里。详见 渲染策略 的「逃生舱 guards」一节

数组类默认值是「覆盖」不是「拼接」(framework#384):auth.guardedPaths / auth.guestPaths / i18n.locales 这类数组,只要在 swiftConfig 里显式给了值(含空数组 []),就整体替换默认值,不会把默认项拼回来。唯一例外是 seo.sitemap.exclude —— 它在 sitemap 模块侧与 framework 的私有路径默认追加合并(见下方 ### seo)。

framework 内部使用 moduleDependencies API(@nuxt/kit 4.x)注册 pinia / vueuse / fonts / scripts / sitemap / schema-org / robots(+ 按开关的 i18n / pwa)等子模块,消费方无感。

配置示例

文档站配置(本站实际使用)

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@swift-web/framework'],

  swiftConfig: {
    theme: { mode: 'toggle', default: 'auto', toggleStates: 3 },

    i18n: {
      enabled: true,
      defaultLocale: 'zh-CN',
      locales: ['zh-CN', 'zh-TW', 'en'],
    },

    pwa: true,

    // 文档站无 auth backend(无 /login/device 接口)→ auth: false 整站关闭
    auth: false,

    websocket: false,

    // 文档站不接错误上报后端
    errorHandler: false,

    // 文档站无 /system/info 后端 → 关闭拉取
    systemInfo: false,
  },
})

典型业务项目配置

export default defineNuxtConfig({
  modules: ['@swift-web/framework'],

  swiftConfig: {
    theme: { mode: 'light' },
    i18n: { enabled: false },
    pwa: false,

    auth: {
      guardedPaths: ['/mine', '/profile', '/settings', '/orders'],
      guestPaths: ['/login', '/register'],
    },

    websocket: false,

    errorHandler: {
      enabled: true,
      endpoint: '/_error-report',
    },

    // systemInfo: true(默认;framework 在 SSR 期自动拉 /system/info)
  },
})

各配置项详解

theme

theme 是单旋钮配置:一个 mode 字段同时决定「加载哪套 token」「声明什么 color-scheme」「是否提供切换器」三件事。

mode加载的 tokencolor-scheme切换器
'system'浅色 + 暗色暗色语境下 dark(跟随系统)❌ 不提供
'toggle'浅色 + 暗色暗色语境下 dark✅ 挂 useTheme() + SwThemeSwitch
'dark'固定深色dark❌
'light'(starter 默认)固定浅色light❌
  • default(仅 toggle):切换器初始态,'auto'(跟随系统)/'light'/'dark',默认 'auto'
  • toggleStates(仅 toggle):切换器形态,3=三态(跟随系统/浅/深循环,可随时回到跟随系统)/2=两态(仅浅/深,更简洁,但切换后无法再回到跟随系统),默认 3

toggle 模式下框架在初始化时读取 localStorage 主题偏好并写入 html[data-theme] 属性;搭配 useTheme() 或内置 SwThemeSwitch 组件切换。

固定 dark / light 会无条件声明 color-scheme(分别注入 color-scheme-dark.css / color-scheme-light.css)——这让原生 UI(滚动条、表单控件)跟着站身走,避免「深色页面配浅色滚动条」。

system / toggle 则是按语境声明:只在暗色生效时(@media (prefers-color-scheme: dark) 或 [data-theme='dark'])声明 color-scheme: dark,浅色语境下不声明、走浏览器默认(normal,渲染与浅色一致)。所以「永远声明」只对固定两档成立,别按「任何 mode 下都有 color-scheme」去推断。

theme 只接受对象形态。固定单主题站直接写 { mode: 'light' } 或 { mode: 'dark' }。

i18n

启用后集成 @nuxtjs/i18n 模块,并自动注册 locales 中列出的语言文件(文件放在 i18n/locales/ 目录)。纯中文项目设 false 关闭,可省下 i18n runtime 体积。

pwa

启用后集成 @vite-pwa/nuxt 模块,生成 Service Worker 和 Web App Manifest,支持"添加到桌面"和基础离线访问。不需要 PWA 的项目设 false。addToHomescreen 子配置控制"添加到桌面"引导卡的延迟显示 + 记忆时长。

auth

路由守卫配置 + framework client 端自动 device login。三种形态:

  • false —— 整站无 auth backend(docs 站这种"无 /login/device 接口"场景),framework 跳过 auth.client.ts 的 device login + 全局 login/guest middleware 自然 noop
  • true 或 undefined(默认)—— 使用默认 guardedPaths: ['/mine'] + guestPaths: ['/login', '/register']
  • 对象 { enabled?, deviceLogin?, guardedPaths, guestPaths } —— 自定义守卫路径;enabled: false 等价于顶层传 false 但允许保留路径声明
  • deviceLogin: false —— 只关 /login/device 匿名设备登录,账密 / 二维码 / 注册与「记住我」凭证续登照常。适合「不想为每台新设备多付一次后端请求」的站点。门在 useUserStore().autoLogin() 一处:启动插件、systemInfo 兜底、401 / 2002 重登三条入口都经它。关掉前自查:后端公共接口须接受不带 token 的请求;游客态 user_id 为空,打点 / 错误上报无 userId、靠设备身份的游客级接口不可用

⚠️ 构建期校验(#166):auth 启用时 runtimeConfig.public.deviceKey / tokenKey 必须为非空字符串,否则构建直接报错——空 cookie 名会让客户端 hydration 写 cookie 时整站 500(SSR/curl 看不出来)。无 auth 后端的站点设 auth: false 即免检。

// 文档站 / 演示站 / 无 backend 项目
swiftConfig: {
  auth: false,
  systemInfo: false,
}

// 标准业务项目
swiftConfig: {
  auth: {
    guardedPaths: ['/mine', '/orders', '/settings'],
    guestPaths: ['/login', '/register'],
  },
}

与 framework 内置的全局中间件(login.global.ts / guest.global.ts)配合使用:

  • guardedPaths:需要登录才能访问的路径前缀数组(前缀匹配)
  • guestPaths:已登录用户不可访问的路径,访问时自动跳转到首页

errorHandler

启用后,框架在客户端注册 Vue 全局错误处理器和 unhandledrejection 监听器,捕获到错误时向 endpoint 发送 POST 请求,请求体为错误详情的 JSON。

以下两类不上报:name 为 AbortError 的未处理 rejection(播放被 pause() / 换源打断、AbortController 取消,属有意取消而非故障);stack 里的脚本地址全部是浏览器扩展(chrome-extension:// 等)的错误。没有 stack 的错误照常上报。

  • false:关闭整个错误监控
  • true 或对象 { enabled, endpoint, toast }(字段全可省):开启,对象形式可自定义上报地址(默认 /_error-report)与错误 toast

toast 与上报解耦(#282,v0.97.0):toast 控制错误时是否给终端用户弹「系统出现了一个错误,我们已收到反馈」的可见提示,默认 false——静默上报(对齐 Sentry / Bugsnag 等业界 SDK 的默认行为;内容站一次无关紧要的三方脚本报错就弹窗属纯打扰)。要保留旧版弹 toast 行为需显式 opt-in:

// swift.config.json
"errorHandler": { "enabled": true, "toast": true }

无论开关,dev 期 Vue 错误依然在 console 可见;上报层只控制 POST 行为。

⚠️ 自定义 endpoint 时别放 /api/ 下。 starter 模板(及由它派生的每个项目)的 routeRules['/api/**'] 把整个 /api/** 代理到业务后端,proxy 先于 router 命中即 return —— 放 /api/ 下的本地端点永远打不到,错误报文(含 userId / stack / route / ua)会被代理 发到业务后端拿 404 再静默吞掉,表现为「开了错误监控却一条都收不到,且无任何报错线索」。 默认值 /_error-report 已在 /api/ 之外;端点实现放 server/routes/ 而非 server/api/。 同源约束见 Sitemap 数据源端点。

systemInfo

控制 framework 在 SSR 期是否拉取 /system/info 接口、用什么端点拉、哪些路径跳过。

  • true(默认,等价 { enabled: true, onError: 'throw' }):framework 自动在 SSR 期拉 /system/info 写入 systemStore(请求经 framework request util,SSR 期 deviceId 自动为空)
  • false:整站不拉(无后端 API 场景,如纯静态文档站)
  • { enabled?: boolean, endpoint?: string, ignorePaths?: string[], onError?: 'throw' | 'silent', clientRefreshTtl?: number }:自定义端点 + 路径级豁免 + SSR 失败策略 + 客户端重拉复用窗口
// 整站关闭(docs 站这种"明确无后端"场景)
swiftConfig: {
  systemInfo: false,
}

// 自定义端点 + 部分路径跳过
swiftConfig: {
  systemInfo: {
    endpoint: '/api/system/info',     // 默认 '/system/info'
    ignorePaths: ['/preview', '/embed'],
  },
}

// 容忍 SSR 拉取失败(后端偶发不稳,接受 SEO 字段 client 端补全)
swiftConfig: {
  systemInfo: { onError: 'silent' },
}

// 客户端重拉复用窗口:同一标签页 10 分钟内的整页加载不再打后端;0 = 每次都拉
swiftConfig: {
  systemInfo: { clientRefreshTtl: 600 },
}

clientRefreshTtl —— 客户端重拉的复用窗口(秒,默认 300)

整页加载后 framework 会在客户端后台重拉一次 /system/info,让运营改的配置(广告 / 公告)不必等页面缓存过期。拉到的结果连时间戳存 sessionStorage(键带 cachePrefix),窗口内的整页加载直接复用、不发请求;0 恢复「每次整页加载都拉」。不重拉时整个会话用的是入口页烤进 payload 的那份 systemInfo,新鲜度等于入口页的缓存 TTL,SPA 内跳转本来就不重拉。ISR 首页下这一请求曾是按 PV 计的最大一笔后端负担;改配置最坏 clientRefreshTtl 秒后对新的整页加载生效,手动新开的标签页视为新会话立即重拉(target="_blank" 打开的标签会复制 opener 的 sessionStorage,仍在窗口内)。

onError —— SSR 拉取失败策略

/system/info 在 SSR 期拉取失败时的行为,默认 'throw':

  • 'throw'(默认,推荐)—— fail-fast:抛 createError({ statusCode: 503, fatal: true }),Nuxt 渲染 error.vue。dev 阶段问题立即暴露;生产阶段触发 5xx 监控告警,避免空壳 HTML 被搜索引擎索引。
  • 'silent' —— 容忍失败:仅 console.error + 标记状态,业务页带空 systemInfo 继续渲染,client 端后台静默重拉补救。适合「后端 SLA 高 + 允许 SEO 字段 client 端补全」的场景;代价是 dev 阶段 bug 隐蔽、生产空壳 SEO 损失、监控不触发。

client 端拉取失败不受 onError 控制 —— 始终 console.error、不跳 error.vue。

device 完全 client-only 建立,SSR 期 cookie 没有 deviceId。若后端强制 deviceId 非空,SSR 拉取必败 → 默认 'throw' 触发 503,这是 fail-fast 的预期行为。修法:让后端放行公共接口的空 deviceId、或显式设 onError: 'silent'、或 systemInfo: false。

obfuscate

JS 混淆开关。生产环境默认开启(process.env.NODE_ENV === 'production'),client 构建产物经 javascript-obfuscator 处理后体积略增、可读性大幅降低;调试 / dev 自动关闭。需要在生产环境临时排查 bug 时显式设 false 保留可读代码。

仅混淆 client bundle:server 代码不下发给用户(混淆零收益),且混淆 SSR 产物会破坏 Nitro 对动态 import chunk 的静态追踪,导致运行时 Cannot find module 500。

websocket

是否注册 framework 内置 $ws 实例(含断线重连)。默认 true,不需要 WebSocket 的项目设 false 跳过插件注册 + 减少 client bundle 体积。

styles

CSS 基础层注入开关。framework 自带六层 CSS:

  • tokens.css —— 永远注入(CSS variable 单一事实源,无开关)
  • theme.css —— 在 theme.mode 为 system / toggle 时注入(含浅+暗色两套 token);dark / light 固定模式改注入对应的 color-scheme 声明
  • reset.css —— 由 styles.reset 控制(默认 true)
  • responsive.css —— 由 styles.responsive 控制(默认 true),提供 .sw-container + .sw-show-mobile / .sw-hide-mobile / .sw-hide-tablet / .sw-hide-desktop 响应式工具类(详见 样式与 Token)
  • modal.css —— 由 styles.modal 控制(默认 true),SwModal 默认皮肤(--sw-modal-* 映射语义 token)
  • toast.css —— 由 styles.toast 控制(默认 true),SwToast 默认皮肤(--sw-toast-* 映射语义 token)
// 关闭 framework reset(用 Tailwind preflight 等替代)
styles: { reset: false, responsive: true }

// 完全跳过(项目自带完整 base style)
styles: false

suppressConsole

生产环境是否禁用 console.log / console.warn(保留 console.error),减少信息泄露。默认 true。需要保留输出(如生产环境排查问题)时设 false。dev 期此开关无效。

image

SwImage 外链图 provider 路由配置。仅影响 <SwImage> 渲染外链 URL 时是否经过 CDN 处理器;不影响:

  • 加密图(.bnc 后缀,走 decrypt-image)
  • 本地图(/images/*,走 Nuxt 原生静态)
image: {
  provider: 'noop',                              // 默认处理器:noop / cf-image / oss-aliyun / cos-tencent / qiniu / imgproxy
  providers: {
    'cf-image': { baseURL: 'https://cdn.example.com' },
  },
  originRules: [
    { match: '^https://(oss|img)\\.example\\.com/', use: 'oss-aliyun' },
  ],
}

图片质量(quality)框架内硬编码为 80,不可配置;显示尺寸由 <SwImage> 的 ratio prop 派生(width / height 是内部从 ratio 算出的 <img> 属性,不是 props)。<SwImage> 的完整 props 见 SwImage 文档。

manualChunks

Vite Rollup 自定义 chunk 分包规则。key 是输出的 chunk 名,value 是匹配 npm 包名的片段数组。

manualChunks: {
  'vendor-charts': ['echarts', 'chart.js'],
  'vendor-rich-editor': ['@tiptap/'],
}

适合把"少数业务页面才用"的第三方库(图表 / 富文本编辑器)单独拆 chunk,避免污染主包。

request

framework $request 全局配置。

request: {
  timeout: 20_000,           // 默认 20000ms(20s)。普通请求超时
  uploadTimeout: 600_000,    // 默认 600000ms(10min)。SwUploadImage / SwUploadVideo 等上传超时
  headers: {
    'X-Tenant-Id': 'foo',    // 全局 headers,注入 $request 与 nitroApiFetch 请求
  },
}

业务调 request(url, { timeout: 5000 }) 时 per-request 配置优先。

request.mock —— dev 期请求 mock(framework#100 / #188)

dev 期在请求层(createApiFetch 明文层)统一拦截 mock,仅 dev 生效(SSR + CSR 双端,framework#208),prod build 被 DCE 删净。后端 API 没好时先把 UI / 交互做完,API 好了删 mock 即联调。

  • enabled?: boolean —— mock 总开关。默认随 import.meta.env.DEV(dev 开 / prod 关)。显式 false 临时关掉所有 registerApiMock 拦截。
  • builtins?: boolean —— 内置预设:framework 自带 /login/* + /system/info 的开箱即用假数据。仅在显式 enabled: true 时激活;默认 true(即 enabled 时跟着开)。只想用机制、不要内置假数据时设 false。
  • systemInfo?: object —— 覆盖内置 /system/info skeleton 的字段(浅合并 + header 深合并一层),仅 builtins 激活时生效。

业务接口的 mock 用 registerApiMock 写在一个 dev-only 文件(如 app/plugins/dev-mock.ts),整合时删该文件即可、组件代码不动。

// 开 dev mock:内置 login / system-info 预设也一并生效
request: {
  mock: { enabled: true },
}

// 只用 registerApiMock 机制,不要内置 login / system-info 假数据
request: {
  mock: { enabled: true, builtins: false },
}

完整用法 / matcher / 内置预设说明见 dev 期请求 mock。

request.transport —— 后端加密报文的传输编码(fw#382)

后端加密报文最外层的编码方式,收发同源,必须与后端约定一致。默认 'base64',绝大多数后端适用;仅少数裸二进制协议的 H5 后端(如黄果短剧 yc203 / yc202 系)需改 'binary'。

  • 'base64'(默认):IV‖密文 再 Base64 成文本,以 text/plain 发送。
  • 'binary':IV‖密文 为原始二进制字节流、不做 Base64(请求体发裸字节、响应按 arrayBuffer 读、解密不做 Base64.parse)。

AES-CBC / PKCS7 / gzip / HMAC 派生密钥等核心加解密逻辑两种模式完全一致,只差最外这一层编码。

// 对接裸二进制加密协议的后端
request: {
  transport: 'binary',
}

配错的症状:后端返回 base64 却配了 'binary'(或反之)时报文解不开,控制台抛「响应报文长度异常(N 字节)……多为 request.transport 与后端约定不符」或 Invalid typed array length。框架不做自动识别(各站响应 Content-Type 都写死 application/json,无法作判据),必须显式配置。

server 侧 nitroApiFetch 与 request() 同源一处配置:sitemap / task 等 Nitro 上下文里用的 nitroApiFetch 经 nitro 的 useRuntimeConfig()(无 event 也可用)读 swiftWebFramework.request.transport / timeout / headers,与客户端 request() 是同一个值。applier 只配 swiftConfig.request.transport 一处即可,不需要任何桥接插件或额外环境变量。

request.headers 同时作用于 request()(浏览器与 SSR)和 nitroApiFetch()(Nitro server routes / tasks),不影响 upload。协议头 Content-Type、deviceType、requestId、version、time、language 由框架按大小写不敏感的名称覆盖,不能通过全局 headers 改写。

临时覆盖(不改配置、只在某台机器上切)走 nitro 的嵌套 env 约定:NUXT_PUBLIC_SWIFT_WEB_FRAMEWORK_REQUEST_TRANSPORT=binary。

seo

SEO 子模块永久启用(sitemap / schema-org / robots / og 全套),此处暴露两个字段:

  • aiBotPolicy?: 'allow' | 'disallow' —— 控制 AI 训练爬虫(GPTBot / ClaudeBot / CCBot / PerplexityBot)是否允许抓取。'allow'(默认)允许;'disallow' 在 robots.txt + meta 中显式禁止
  • sitemap?: { exclude?: string[], mandatorySources?: string[] } —— sitemap.xml 私有路径排除,见下

seo.sitemap

sitemap 默认 exclude 已包含通用私有路径(framework#85 GAP3):

/login, /register, /forgot,
/mine/**, /profile/**, /account/**,
/admin/**, /dashboard/**,
/search, /oauth/**

业务自定义私有路径通过 seo.sitemap.exclude 追加(与 framework 默认合并,不是替换)——framework 的默认私有路径清单不可移除,你只能往上加:

// swift.config.json
{
  "framework": {
    "seo": {
      "sitemap": {
        "exclude": ["/link", "/promo-draft", "/transit/**"]
      }
    }
  }
}

字段:

  • exclude?: string[] —— 追加路径列表(micromatch glob 语法)。/login、/mine/** 等通用路径不需要重复声明,framework 已默认包含
  • mandatorySources?: string[] —— 默认关闭;精确同站 JSON 必需源,失败中止 XML 生成并返回安全 503。详见 Sitemap 指南。

sitemap 的 siteUrl(NUXT_PUBLIC_SITE_URL)

sitemap.xml 的 siteUrl 由 环境变量 NUXT_PUBLIC_SITE_URL 锁定(不在 swiftConfig 暴露)。framework 在 module setup 阶段做 host 格式校验:

形态校验结果
undefined / ''❌ 未配置
example.com(漏协议)❌ 不是合法 URL
<your-domain>(占位符)❌ 不是合法 URL
ftp://example.com❌ 协议必须 http/https
https://example.com/api(带 path)❌ 不应包含 path
https://example.com?lang=zh❌ 不应包含 query/hash
https://example.com✅
https://example.com/(末尾斜杠)✅
http://localhost:3000(开发)✅

校验失败时:dev 期 console.warn、production build 期 console.error,但不阻断 build(CI 流水线可能在 build 后注入)。

此值通常由运营 / 运维提供(不是开发自填):

  • 本地开发:.env 配 NUXT_PUBLIC_SITE_URL=http://localhost:3000 或测试环境地址
  • 生产部署:由运维 / CI 流水线注入主域名(如 https://www.example.com)

详细诊断与 nginx 透传配置见 nginx origin 透传配置。

跟 useSeo 的 origin 决策语义不同:sitemap.xml 恒用 NUXT_PUBLIC_SITE_URL(稳定主域名,给搜索引擎看的目录文件应当输出单一稳定 URL 集合);useSeo 的 canonical/og:url 则是配了它就跟着收敛,没配才用 useRequestURL().origin 跟随用户访问域名——framework#278 起该变量是 origin 优先级链的 L2,排在请求头之前(有 ISR 或预渲染页的站点必须配,否则被缓存的页面拿不到 Host)。详见 framework#87 / #85 / #278。

SwAd* 广告家族级配置。目前唯一字段 showLabel——「广告」合规角标(SwAdLabel)的全站默认值:

  • true(默认):所有 SwAd* 组件不传 showAdLabel 时渲染角标。默认偏合规安全侧——忘了关多一个角标只是难看;忘了开则广告无标识,是合规风险。
  • false:全站默认不渲染,适合素材图内已画好广告标识的站点。
  • 组件级 prop show-ad-label 显式传值时始终覆盖本默认(如全站关闭后个别位单独开)。
// nuxt.config.ts —— 素材图自带「广告」标识的站点全局关
swiftConfig: {
  ad: { showLabel: false },
}

升级提示:素材图自带广告标识、不需要组件角标的站点需显式关闭(全局 ad.showLabel: false,或组件级 :show-ad-label="false")。

tracker

集团统一运营数据上报(WebSDK)底座。开启后 framework 在客户端懒加载 WebSDK 并接管埋点,驱动 SwAd* 广告组件的曝光 / 点击上报,以及业务侧 useTracker() / useAdTrack() 的自定义上报。

  • boolean —— true(默认)启用底座;false 完全关闭
  • 对象 { enabled?, autoPageView?, heartbeatInterval? }:
    • enabled?: boolean —— 总开关,默认 true
    • autoPageView?: boolean —— 路由切换自动上报 appPageView,默认 true
    • heartbeatInterval?: number —— 视频播放心跳间隔(毫秒):播放态每 N 毫秒发一次 videoEvent(video_behavior_key: 'video_heartbeat',payload 带累计观看秒 watch_time),支撑「人均播放时长 / 有效播放」指标。默认 30000(30 秒),0 关闭心跳(watch_time 字段仍随其余播放事件上报)

autoPageClick 选项已随 WebSDK v1.1.6 移除——SDK 自动采集 page_click(字段更全、默认开启),见打点底座 · SDK 自动采集事件。

// 默认即启用,无需显式配置;如需关掉自动 pageView:
tracker: { autoPageView: false }

// 完全关闭埋点底座
tracker: false

双重 gate(缺任一静默 no-op):上报实际生效需同时满足 tracker.enabled 为真 + system/info.tracker 返回 appId / encryptedConfig。配置缺失时 framework 自动降级静默(组件埋点照写、运行时不发),无需手动关。

完整事件清单与用法见 打点底座。

相关链接