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 路由(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、靠裝置身份的訪客級介面不可用
// 文件站 / 演示站 / 無 backend 專案
swiftConfig: {
  auth: false,
  systemInfo: false,
}

// 標準業務專案
swiftConfig: {
  auth: {
    guardedPaths: ['/mine', '/orders', '/settings'],
    guestPaths: ['/login', '/register'],
  },
}

與 framework 內建的全域中介軟體(login.global.ts / guest.global.ts)配合使用:

  • guardedPaths:需要登入才能存取的路徑前綴陣列(前綴比對)
  • guestPaths:已登入使用者不可存取的路徑,存取時自動跳轉到首頁

⚠️ 建置期校驗(#166):auth 啟用時 runtimeConfig.public.deviceKey / tokenKey 必須為非空字串,否則建置直接報錯——空 cookie 名會讓用戶端 hydration 寫 cookie 時整站 500(SSR/curl 看不出來)。無 auth 後端的站點設 auth: false 即免檢。

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 自動降級靜默(元件埋點照寫、執行時不發),無需手動關。

完整事件清單與用法見 打點底座。

相關連結