[{"data":1,"prerenderedAt":3185},["ShallowReactive",2],{"navigation":3,"search":304,"docs-/docs/getting-started":3033},[4,127],{"title":5,"path":6,"stem":7,"children":8,"page":85,"to":6,"label":5},"Docs","/docs","docs",[9,32,86],{"title":10,"path":11,"stem":12,"children":13,"to":11,"label":10},"介绍","/docs/getting-started","docs/1.getting-started/1.index",[14,15,19,23,27],{"title":10,"path":11,"stem":12,"to":11,"label":10},{"title":16,"path":17,"stem":18,"to":17,"label":16},"安装","/docs/getting-started/installation","docs/1.getting-started/2.installation",{"title":20,"path":21,"stem":22,"to":21,"label":20},"教程：加载 js-confetti","/docs/getting-started/confetti-tutorial","docs/1.getting-started/3.confetti-tutorial",{"title":24,"path":25,"stem":26,"to":25,"label":24},"提交问题","/docs/getting-started/reproductions","docs/1.getting-started/4.reproductions",{"title":28,"path":29,"stem":30,"icon":31,"to":29,"label":28},"贡献","/docs/getting-started/contributing","docs/1.getting-started/5.contributing","i-ph-git-pull-request-duotone",{"title":33,"path":34,"stem":35,"children":36,"page":85,"to":34,"label":33},"Guides","/docs/guides","docs/1.guides",[37,41,45,49,53,57,61,65,69,73,77,81],{"title":38,"path":39,"stem":40,"to":39,"label":38},"关键概念","/docs/guides/key-concepts","docs/1.guides/0.key-concepts",{"title":42,"path":43,"stem":44,"to":43,"label":42},"注册表脚本","/docs/guides/registry-scripts","docs/1.guides/1.registry-scripts",{"title":46,"path":47,"stem":48,"to":47,"label":46},"脚本触发器","/docs/guides/script-triggers","docs/1.guides/1.script-triggers",{"title":50,"path":51,"stem":52,"to":51,"label":50},"预热策略","/docs/guides/warmup","docs/1.guides/1.warmup",{"title":54,"path":55,"stem":56,"to":55,"label":54},"第一方模式","/docs/guides/first-party","docs/1.guides/2.first-party",{"title":58,"path":59,"stem":60,"to":59,"label":58},"打包远程脚本","/docs/guides/bundling","docs/1.guides/3.bundling",{"title":62,"path":63,"stem":64,"to":63,"label":62},"同意管理","/docs/guides/consent","docs/1.guides/3.consent",{"title":66,"path":67,"stem":68,"to":67,"label":66},"脚本事件页面","/docs/guides/page-events","docs/1.guides/3.page-events",{"title":70,"path":71,"stem":72,"to":71,"label":70},"全局脚本","/docs/guides/global","docs/1.guides/4.global",{"title":74,"path":75,"stem":76,"to":75,"label":74},"门面组件","/docs/guides/facade-components","docs/1.guides/5.facade-components",{"title":78,"path":79,"stem":80,"to":79,"label":78},"CORS 和安全属性","/docs/guides/cors","docs/1.guides/6.cors",{"title":82,"path":83,"stem":84,"to":83,"label":82},"v1 迁移指南","/docs/guides/v1-migration","docs/1.guides/6.v1-migration",false,{"title":87,"path":88,"stem":89,"children":90,"page":85,"to":88,"label":87},"Api","/docs/api","docs/3.api",[91,95,99,103,107,111,115,119,123],{"title":92,"path":93,"stem":94,"to":93,"label":92},"useScript","/docs/api/use-script","docs/3.api/1.use-script",{"title":96,"path":97,"stem":98,"to":97,"label":96},"useScriptTriggerConsent","/docs/api/use-script-trigger-consent","docs/3.api/3.use-script-trigger-consent",{"title":100,"path":101,"stem":102,"to":101,"label":100},"useScriptTriggerElement","/docs/api/use-script-trigger-element","docs/3.api/3.use-script-trigger-element",{"title":104,"path":105,"stem":106,"to":105,"label":104},"useScriptTriggerIdleTimeout","/docs/api/use-script-trigger-idle-timeout","docs/3.api/3.use-script-trigger-idle-timeout",{"title":108,"path":109,"stem":110,"to":109,"label":108},"useScriptTriggerInteraction","/docs/api/use-script-trigger-interaction","docs/3.api/3.use-script-trigger-interaction",{"title":112,"path":113,"stem":114,"to":113,"label":112},"useScriptEventPage","/docs/api/use-script-event-page","docs/3.api/4.use-script-event-page",{"title":116,"path":117,"stem":118,"to":117,"label":116},"Nuxt 配置","/docs/api/nuxt-config","docs/3.api/5.nuxt-config",{"title":120,"path":121,"stem":122,"to":121,"label":120},"Nuxt 应用钩子","/docs/api/nuxt-app-hooks","docs/3.api/6.nuxt-app-hooks",{"title":124,"path":125,"stem":126,"to":125,"label":124},"Nuxt 钩子","/docs/api/nuxt-hooks","docs/3.api/6.nuxt-hooks",{"title":128,"path":129,"stem":130,"children":131,"page":85,"to":129,"label":128},"Scripts","/scripts","scripts",[132,145,186,211,224,241,254,287],{"title":133,"path":134,"stem":135,"children":136,"page":85,"to":134,"label":133},"Ads","/scripts/ads","scripts/ads",[137,141],{"title":138,"path":139,"stem":140,"to":139,"label":138},"Carbon Ads 碳广告","/scripts/ads/carbon-ads","scripts/ads/carbon-ads",{"title":142,"path":143,"stem":144,"to":143,"label":142},"Google Adsense","/scripts/ads/google-adsense","scripts/ads/google-adsense",{"title":146,"path":147,"stem":148,"children":149,"page":85,"to":147,"label":146},"Analytics","/scripts/analytics","scripts/analytics",[150,154,158,162,166,170,174,178,182],{"title":151,"path":152,"stem":153,"to":152,"label":151},"Cloudflare Web Analytics","/scripts/analytics/cloudflare-web-analytics","scripts/analytics/cloudflare-web-analytics",{"title":155,"path":156,"stem":157,"to":156,"label":155},"Databuddy Analytics","/scripts/analytics/databuddy-analytics","scripts/analytics/databuddy-analytics",{"title":159,"path":160,"stem":161,"to":160,"label":159},"Fathom Analytics","/scripts/analytics/fathom-analytics","scripts/analytics/fathom-analytics",{"title":163,"path":164,"stem":165,"to":164,"label":163},"Google Analytics","/scripts/analytics/google-analytics","scripts/analytics/google-analytics",{"title":167,"path":168,"stem":169,"to":168,"label":167},"Matomo 分析","/scripts/analytics/matomo-analytics","scripts/analytics/matomo-analytics",{"title":171,"path":172,"stem":173,"to":172,"label":171},"Plausible Analytics","/scripts/analytics/plausible-analytics","scripts/analytics/plausible-analytics",{"title":175,"path":176,"stem":177,"to":176,"label":175},"PostHog","/scripts/analytics/posthog","scripts/analytics/posthog",{"title":179,"path":180,"stem":181,"to":180,"label":179},"Rybbit Analytics","/scripts/analytics/rybbit-analytics","scripts/analytics/rybbit-analytics",{"title":183,"path":184,"stem":185,"to":184,"label":183},"Umami Analytics","/scripts/analytics/umami-analytics","scripts/analytics/umami-analytics",{"title":187,"path":188,"stem":189,"children":190,"page":85,"to":188,"label":187},"Content","/scripts/content","scripts/content",[191,195,199,203,207],{"title":192,"path":193,"stem":194,"to":193,"label":192},"谷歌地图","/scripts/content/google-maps","scripts/content/google-maps",{"title":196,"path":197,"stem":198,"to":197,"label":196},"Instagram 嵌入","/scripts/content/instagram-embed","scripts/content/instagram-embed",{"title":200,"path":201,"stem":202,"to":201,"label":200},"Vimeo 播放器","/scripts/content/vimeo-player","scripts/content/vimeo-player",{"title":204,"path":205,"stem":206,"to":205,"label":204},"X 嵌入","/scripts/content/x-embed","scripts/content/x-embed",{"title":208,"path":209,"stem":210,"to":209,"label":208},"YouTube 播放器","/scripts/content/youtube-player","scripts/content/youtube-player",{"title":212,"path":213,"stem":214,"children":215,"page":85,"to":213,"label":212},"Marketing","/scripts/marketing","scripts/marketing",[216,220],{"title":217,"path":218,"stem":219,"to":218,"label":217},"Clarity","/scripts/marketing/clarity","scripts/marketing/clarity",{"title":221,"path":222,"stem":223,"to":222,"label":221},"Hotjar","/scripts/marketing/hotjar","scripts/marketing/hotjar",{"title":225,"path":226,"stem":227,"children":228,"page":85,"to":226,"label":225},"Payments","/scripts/payments","scripts/payments",[229,233,237],{"title":230,"path":231,"stem":232,"to":231,"label":230},"Lemon Squeezy","/scripts/payments/lemon-squeezy","scripts/payments/lemon-squeezy",{"title":234,"path":235,"stem":236,"to":235,"label":234},"PayPal","/scripts/payments/paypal","scripts/payments/paypal",{"title":238,"path":239,"stem":240,"to":239,"label":238},"Stripe","/scripts/payments/stripe","scripts/payments/stripe",{"title":242,"path":243,"stem":244,"children":245,"page":85,"to":243,"label":242},"Support","/scripts/support","scripts/support",[246,250],{"title":247,"path":248,"stem":249,"to":248,"label":247},"Crisp","/scripts/support/crisp","scripts/support/crisp",{"title":251,"path":252,"stem":253,"to":252,"label":251},"Intercom","/scripts/support/intercom","scripts/support/intercom",{"title":255,"path":256,"stem":257,"children":258,"page":85,"to":256,"label":255},"Tracking","/scripts/tracking","scripts/tracking",[259,263,267,271,275,279,283],{"title":260,"path":261,"stem":262,"to":261,"label":260},"Google Tag Manager","/scripts/tracking/google-tag-manager","scripts/tracking/google-tag-manager",{"title":264,"path":265,"stem":266,"to":265,"label":264},"Meta Pixel","/scripts/tracking/meta-pixel","scripts/tracking/meta-pixel",{"title":268,"path":269,"stem":270,"to":269,"label":268},"Reddit 像素","/scripts/tracking/reddit-pixel","scripts/tracking/reddit-pixel",{"title":272,"path":273,"stem":274,"to":273,"label":272},"Segment","/scripts/tracking/segment","scripts/tracking/segment",{"title":276,"path":277,"stem":278,"to":277,"label":276},"Snapchat 像素","/scripts/tracking/snapchat-pixel","scripts/tracking/snapchat-pixel",{"title":280,"path":281,"stem":282,"to":281,"label":280},"TikTok Pixel","/scripts/tracking/tiktok-pixel","scripts/tracking/tiktok-pixel",{"title":284,"path":285,"stem":286,"to":285,"label":284},"X Pixel","/scripts/tracking/x-pixel","scripts/tracking/x-pixel",{"title":288,"path":289,"stem":290,"children":291,"page":85,"to":289,"label":288},"Utility","/scripts/utility","scripts/utility",[292,296,300],{"title":293,"path":294,"stem":295,"to":294,"label":293},"Google reCAPTCHA","/scripts/utility/google-recaptcha","scripts/utility/google-recaptcha",{"title":297,"path":298,"stem":299,"to":298,"label":297},"Google 登录","/scripts/utility/google-sign-in","scripts/utility/google-sign-in",{"title":301,"path":302,"stem":303,"to":302,"label":301},"NPM","/scripts/utility/npm","scripts/utility/npm",[305,309,315,321,326,331,336,341,346,349,354,359,362,366,371,376,381,386,391,396,402,407,412,417,420,425,430,433,438,443,446,451,456,461,466,469,473,478,483,488,493,498,502,507,512,517,522,527,532,537,540,545,550,554,559,564,569,573,578,581,585,590,595,598,602,607,612,616,621,626,631,636,641,646,651,656,661,666,670,675,680,685,690,695,699,704,709,714,719,724,728,733,738,743,748,753,758,763,768,773,778,783,788,793,798,803,808,813,818,823,828,831,835,839,844,848,852,857,862,867,872,877,882,887,892,897,902,907,912,917,922,927,932,937,940,944,949,954,959,964,967,971,975,978,982,986,991,995,998,1003,1008,1013,1017,1022,1027,1032,1037,1042,1047,1052,1055,1059,1063,1067,1072,1077,1082,1086,1091,1096,1101,1106,1111,1115,1120,1125,1130,1135,1138,1143,1147,1152,1157,1162,1167,1172,1177,1182,1186,1189,1194,1199,1204,1207,1212,1217,1220,1225,1229,1234,1239,1244,1249,1252,1256,1260,1264,1268,1273,1276,1281,1285,1289,1294,1298,1301,1305,1309,1313,1318,1321,1325,1330,1335,1340,1343,1347,1351,1355,1360,1365,1368,1372,1377,1382,1387,1392,1396,1399,1403,1407,1411,1415,1418,1423,1428,1432,1437,1442,1447,1452,1457,1462,1467,1472,1477,1480,1485,1490,1493,1498,1501,1506,1511,1516,1521,1525,1528,1532,1537,1541,1546,1551,1556,1561,1566,1571,1576,1581,1586,1591,1596,1599,1604,1609,1614,1619,1623,1626,1630,1635,1640,1645,1650,1654,1657,1661,1666,1671,1676,1680,1684,1687,1691,1696,1700,1705,1710,1715,1720,1724,1729,1734,1739,1744,1749,1752,1756,1761,1766,1771,1776,1781,1785,1789,1792,1796,1801,1806,1811,1816,1820,1823,1827,1832,1837,1842,1847,1851,1855,1860,1865,1870,1875,1880,1883,1887,1892,1897,1902,1906,1911,1915,1918,1922,1927,1932,1937,1941,1945,1950,1955,1959,1962,1967,1972,1977,1982,1987,1991,1995,2000,2005,2010,2015,2020,2024,2028,2032,2037,2041,2046,2050,2055,2059,2064,2069,2074,2079,2084,2087,2092,2097,2102,2107,2112,2117,2121,2124,2129,2133,2137,2142,2147,2152,2156,2161,2165,2168,2172,2177,2181,2186,2191,2195,2199,2204,2209,2214,2218,2221,2226,2230,2234,2238,2242,2246,2250,2253,2257,2262,2266,2270,2275,2280,2285,2289,2293,2297,2302,2307,2311,2314,2318,2323,2328,2332,2336,2340,2343,2347,2352,2357,2361,2365,2369,2372,2377,2381,2385,2389,2394,2399,2403,2406,2410,2414,2418,2421,2425,2429,2434,2438,2442,2446,2451,2455,2460,2464,2467,2472,2476,2480,2484,2489,2493,2497,2502,2507,2512,2516,2519,2524,2528,2532,2536,2540,2544,2549,2553,2558,2563,2567,2571,2574,2578,2583,2588,2593,2598,2603,2606,2611,2616,2620,2625,2629,2634,2639,2644,2649,2654,2657,2661,2665,2670,2675,2680,2684,2688,2691,2695,2699,2704,2709,2713,2717,2721,2724,2728,2732,2737,2742,2746,2750,2754,2757,2761,2765,2770,2775,2779,2784,2788,2791,2795,2799,2804,2809,2813,2817,2821,2826,2831,2834,2838,2842,2847,2852,2856,2860,2864,2867,2871,2876,2881,2885,2889,2894,2899,2904,2909,2914,2917,2921,2926,2930,2934,2939,2944,2949,2952,2957,2962,2967,2971,2976,2981,2986,2989,2994,2999,3004,3008,3011,3015,3020,3025,3029],{"id":11,"title":10,"titles":306,"content":307,"level":308,"path":11,"to":11,"label":10},[],"Nuxt Scripts 是用于第三方脚本的 Nuxt 开发者体验（DX）。 Nuxt Scripts 在将第三方脚本整合到 Nuxt 应用中时，提升了性能、隐私和开发者体验（DX）。",1,{"id":310,"title":311,"titles":312,"content":313,"level":314,"path":310,"to":310,"label":311},"/docs/getting-started#背景","背景",[10],"使用 useHead 组合式函数加载第三方 IIFE 脚本很简单，但在服务器端渲染（SSR）、懒加载和类型安全方面会遇到复杂问题。Nuxt Scripts 通过优化第三方脚本的集成，解决了这些挑战，从而提高性能、隐私和整体开发体验。",2,{"id":316,"title":317,"titles":318,"content":319,"level":320,"path":316,"to":316,"label":317},"/docs/getting-started#第三方脚本的挑战","第三方脚本的挑战",[10,311],"在客户端和服务器端环境中的兼容性。采用最佳实践的默认设置。细粒度的优化控制。避免阻碍渲染、隐私问题和性能瓶颈。确保类型安全和脚本验证。与第三方服务器相关的安全考虑。",3,{"id":322,"title":323,"titles":324,"content":325,"level":320,"path":322,"to":322,"label":323},"/docs/getting-started#第三方如何影响用户体验","第三方如何影响用户体验",[10,311],"第三方资源如分析工具、视频嵌入、地图和社交媒体集成功能增强了网站功能，但并非由网站所有者直接管理。单个资源的性能影响或许很小，但多个资源会显著降低用户体验。脚本尤其可能延迟交互响应并阻碍页面渲染。 根据 Chrome 用户体验报告，拥有众多第三方资源的 Nuxt 站点通常获得较低的 Interaction to Next Paint (INP) 和 Largest Contentful Paint (LCP) 分数。尽管这种相关性不代表因果关系，实验室测试和 Web 年鉴 均证实第三方资源对性能有显著影响。",{"id":327,"title":328,"titles":329,"content":330,"level":314,"path":327,"to":327,"label":328},"/docs/getting-started#nuxt-script-功能","Nuxt Script 功能",[10],"",{"id":332,"title":333,"titles":334,"content":335,"level":320,"path":332,"to":332,"label":333},"/docs/getting-started#️-性能","🏎️ 性能",[10,328],"脚本加载默认仅在 Nuxt 准备好后触发。更高级的脚本加载触发方式，与具体实现无关。通过远程脚本打包提升脚本加载速度。",{"id":337,"title":338,"titles":339,"content":340,"level":320,"path":337,"to":337,"label":338},"/docs/getting-started#开发者体验","😌 开发者体验",[10,328],"为常见第三方应用提供精选脚本注册表。简化分析事件管理，例如页面浏览跟踪。脚本选项输入校验。类型安全与 SSR 兼容的 API。",{"id":342,"title":343,"titles":344,"content":345,"level":320,"path":342,"to":342,"label":343},"/docs/getting-started#隐私","🔒 隐私",[10,328],"通过远程脚本打包最小化用户数据暴露。集成的用户同意管理。增强的脚本隐私设置，例如 crossorigin=\"anonymous\" 和 referrerpolicy=\"no-referrer\"。",{"id":17,"title":16,"titles":347,"content":348,"level":308,"path":17,"to":17,"label":16},[],"了解如何创建一个 Nuxt Scripts 项目或将其添加到您当前的 Nuxt 项目中。",{"id":350,"title":351,"titles":352,"content":353,"level":314,"path":350,"to":350,"label":351},"/docs/getting-started/installation#快速开始","快速开始",[16],"要开始，只需运行： npx nuxi@latest module add scripts !TIP\n使用 skilld 为此包生成一个代理技能：npx skilld add @nuxt/scripts 就是这样！Nuxt Scripts 模块将被下载并添加到您的 Nuxt 配置的 modules 中。",{"id":355,"title":356,"titles":357,"content":358,"level":314,"path":355,"to":355,"label":356},"/docs/getting-started/installation#下一步","下一步",[16],"需要一些灵感来开始使用 Nuxt Scripts 吗？试试以下内容： 🎉 使用 彩带教程 让表情符号飞起来。📚 了解 脚本加载 的工作原理。🔍 探索受欢迎的预配置第三方脚本的 脚本注册表。🚀 使用 useScript 或 全局脚本 加载其他脚本。🔨 通过 打包 和 同意管理 微调您的性能和隐私。 html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":21,"title":20,"titles":360,"content":361,"level":308,"path":21,"to":21,"label":20},[],"学习如何使用 Nuxt Scripts 模块加载 js-confetti 脚本。",{"id":363,"title":10,"titles":364,"content":365,"level":314,"path":363,"to":363,"label":10},"/docs/getting-started/confetti-tutorial#介绍",[20],"在本教程中，您将学习如何使用 Nuxt Scripts 模块加载 js-confetti 脚本。 您将了解以下内容： 什么是 useScriptNpm 注册脚本。如何使用它来加载 js-confetti 脚本。为加载的脚本添加类型。使用代理函数调用脚本。",{"id":367,"title":368,"titles":369,"content":370,"level":314,"path":367,"to":367,"label":368},"/docs/getting-started/confetti-tutorial#关于-usescriptnpm-的背景","关于 useScriptNpm 的背景",[20],"要加载脚本，我们将使用 useScriptNpm。 这是一个注册脚本，是建立在 useScript 组合式函数之上的受支持第三方集成，允许您从 NPM 加载脚本。 在使用 NPM 文件时，通常会将它们作为 node_module 依赖项包含在 package.json 文件中。然而，优化这些脚本的加载可能很困难，通常需要从单独的代码块动态导入模块，并且只在需要时加载。它还会降低构建速度，因为模块需要被转译。 useScriptNpm 注册脚本抽象了此过程，允许您用一行代码加载那些被导出为可立即调用函数的脚本。 在许多情况下，将脚本作为 package.json 文件中的依赖项可能仍更合理，但对于不常用或对应用不关键的脚本，这可以是一个很好的替代方案。 最开始我们可以将使用该脚本视为 useHead 组合式函数的替代。您可以在以下代码示例中看到抽象层的比较。 useScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n})\nuseScript('https://cdn.jsdelivr.net/npm/js-confetti@0.12.0/dist/js-confetti.browser.js')\nuseHead({\n  script: [\n    { src: 'https://cdn.jsdelivr.net/npm/js-confetti@latest/dist/js-confetti.browser.js' }\n  ]\n})",{"id":372,"title":373,"titles":374,"content":375,"level":320,"path":372,"to":372,"label":373},"/docs/getting-started/confetti-tutorial#加载脚本","加载脚本",[20,368],"在您的某个组件中，您将需要加载该脚本。您可以通过使用 useScriptNpm 注册脚本来实现。 \u003Cscript setup lang=\"ts\">\nuseScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n})\n\u003C/script> 如果检查浏览器请求，您应该会看到脚本被加载。",{"id":377,"title":378,"titles":379,"content":380,"level":320,"path":377,"to":377,"label":378},"/docs/getting-started/confetti-tutorial#解析第三方脚本-api","解析第三方脚本 API",[20,368],"脚本加载完成后，您可以在组件中使用它。为此，我们需要告诉底层 API 如何使用该脚本，为此可以利用 use 函数。 该函数只会在客户端调用，用于解析第三方脚本。 \u003Cscript setup lang=\"ts\">\nuseScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n  scriptOptions: {\n    // 告诉 useScript 如何解析第三方脚本\n    use() {\n      return { JSConfetti: window.JSConfetti }\n    },\n  },\n})\n\u003C/script>",{"id":382,"title":383,"titles":384,"content":385,"level":320,"path":382,"to":382,"label":383},"/docs/getting-started/confetti-tutorial#使用第三方脚本-api","使用第三方脚本 API",[20,368],"既然我们有了解析第三方脚本 API 的方法，就可以开始使用它了。 js-confetti 库要求每次使用时都要实例化一个 JSConfetti 类的新实例，最兼容的处理方式是显式等待脚本加载完成。 但是，如果您喜欢更便捷的 API，也可以使用代理函数。需要注意的是，当在页面之间切换时，这种方式会失效，因为需要在页面间调用 new window.JSConfetti()。 \u003Cscript setup lang=\"ts\">\nconst { onLoaded } = useScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n  scriptOptions: {\n    use() {\n      return { JSConfetti: window.JSConfetti }\n    },\n  },\n})\nonLoaded(({ JSConfetti }) => {\n  // 使用真实的 API 实例\n  const confetti = new JSConfetti()\n  confetti.addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })\n})\n\u003C/script>\n\u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n  scriptOptions: {\n    use: () => typeof window.JSConfetti !== 'undefined' && new window.JSConfetti()\n  }\n})\nonMounted(() => {\n  // 直接使用\n  proxy.addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })\n})\n\u003C/script> 恭喜！脚本加载后您应该能看到一些表情符号。 不过，您会注意到类型有问题。addConfetti 函数没有类型定义，因此没有智能感知或类型检查。",{"id":387,"title":388,"titles":389,"content":390,"level":320,"path":387,"to":387,"label":388},"/docs/getting-started/confetti-tutorial#添加类型","添加类型",[20,368],"您可以使用 useScriptNpm 组合式函数的泛型为脚本添加类型，并向全局 window 对象添加类型声明。 \u003Cscript setup lang=\"ts\">\nexport interface JSConfettiApi {\n  JSConfetti: { \n    new (): {\n      addConfetti: (options?: { emojis: string[] }) => void\n    } \n  }\n}\n\ndeclare global {\n  interface Window extends JSConfettiApi {}\n}\n\nconst { onLoaded } = useScriptNpm\u003CJSConfettiApi>({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n  scriptOptions: {\n    use() {\n      return { JSConfetti: window.JSConfetti }\n    },\n  },\n})\nonMounted(() => {\n  onLoaded(({ JSConfetti }) => {\n    const confetti = new JSConfetti()\n    // 完全有类型支持！\n    confetti.addConfetti({ emojis: ['🌈', '⚡️', '💥', '✨', '💫', '🌸'] })\n  })\n})\n\u003C/script>",{"id":392,"title":393,"titles":394,"content":395,"level":320,"path":392,"to":392,"label":393},"/docs/getting-started/confetti-tutorial#额外内容基于触发条件的脚本加载","额外内容：基于触发条件的脚本加载",[20,368],"您可以使用 trigger 选项延迟加载脚本。如果想在某个事件或某个时间点后加载脚本，这非常有用。 请参考脚本触发器指南了解所有可用选项。",{"id":397,"title":398,"titles":399,"content":400,"level":401,"path":397,"to":397,"label":398},"/docs/getting-started/confetti-tutorial#使用-ref","使用 Ref",[20,368,393],"最简单的方法是使用一个 ref —— 当该 ref 变为真值时，脚本会加载。 \u003Cscript setup lang=\"ts\">\nconst shouldLoad = ref(false)\nconst { onLoaded } = useScriptNpm({\n  // ..\n  scriptOptions: {\n    trigger: shouldLoad\n  }\n})\nonLoaded(({ JSConfetti }) => {\n  const confetti = new JSConfetti()\n  confetti.addConfetti({ emojis: ['🎉', '🎊', '✨'] })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"shouldLoad = true\">\n    点击加载彩带\n  \u003C/button>\n\u003C/template> 您也可以使用计算属性 ref 或 getter 函数：trigger: computed(() => someCondition.value) 或 trigger: () => shouldLoad.value。",4,{"id":403,"title":404,"titles":405,"content":406,"level":401,"path":403,"to":403,"label":404},"/docs/getting-started/confetti-tutorial#使用元素事件","使用元素事件",[20,368,393],"您还可以使用 useScriptTriggerElement 组合函数，基于元素交互触发加载。 \u003Cscript setup lang=\"ts\">\nconst mouseOverEl = ref\u003CHTMLElement>()\nconst { onLoaded } = useScriptNpm({\n  // ..\n  scriptOptions: {\n    trigger: useScriptTriggerElement({ trigger: 'mouseover', el: mouseOverEl })\n  }\n})\n// ..\nonMounted(() => {\n  onLoaded(({ JSConfetti }) => {\n    const confetti = new JSConfetti()\n    confetti.addConfetti({ emojis: ['L', 'O', 'A', 'D', 'E', 'D'] })\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv ref=\"mouseOverEl\">\n    \u003Ch1>鼠标悬停在这里加载彩带\u003C/h1>\n  \u003C/div>\n\u003C/template>",{"id":408,"title":409,"titles":410,"content":411,"level":320,"path":408,"to":408,"label":409},"/docs/getting-started/confetti-tutorial#额外内容打包脚本","额外内容：打包脚本",[20,368],"由于脚本来自 NPM 并且有版本控制，我们可以将它安全地与应用一起打包。这样可以减少 DNS 请求数量，提升应用性能。 要打包脚本，可以使用 bundle 选项。 \u003Cscript setup lang=\"ts\">\nconst script = useScriptNpm({\n  // ...\n  scriptOptions: {\n    bundle: true\n  }\n})\n// ..\n\u003C/script> 您应该能看到脚本是从您的应用服务器加载的。",{"id":413,"title":414,"titles":415,"content":416,"level":314,"path":413,"to":413,"label":414},"/docs/getting-started/confetti-tutorial#结论","结论",[20],"在本教程中，您学习了如何使用 useScriptNpm 注册脚本加载 js-confetti 脚本。 想了解更多您所接触到的具体概念，请查看关键概念文档。 html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}",{"id":25,"title":24,"titles":418,"content":419,"level":308,"path":25,"to":25,"label":24},[],"在排查模块问题时，使用 StackBlitz 创建复现案例。 要针对 Nuxt Scripts 模块提交问题，你需要创建一个复现案例。",{"id":421,"title":422,"titles":423,"content":424,"level":314,"path":421,"to":421,"label":422},"/docs/getting-started/reproductions#创建复现案例","创建复现案例",[24],"为问题制作复现案例是获得帮助的重要第一步，了解更多内容请参阅 为何需要复现案例。 创建复现案例最简单的方法是使用下方提供的 StackBlitz 沙盒环境。 你可以利用这些环境在沙盒中实验模块功能，或为问题创建复现案例。",{"id":426,"title":427,"titles":428,"content":429,"level":314,"path":426,"to":426,"label":427},"/docs/getting-started/reproductions#stackblitz-沙盒环境","Stackblitz 沙盒环境",[24],"Minimal Nuxt Scripts",{"id":29,"title":28,"titles":431,"content":432,"level":308,"path":29,"to":29,"label":28},[],"@nuxt/scripts 是一个社区项目——因此我们欢迎各种贡献！❤️",{"id":434,"title":435,"titles":436,"content":437,"level":314,"path":434,"to":434,"label":435},"/docs/getting-started/contributing#准备你的开发环境","准备你的开发环境",[28],"@nuxt/scripts 是一个使用 pnpm 工作区的单体仓库。用于安装和链接依赖的包管理器必须是 pnpm。 克隆仓库后，你可以通过以下命令准备你的环境： pnpm i && pnpm dev:prepare",{"id":439,"title":440,"titles":441,"content":442,"level":314,"path":439,"to":439,"label":440},"/docs/getting-started/contributing#运行示例环境","运行示例环境",[28],"你可以通过运行开发服务器来体验 playground： pnpm dev html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":39,"title":38,"titles":444,"content":445,"level":308,"path":39,"to":39,"label":38},[],"了解 Nuxt Scripts 的关键概念。 useScript 组合式函数是 Nuxt Scripts 的核心，用于加载所有脚本。 在 useScript 之上构建了额外的抽象层，使得以不同方式加载脚本变得更加容易。 注册脚本 - 预配置的第三方脚本，可以通过 Nuxt 配置、组合式函数和组件加载。全局脚本 - 通过 Nuxt 配置文件加载脚本。",{"id":447,"title":448,"titles":449,"content":450,"level":314,"path":447,"to":447,"label":448},"/docs/guides/key-concepts#unhead-抽象层","Unhead 抽象层",[38],"Nuxt Scripts 的 useScript 组合式函数是对 Unhead 的 useScript 的抽象，而后者又是基于 useHead 的抽象。通过 useHead 可用的许多功能，在 Nuxt Scripts 的 useScript 中也能使用。",{"id":452,"title":453,"titles":454,"content":455,"level":314,"path":452,"to":452,"label":453},"/docs/guides/key-concepts#脚本单例","脚本单例",[38],"在 Nuxt Scripts 中，不可能多次加载相同 src（或 key）的脚本。这是因为脚本是全局加载的，并且在所有组件间共享。 这意味着脚本只会经过一次初始化过程，后续对 useScript 的调用都会返回同一实例。 因此，你可以考虑将 useScript 调用封装在自己的组合式函数中，以便更方便地实例化该脚本。 export function useMyScript() {\n  return useScript({\n    src: 'https://example.com/script.js',\n  })\n}",{"id":457,"title":458,"titles":459,"content":460,"level":314,"path":457,"to":457,"label":458},"/docs/guides/key-concepts#默认行为","默认行为",[38],"Nuxt Scripts 不会在 SSR 响应中插入脚本标签。这是一个性能决策，旨在最大限度地减少对 hydration 过程的干扰。相反，脚本默认会在 Nuxt 完全在客户端完成 hydration 后加载。 你可以通过修改 defaultScriptOptions 来改变此行为。 Nuxt Scripts 还会向 \u003Cscript> 标签插入若干额外的属性，以优化性能和隐私。 async - 脚本异步加载，防止阻塞页面渲染。defer - 脚本延迟执行，确保按加载顺序执行。crossorigin=\"anonymous\" - 脚本带有 anonymous 属性，防止访问 Cookie。referrerpolicy=\"no-referrer\" - 脚本使用 no-referrer 策略，防止发送 Referer 头。fetchpriority=\"low\" - 脚本以较低优先级加载，提升页面性能。 注意： 默认不使用 async，而是使用 defer。如果需要 async，你可以显式禁用 defer。",{"id":462,"title":463,"titles":464,"content":465,"level":314,"path":462,"to":462,"label":463},"/docs/guides/key-concepts#理解代理函数","理解代理函数",[38],"你可能会好奇 useScript 组合式函数如何返回 SSR 安全的函数，并且可以在脚本加载前调用。 const { proxy } = useScript('/script.js')\n// 如你所愿地工作 —— 魔法吗？\nproxy.gtag('event', 'page_view') gtag 函数调用是一个代理，函数会被排队，等脚本加载后才执行。如果脚本从未加载，则函数不会被调用。 这带来了几个优点： SSR 安全如果脚本未加载（被广告拦截器阻止），不会破坏你的网站允许随时加载脚本，无需担心脚本和函数调用的顺序 但也有一些缺点： 仅适用于不需要返回值的函数。你可以等待函数调用来获取返回值，但这会阻塞页面渲染。如果不了解其工作原理，调试时可能会感到困惑。 如果你想直接访问脚本的 API，建议等待脚本加载完成后再调用。 const { onLoaded } = useScript('/script.js')\n// 直接使用脚本实例，而非代理\nonLoaded(({ gtag }) => {\n  gtag('event', 'page_view')\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"id":43,"title":42,"titles":467,"content":468,"level":308,"path":43,"to":43,"label":42},[],"了解如何使用注册表脚本简化在 Nuxt 脚本中集成第三方脚本。 注册表脚本通过简化在 Nuxt 脚本中集成第三方脚本，提升开发者体验。 支持的注册表脚本列表，请参见 脚本注册表 列表。",{"id":470,"title":471,"titles":472,"content":330,"level":314,"path":470,"to":470,"label":471},"/docs/guides/registry-scripts#特性","特性",[42],{"id":474,"title":475,"titles":476,"content":477,"level":320,"path":474,"to":474,"label":475},"/docs/guides/registry-scripts#安全初始化","😌 安全初始化",[42,471],"许多第三方脚本需要在加载脚本前初始化一些全局状态，Nuxt 脚本会以优化的方式帮你处理这一过程。",{"id":479,"title":480,"titles":481,"content":482,"level":320,"path":479,"to":479,"label":480},"/docs/guides/registry-scripts#️-细粒度性能调优","🏎️ 细粒度性能调优",[42,471],"每个注册表脚本都经过优化，以尽可能高效的方式加载脚本功能。",{"id":484,"title":485,"titles":486,"content":487,"level":320,"path":484,"to":484,"label":485},"/docs/guides/registry-scripts#完全类型化","📜 完全类型化",[42,471],"处理第三方脚本通常需要自行处理它们的 API 类型。注册表脚本通过提供预定义类型来缓解这一问题，使你的项目能够享受代码补全和类型安全。",{"id":489,"title":490,"titles":491,"content":492,"level":320,"path":489,"to":489,"label":490},"/docs/guides/registry-scripts#选项验证","✅ 选项验证",[42,471],"使用 Valibot，注册表脚本自动验证第三方脚本的配置选项，帮助你及早发现并解决配置错误。例如，它们会检查 Cloudflare Web Analytics 的令牌长度。 export const CloudflareWebAnalyticsOptions = object({\n  /**\n   * Cloudflare Web Analytics 的令牌。\n   */\n  token: string([minLength(32)]),\n  /**\n   * Cloudflare Web Analytics 通过重写 History API 的 pushState 函数和监听 onpopstate 自动测量 SPA。\n   * 不支持基于哈希的路由器。\n   *\n   * @default true\n   */\n  spa: optional(boolean()),\n})\nuseScriptCloudflareWebAnalytics({\n  token: '123', // 会抛出错误，字符串长度不是 32\n}) 出于性能考虑，验证仅在开发时进行。在生产构建中会被 tree-shake 掉。",{"id":494,"title":495,"titles":496,"content":497,"level":320,"path":494,"to":494,"label":495},"/docs/guides/registry-scripts#运行时配置集成","🤫 运行时配置集成",[42,471],"注册表脚本可以通过 .env 文件配置，允许你不在代码中硬编码脚本选项。 NUXT_PUBLIC_SCRIPTS_CLOUDFLARE_WEB_ANALYTICS_TOKEN=YOUR_TOKEN\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      // 加载脚本\n      cloudflareWebAnalytics: true,\n    },\n  },\n  runtimeConfig: {\n    public: {\n      scripts: {\n        cloudflareWebAnalytics: {\n          // 提供空字符串以使 .env 生效\n          token: '', // NUXT_PUBLIC_SCRIPTS_CLOUDFLARE_WEB_ANALYTICS_TOKEN\n        },\n      },\n    },\n  },\n})",{"id":499,"title":500,"titles":501,"content":330,"level":314,"path":499,"to":499,"label":500},"/docs/guides/registry-scripts#使用","使用",[42],{"id":503,"title":504,"titles":505,"content":506,"level":320,"path":503,"to":503,"label":504},"/docs/guides/registry-scripts#在开发环境中禁用","在开发环境中禁用",[42,500],"当你想在开发环境中使用暴露的 API 脚本（例如组件内调用 gtag）时，你希望加载一个模拟版本，这样脚本就永远不会真正加载。 你可以通过给注册表脚本提供一个 mock 值来实现。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: true,\n    },\n  },\n  $development: {\n    scripts: {\n      registry: {\n        googleTagManager: \"mock\",\n      },\n    },\n  },\n})",{"id":508,"title":509,"titles":510,"content":511,"level":320,"path":508,"to":508,"label":509},"/docs/guides/registry-scripts#加载多个相同脚本","加载多个相同脚本",[42,500],"你可能有需要使用不同配置加载同一个注册表脚本多次的情况。 默认情况下，它们会去重且只加载一次。要加载同一个脚本的多个实例，可以给脚本提供唯一的 key。 const { proxy: gaOne } = useScriptGoogleAnalytics({\n  id: 'G-TR58L0EF8P',\n})\n\nconst { proxy: gaTwo } = useScriptGoogleAnalytics({\n  // 不设置 key 会返回第一个脚本实例\n  key: 'gtag2',\n  id: 'G-1234567890',\n}) 需要注意的是，当修改 key 时，你使用的环境变量会失效。 例如，将 key 设置为 gtag2，你需要按如下方式提供运行时配置： export default defineNuxtConfig({\n  runtimeConfig: {\n    public: {\n      scripts: {\n        gtag2: {\n          id: '', // NUXT_PUBLIC_SCRIPTS_GTAG2_ID\n        },\n      },\n    },\n  },\n})",{"id":513,"title":514,"titles":515,"content":516,"level":320,"path":513,"to":513,"label":514},"/docs/guides/registry-scripts#使用脚本选项和脚本输入","使用脚本选项和脚本输入",[42,500],"注册表脚本不会阻止你使用核心的 useScript 功能，你可以通过额外的选项启用高级功能。 scriptOptions — 传递给脚本的附加选项。详见 useScript 选项。scriptInput — 传递给脚本的附加输入。详见 useScript 输入。 import { useTimeout } from '@vueuse/core'\nimport { useScriptCloudflareWebAnalytics } from '#imports'\n\nconst { ready } = useTimeout(5000)\nuseScriptCloudflareWebAnalytics({\n  token: '123',\n  // 传递给 script 元素的 HTML 属性\n  scriptInput: {\n    'data-cf-test': 'true'\n  },\n  // 用于高级功能的 useScript 选项\n  scriptOptions: {\n    trigger: ready,\n    bundle: true,\n  },\n})",{"id":518,"title":519,"titles":520,"content":521,"level":320,"path":518,"to":518,"label":519},"/docs/guides/registry-scripts#加载最佳实践","加载最佳实践",[42,500],"当在多个页面或组件中使用注册表脚本时，建议你在 app.vue 或 nuxt.config 中初始化脚本并传入所需配置。 后续对注册表脚本的调用会使用同一个脚本实例，不需要再次传入选项。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      // 加载脚本\n      fathomAnalytics: {\n        site: 'SITE_ID',\n      }\n    }\n  }\n})\n\u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptFathomAnalytics() // 不需要传入选项\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"proxy.trackGoal('GOAL_ID')\">\n    跟踪目标\n  \u003C/button>\n\u003C/template> 或者，你可以将注册表脚本封装成一个 composable 以便更方便地实例化脚本。 export function useFathomAnalytics() {\n  return useScriptFathomAnalytics({\n    site: 'SITE_ID',\n  })\n}",{"id":523,"title":524,"titles":525,"content":526,"level":314,"path":523,"to":523,"label":524},"/docs/guides/registry-scripts#扩展脚本注册表","扩展脚本注册表",[42],"你可以在 nuxt.config.ts 中使用 scripts:registry 钩子扩展脚本注册表： import { createResolver } from '@nuxt/kit'\n\nconst { resolve } = createResolver(import.meta.url)\n\nexport default defineNuxtConfig({\n  modules: ['@nuxt/scripts'],\n\n  hooks: {\n    'scripts:registry': function (registry) {\n      registry.push({\n        category: 'custom',\n        label: '我的自定义分析',\n        logo: '\u003Csvg>...\u003C/svg>', // 可选\n        import: {\n          name: 'useScriptMyAnalytics',\n          from: resolve('./composables/useScriptMyAnalytics'),\n        },\n      })\n    },\n  },\n\n  devtools: {\n    enabled: true,\n  },\n}) 然后创建你的自定义脚本 composable： import { useRegistryScript } from '#nuxt-scripts/utils'\nimport { object, string } from '#nuxt-scripts-validator'\n\nexport interface MyAnalyticsApi {\n  track: (event: string, data?: Record\u003Cstring, any>) => void\n  identify: (userId: string) => void\n}\n\n// 用于验证和 DevTools 元数据的 Schema\nconst MyAnalyticsSchema = object({\n  apiKey: string(),\n})\n\nexport function useScriptMyAnalytics\u003CT extends MyAnalyticsApi>(options?: {\n  apiKey: string\n  scriptOptions?: NuxtUseScriptOptions\n}) {\n  return useRegistryScript\u003CT, typeof MyAnalyticsSchema>('myAnalytics', () => ({\n    scriptInput: {\n      src: 'https://analytics.example.com/sdk.js',\n    },\n    scriptOptions: {\n      ...options?.scriptOptions,\n      use() {\n        // 初始化脚本\n        window.MyAnalytics.init(options?.apiKey)\n        return window.MyAnalytics as T\n      },\n    },\n  }), options, { schema: MyAnalyticsSchema })\n}",{"id":528,"title":529,"titles":530,"content":531,"level":320,"path":528,"to":528,"label":529},"/docs/guides/registry-scripts#使用自定义注册表脚本","使用自定义注册表脚本",[42,524],"注册后，你的自定义脚本使用方式与内置注册表脚本完全相同： \u003Cscript setup>\n// 从注册表自动导入\nconst { proxy, status } = useScriptMyAnalytics({\n  apiKey: 'your-api-key',\n  scriptOptions: {\n    trigger: 'onNuxtReady'\n  }\n})\n\n// 使用脚本 API\nfunction trackClick() {\n  proxy.track('button_click', { button: 'hero-cta' })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"trackClick\">\n    跟踪此点击\n  \u003C/button>\n  \u003Cdiv>状态: {{ status }}\u003C/div>\n\u003C/template>",{"id":533,"title":534,"titles":535,"content":536,"level":320,"path":533,"to":533,"label":534},"/docs/guides/registry-scripts#devtools-集成","DevTools 集成",[42,524],"当你包含验证 Schema 时，Nuxt 脚本会自动用你的脚本配置填充 DevTools 元数据。在开发模式下，registryKey 和 registryMeta 会自动设置，使你能够： html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sm_uT, html code.shiki .sm_uT{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}",{"id":47,"title":46,"titles":538,"content":539,"level":308,"path":47,"to":47,"label":46},[],"使用 Nuxt Scripts 灵活的触发系统控制脚本加载时机。 在 StackBlitz 上试用实时的性能示例，体验触发器的实际效果。 Nuxt Scripts 提供了一个灵活的触发系统，用于控制脚本的加载时机，帮助你通过在合适的时刻为用户加载脚本来优化性能。",{"id":541,"title":542,"titles":543,"content":544,"level":314,"path":541,"to":541,"label":542},"/docs/guides/script-triggers#触发器的工作原理","触发器的工作原理",[46],"传入任意响应式值作为 trigger —— 当其变为真值时，脚本将加载： const shouldLoad = ref(false)\n\nuseScript('https://example.com/script.js', {\n  trigger: shouldLoad\n})\n\n// 后续：触发加载\nshouldLoad.value = true 它支持 refs、计算属性 refs、getter 函数和 Promise： // Ref\ntrigger: shouldLoad\n\n// 计算属性\ntrigger: computed(() => !!route.query.affiliateId)\n\n// Getter 函数\ntrigger: () => shouldLoad.value\n\n// Promise\ntrigger: new Promise(resolve => setTimeout(resolve, 3000))",{"id":546,"title":547,"titles":548,"content":549,"level":314,"path":546,"to":546,"label":547},"/docs/guides/script-triggers#默认onnuxtready","默认：onNuxtReady",[46],"默认情况下，脚本使用 onNuxtReady 触发器，提供“空闲加载”行为，即仅在页面完全交互式后加载脚本。这将最大限度地减少对核心网页指标和用户体验的影响。 onNuxtReady 触发器确保脚本在以下情况下加载： Nuxt hydration 完成后浏览器空闲且主线程可用时不阻塞关键页面渲染或用户交互 // 默认行为——为了清晰显式写出\nuseScript('https://widget.intercom.io/widget/abc123', {\n  trigger: 'onNuxtReady'\n})\n\n// 注册脚本默认也使用 onNuxtReady\nuseScriptGoogleAnalytics({\n  id: 'GA_MEASUREMENT_ID'\n  // trigger: 'onNuxtReady' 是隐含的\n}) 你可以通过修改 defaultScriptOptions 来改变此默认值。",{"id":551,"title":552,"titles":553,"content":330,"level":314,"path":551,"to":551,"label":552},"/docs/guides/script-triggers#专用触发器","专用触发器",[46],{"id":555,"title":556,"titles":557,"content":558,"level":320,"path":555,"to":555,"label":556},"/docs/guides/script-triggers#空闲超时","空闲超时",[46,552],"使用 useScriptTriggerIdleTimeout 在 Nuxt 准备好后延迟指定时间再加载脚本： useScript('https://example.com/analytics.js', {\n  trigger: useScriptTriggerIdleTimeout({ timeout: 5000 })\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAnalytics: [{\n        id: 'GA_MEASUREMENT_ID'\n      }, {\n        trigger: { idleTimeout: 3000 }\n      }]\n    }\n  }\n})",{"id":560,"title":561,"titles":562,"content":563,"level":320,"path":560,"to":560,"label":561},"/docs/guides/script-triggers#用户交互","用户交互",[46,552],"使用 useScriptTriggerInteraction 在用户与站点交互时加载脚本： useScript('https://example.com/chat-widget.js', {\n  trigger: useScriptTriggerInteraction({\n    events: ['scroll', 'click', 'keydown']\n  })\n})\nexport default defineNuxtConfig({\n  scripts: {\n    globals: {\n      chatWidget: ['https://widget.example.com/chat.js', {\n        trigger: { interaction: ['scroll', 'click', 'touchstart'] }\n      }]\n    }\n  }\n})",{"id":565,"title":566,"titles":567,"content":568,"level":320,"path":565,"to":565,"label":566},"/docs/guides/script-triggers#元素事件","元素事件",[46,552],"使用 useScriptTriggerElement 根据特定元素的交互来触发脚本： const buttonEl = ref\u003CHTMLElement>()\n\nuseScript('https://example.com/feature.js', {\n  trigger: useScriptTriggerElement({\n    trigger: 'visible', // 或 'hover'、'click' 等等\n    el: buttonEl,\n  })\n})",{"id":570,"title":571,"titles":572,"content":330,"level":314,"path":570,"to":570,"label":571},"/docs/guides/script-triggers#基础触发器","基础触发器",[46],{"id":574,"title":575,"titles":576,"content":577,"level":320,"path":574,"to":574,"label":575},"/docs/guides/script-triggers#手动控制","手动控制",[46,571],"使用 manual 触发器可以完全控制脚本的加载时机： const { load } = useScript('https://example.com/script.js', {\n  trigger: 'manual'\n})\n\n// 你决定何时加载\nawait load() html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"id":51,"title":50,"titles":579,"content":580,"level":308,"path":51,"to":51,"label":50},[],"自定义脚本使用的预加载或预连接策略。",{"id":582,"title":311,"titles":583,"content":584,"level":314,"path":582,"to":582,"label":311},"/docs/guides/warmup#背景",[50],"Nuxt Scripts 会插入相关的预热 link 标签以优化脚本的加载。优化目的是在 Nuxt 完成水合（hydration）后实现最快的加载速度。 例如，如果我们有如下脚本： useScript('/script.js') 这段代码将在 onNuxtReady 事件时加载 /script.js。由于在 Nuxt 应用水合期间网络可能闲置，Nuxt Scripts 会利用这段时间通过在文档头部插入 preload 标签来预热脚本。 \u003Clink rel=\"preload\" href=\"/script.js\" as=\"script\" fetchpriority=\"low\"> 该行为仅在使用 client 或 onNuxtReady 脚本触发器 时应用。要进一步自定义该行为，可以使用 warmupStrategy 选项。",{"id":586,"title":587,"titles":588,"content":589,"level":314,"path":586,"to":586,"label":587},"/docs/guides/warmup#warmupstrategy","warmupStrategy",[50],"warmupStrategy 选项可用于自定义插入到脚本中的 link 标签。该选项可以是一个函数，返回一个具有以下属性的对象： false - 禁用预热。'preload' - 预加载脚本，适用于立即加载脚本的场景。'preconnect' 或 'dns-prefetch' - 预连接到脚本源，适用于您知道脚本将在 10 秒内被加载的场景。仅在从不同源加载脚本时有效，如果源相同则回退为 false。 所有这些选项也可以作为回调函数的参数传入，当脚本触发条件动态变化时非常有用。",{"id":591,"title":592,"titles":593,"content":594,"level":314,"path":591,"to":591,"label":592},"/docs/guides/warmup#warmup","warmup",[50],"warmup 函数可以显式调用，为脚本添加预连接或预加载的 link 标签。该操作仅在函数首次调用时有效。 当您确定脚本即将被加载时，该功能非常有用。 const script = useScript('/video.js', {\n  trigger: 'manual'\n})\n// 当我们认为用户可能需要该脚本时，预热脚本\nonVisible(videoContainer, () => {\n  script.warmup('preload')\n})\n// 加载脚本\nonClick(videoContainer, () => {\n  script.load()\n}) html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":55,"title":54,"titles":596,"content":597,"level":308,"path":55,"to":55,"label":54},[],"通过您的域名路由第三方脚本流量，以提升隐私和可靠性。",{"id":599,"title":311,"titles":600,"content":601,"level":314,"path":599,"to":599,"label":311},"/docs/guides/first-party#背景",[54],"当第三方脚本直接从外部服务器加载时，会暴露您的用户数据： IP 地址暴露 — 每个请求都会向第三方泄露用户的 IP 地址第三方 Cookie — 外部脚本可设置跨站追踪的 Cookie广告拦截器干扰 — 隐私工具会阻止已知追踪域的请求连接开销 — 额外的 DNS 查询和 TLS 握手会降低页面加载速度",{"id":603,"title":604,"titles":605,"content":606,"level":320,"path":603,"to":603,"label":604},"/docs/guides/first-party#第一方模式如何帮助","第一方模式如何帮助",[54,311],"第一方模式通过您的域名路由所有脚本流量： 用户 IP 匿名化 — 在转发前，IP 地址被匿名到子网级别，第三方无法识别单个用户减少设备指纹识别 — 屏幕分辨率、User-Agent 和硬件信息被泛化到常见类别无第三方 Cookie — 请求为同源，消除跨站追踪兼容广告拦截器 — 请求看起来像第一方请求加载更快 — 无需针对外部域的额外 DNS 查询",{"id":608,"title":609,"titles":610,"content":611,"level":314,"path":608,"to":608,"label":609},"/docs/guides/first-party#工作原理","工作原理",[54],"启用第一方模式时： 构建时：脚本被下载且 URL 重写为本地路径（例如：https://www.google-analytics.com/g/collect → /_scripts/c/ga/g/collect）运行时：Nitro 路由规则将来自本地路径的请求代理回原始端点 用户浏览器 → 您的服务器 (/_scripts/c/ga/...) → Google Analytics 您的用户永远不会直接连接第三方服务器。",{"id":613,"title":614,"titles":615,"content":330,"level":314,"path":613,"to":613,"label":614},"/docs/guides/first-party#使用方法","使用方法",[54],{"id":617,"title":618,"titles":619,"content":620,"level":320,"path":617,"to":617,"label":618},"/docs/guides/first-party#全局启用","全局启用",[54,614],"为所有支持的脚本启用第一方模式： export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      googleAnalytics: { id: 'G-XXXXXX' },\n      metaPixel: { id: '123456' },\n    }\n  }\n})",{"id":622,"title":623,"titles":624,"content":625,"level":320,"path":622,"to":622,"label":623},"/docs/guides/first-party#privacy-controls","Privacy Controls",[54,614],"每个注册的脚本根据其所需数据声明默认隐私设置。隐私通过以下六个标识控制： 标识功能说明ip在请求头和数据参数中将 IP 地址匿名到子网级别userAgent将 User-Agent 归一化为浏览器类别 + 主版本（例如 Mozilla/5.0 (compatible; Chrome/131.0)）language将 Accept-Language 归一化为主语言标签screen将屏幕分辨率、视口、硬件并发性和设备内存泛化到通用类别timezone泛化时区偏移和 IANA 时区名称hardware匿名化 canvas/webgl/audio 指纹、插件/字体列表、浏览器版本和设备信息 无论隐私设置如何，敏感请求头（如 cookie、authorization）都会始终被移除。",{"id":627,"title":628,"titles":629,"content":630,"level":401,"path":627,"to":627,"label":628},"/docs/guides/first-party#单个脚本默认隐私设置示例","单个脚本默认隐私设置示例",[54,614,623],"脚本ipuserAgentlanguagescreentimezonehardware理由Google Analytics✓-✓--✓设备、时间和操作系统相关报告需要 UA/屏幕/时区信息Google Tag Manager------容器脚本加载，无用户数据传输Meta Pixel✓✓✓✓✓✓不可信广告网络，需完全匿名TikTok Pixel✓✓✓✓✓✓不可信广告网络，需完全匿名X/Twitter Pixel✓✓✓✓✓✓不可信广告网络，需完全匿名Snapchat Pixel✓✓✓✓✓✓不可信广告网络，需完全匿名Reddit Pixel✓✓✓✓✓✓不可信广告网络，需完全匿名Segment------可信的数据通路，要求完整数据PostHog------可信、开源，要求完整数据Microsoft Clarity✓-✓--✓热图和设备筛选需要 UA/屏幕/时区信息Hotjar✓-✓--✓热图和设备筛选需要 UA/屏幕/时区信息 ✓ 表示匿名化处理，- 表示通过原始数据。",{"id":632,"title":633,"titles":634,"content":635,"level":401,"path":632,"to":632,"label":633},"/docs/guides/first-party#全局覆盖","全局覆盖",[54,614,623],"一次性覆盖所有脚本默认隐私设置： export default defineNuxtConfig({\n  scripts: {\n    firstParty: {\n      privacy: true, // 对所有脚本全面匿名化\n    }\n  }\n}) 或者选择性覆盖特定标识： export default defineNuxtConfig({\n  scripts: {\n    firstParty: {\n      privacy: { ip: true }, // 仅对所有脚本匿名化 IP，其他使用脚本默认设置\n    }\n  }\n}) 启用某个标识时，数据会被泛化（降低精度）或脱敏（清空/归零）——分析端点仍接收有效数据。例如，屏幕分辨率 1440x900 会变为 1920x1080（桌面类别），User-Agent 会归一化为 Mozilla/5.0 (compatible; Chrome/131.0)，而如 canvas、WebGL、插件、字体等硬件指纹则被清空或重置。",{"id":637,"title":638,"titles":639,"content":640,"level":320,"path":637,"to":637,"label":638},"/docs/guides/first-party#自定义路径","自定义路径",[54,614],"可自定义代理收集端点路径： export default defineNuxtConfig({\n  scripts: {\n    firstParty: {\n      collectPrefix: '/_analytics', // 默认为 /_scripts/c\n    }\n  }\n})",{"id":642,"title":643,"titles":644,"content":645,"level":320,"path":642,"to":642,"label":643},"/docs/guides/first-party#按脚本选择退出","按脚本选择退出",[54,614],"禁用某脚本的第一方路由： useScriptGoogleAnalytics({\n  id: 'G-XXXXXX',\n  scriptOptions: {\n    firstParty: false, // 直接从 Google 加载\n  }\n})",{"id":647,"title":648,"titles":649,"content":650,"level":314,"path":647,"to":647,"label":648},"/docs/guides/first-party#支持的脚本","支持的脚本",[54],"第一方模式支持以下脚本： 脚本代理端点Google Analyticsgoogle-analytics.com, analytics.google.com, stats.g.doubleclick.net, pagead2.googlesyndication.comGoogle Tag Managerwww.googletagmanager.comMeta Pixelconnect.facebook.net, www.facebook.com/tr, pixel.facebook.comTikTok Pixelanalytics.tiktok.comSegmentapi.segment.io, cdn.segment.comPostHogus.i.posthog.com, eu.i.posthog.com, us-assets.i.posthog.com, eu-assets.i.posthog.comMicrosoft Claritywww.clarity.ms, scripts.clarity.ms, d.clarity.ms, e.clarity.msHotjarstatic.hotjar.com, script.hotjar.com, vars.hotjar.com, in.hotjar.comX/Twitter Pixelanalytics.twitter.com, t.coSnapchat Pixeltr.snapchat.comReddit Pixelalb.reddit.com",{"id":652,"title":653,"titles":654,"content":655,"level":314,"path":652,"to":652,"label":653},"/docs/guides/first-party#要求","要求",[54],"第一方模式需要服务器运行时环境。无法用于纯静态托管（如 nuxt generate 部署到 GitHub Pages），因为代理端点需要服务器转发请求。 静态部署仍可启用第一方模式，脚本中包含重写 URL，但您需手动配置托管平台的重写规则。",{"id":657,"title":658,"titles":659,"content":660,"level":320,"path":657,"to":657,"label":658},"/docs/guides/first-party#静态托管重写规则示例","静态托管重写规则示例",[54,653],"若部署为静态站点，请配置平台代理请求： /_scripts/c/ga/* → https://www.google.com/*\n/_scripts/c/gtm/* → https://www.googletagmanager.com/*\n/_scripts/c/meta/* → https://connect.facebook.net/*",{"id":662,"title":663,"titles":664,"content":665,"level":314,"path":662,"to":662,"label":663},"/docs/guides/first-party#第一方模式-vs-bundle-选项","第一方模式 vs bundle 选项",[54],"第一方模式替代了旧的 bundle 选项： 功能bundle: truefirstParty: true构建时下载脚本✅✅从您域名提供脚本✅✅重写收集 URL❌✅代理 API 请求❌✅隐藏用户 IP❌✅阻止第三方 Cookie❌✅ bundle 仅自托管脚本文件。第一方模式还重写并代理所有收集/追踪端点，实现完整第一方路由。 bundle 选项已废弃。新项目请使用 firstParty: true。",{"id":667,"title":458,"titles":668,"content":669,"level":314,"path":667,"to":667,"label":458},"/docs/guides/first-party#默认行为",[54],"第一方模式默认启用。对于静态托管（如 GitHub Pages），脚本仍被打包，但您需配置平台重写规则以使代理端点生效。 关闭第一方模式： export default defineNuxtConfig({\n  scripts: {\n    firstParty: false\n  }\n})",{"id":671,"title":672,"titles":673,"content":674,"level":314,"path":671,"to":671,"label":672},"/docs/guides/first-party#平台重写配置","平台重写配置",[54],"部署到静态托管或边缘平台时，请配置如下重写规则以代理收集端点。",{"id":676,"title":677,"titles":678,"content":679,"level":320,"path":676,"to":676,"label":677},"/docs/guides/first-party#vercel","Vercel",[54,672],"{\n  \"rewrites\": [\n    { \"source\": \"/_scripts/c/ga/:path*\", \"destination\": \"https://www.google.com/:path*\" },\n    { \"source\": \"/_scripts/c/ga-legacy/:path*\", \"destination\": \"https://www.google-analytics.com/:path*\" },\n    { \"source\": \"/_scripts/c/gtm/:path*\", \"destination\": \"https://www.googletagmanager.com/:path*\" },\n    { \"source\": \"/_scripts/c/meta/:path*\", \"destination\": \"https://connect.facebook.net/:path*\" },\n    { \"source\": \"/_scripts/c/tiktok/:path*\", \"destination\": \"https://analytics.tiktok.com/:path*\" },\n    { \"source\": \"/_scripts/c/segment/:path*\", \"destination\": \"https://api.segment.io/:path*\" },\n    { \"source\": \"/_scripts/c/clarity/:path*\", \"destination\": \"https://www.clarity.ms/:path*\" },\n    { \"source\": \"/_scripts/c/hotjar/:path*\", \"destination\": \"https://static.hotjar.com/:path*\" },\n    { \"source\": \"/_scripts/c/x/:path*\", \"destination\": \"https://analytics.twitter.com/:path*\" },\n    { \"source\": \"/_scripts/c/snap/:path*\", \"destination\": \"https://tr.snapchat.com/:path*\" },\n    { \"source\": \"/_scripts/c/reddit/:path*\", \"destination\": \"https://alb.reddit.com/:path*\" }\n  ]\n}",{"id":681,"title":682,"titles":683,"content":684,"level":320,"path":681,"to":681,"label":682},"/docs/guides/first-party#netlify","Netlify",[54,672],"[[redirects]]\n  from = \"/_scripts/c/ga/*\"\n  to = \"https://www.google.com/:splat\"\n  status = 200\n\n[[redirects]]\n  from = \"/_scripts/c/ga-legacy/*\"\n  to = \"https://www.google-analytics.com/:splat\"\n  status = 200\n\n[[redirects]]\n  from = \"/_scripts/c/gtm/*\"\n  to = \"https://www.googletagmanager.com/:splat\"\n  status = 200\n\n[[redirects]]\n  from = \"/_scripts/c/meta/*\"\n  to = \"https://connect.facebook.net/:splat\"\n  status = 200\n\n# 根据需要添加更多...",{"id":686,"title":687,"titles":688,"content":689,"level":320,"path":686,"to":686,"label":687},"/docs/guides/first-party#cloudflare-pages","Cloudflare Pages",[54,672],"在公共目录创建 _redirects 文件： /_scripts/c/ga/* https://www.google.com/:splat 200\n/_scripts/c/ga-legacy/* https://www.google-analytics.com/:splat 200\n/_scripts/c/gtm/* https://www.googletagmanager.com/:splat 200\n/_scripts/c/meta/* https://connect.facebook.net/:splat 200 或者使用 Cloudflare Workers 获取更灵活的控制： export const onRequest: PagesFunction = async (context) => {\n  const url = new URL(context.request.url)\n  const path = url.pathname.replace('/_scripts/c/', '')\n\n  // 根据前缀路由\n  const routes: Record\u003Cstring, string> = {\n    'ga/': 'https://www.google.com/',\n    'gtm/': 'https://www.googletagmanager.com/',\n    'meta/': 'https://connect.facebook.net/',\n  }\n\n  for (const [prefix, target] of Object.entries(routes)) {\n    if (path.startsWith(prefix)) {\n      const targetUrl = target + path.slice(prefix.length) + url.search\n      return fetch(targetUrl, context.request)\n    }\n  }\n\n  return new Response('Not found', { status: 404 })\n}",{"id":691,"title":692,"titles":693,"content":694,"level":314,"path":691,"to":691,"label":692},"/docs/guides/first-party#架构示意图","架构示意图",[54],"┌─────────────────────────────────────────────────────────────────────┐\n│                          构建阶段                                   │\n├─────────────────────────────────────────────────────────────────────┤\n│                                                                     │\n│  1. 从第三方下载脚本                                                │\n│     https://www.googletagmanager.com/gtag/js?id=G-XXX               │\n│                           ↓                                         │\n│  2. 重写脚本内容中的 URL                                            │\n│     \"www.google.com/g/collect\" → \"/_scripts/c/ga/g/collect\"         │\n│                           ↓                                         │\n│  3. 将重写的脚本保存到构建输出                                     │\n│     .output/public/_scripts/abc123.js                               │\n│                                                                     │\n└─────────────────────────────────────────────────────────────────────┘\n                                ↓\n┌─────────────────────────────────────────────────────────────────────┐\n│                            运行阶段                                 │\n├─────────────────────────────────────────────────────────────────────┤\n│                                                                     │\n│  用户浏览器                                                        │\n│       │                                                             │\n│       │ 1. 请求脚本                                                │\n│       │    GET /_scripts/abc123.js                                 │\n│       ↓                                                             │\n│  您的服务器（Nitro）                                               │\n│       │                                                             │\n│       │ 2. 返回打包的脚本（已重写 URL）                            │\n│       ↓                                                             │\n│  用户浏览器                                                        │\n│       │                                                             │\n│       │ 3. 脚本发送分析数据                                        │\n│       │    POST /_scripts/c/ga/g/collect                           │\n│       ↓                                                             │\n│  您的服务器（Nitro 路由规则）                                     │\n│       │                                                             │\n│       │ 4. 代理请求到第三方                                       │\n│       │    POST https://www.google.com/g/collect                   │\n│       ↓                                                             │\n│  第三方服务器                                                     │\n│       │                                                             │\n│       │ 5. 看到的是您的服务器 IP，而非用户 IP                      │\n│       ↓                                                             │\n│  响应被代理回用户                                                 │\n│                                                                     │\n└─────────────────────────────────────────────────────────────────────┘",{"id":696,"title":697,"titles":698,"content":330,"level":314,"path":696,"to":696,"label":697},"/docs/guides/first-party#故障排查","故障排查",[54],{"id":700,"title":701,"titles":702,"content":703,"level":320,"path":700,"to":700,"label":701},"/docs/guides/first-party#分析无数据追踪","分析无数据追踪",[54,697],"症状：统计分析面板没有事件数据。 检查项： 验证代理路由是否生效 — 在开发模式下检查 /_scripts/status.json 或通过 DevTools 的 Scripts 面板查看浏览器网络面板 — 确认是否有对 /_scripts/c/ 路径的请求且返回状态码为 200检查服务器日志 — 查找 Nitro 代理相关错误验证路由规则 — 运行 npx nuxi build 并检查 .output/server/chunks/routes/rules.mjs // 调试：服务器中间件中打印所有代理请求\nexport default defineEventHandler((event) => {\n  if (event.path.startsWith('/_scripts/c/')) {\n    console.log('代理请求:', event.path)\n  }\n})",{"id":705,"title":706,"titles":707,"content":708,"level":320,"path":705,"to":705,"label":706},"/docs/guides/first-party#跨域请求错误cors","跨域请求错误（CORS）",[54,697],"症状：浏览器控制台出现分析请求的 CORS 错误。 解决方案： 确保 nuxt.config.ts 中正确配置了第一方路由规则静态托管环境确认重写规则正确生效检查重写目标 URL 是否完全匹配",{"id":710,"title":711,"titles":712,"content":713,"level":320,"path":710,"to":710,"label":711},"/docs/guides/first-party#缓存旧脚本","缓存旧脚本",[54,697],"症状：脚本内容过时或未重写 URL。 解决方案： 清理构建缓存：rm -rf .nuxt/cache/scripts\nnpx nuxi build\n开发模式下强制重新下载：useScriptGoogleAnalytics({\n  id: 'G-XXX',\n  scriptOptions: { bundle: 'force' }\n})",{"id":715,"title":716,"titles":717,"content":718,"level":320,"path":715,"to":715,"label":716},"/docs/guides/first-party#静态构建不代理","静态构建不代理",[54,697],"症状：脚本加载正常，但静态托管的分析无数据。 说明：这是预期表现——静态构建无法代理请求。请配置托管平台重写（参见“平台重写配置”章节），或使用服务端渲染模式。",{"id":720,"title":721,"titles":722,"content":723,"level":320,"path":720,"to":720,"label":721},"/docs/guides/first-party#脚本下载失败","脚本下载失败",[54,697],"症状：构建时遇到网络超时或下载错误。 解决方案： 启用回退模式：export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    assets: {\n      fallbackOnSrcOnBundleFail: true\n    }\n  }\n})\n增加超时配置：export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      fetchOptions: {\n        timeout: 30000 // 30 秒\n      }\n    }\n  }\n})",{"id":725,"title":726,"titles":727,"content":330,"level":314,"path":725,"to":725,"label":726},"/docs/guides/first-party#常见问题","常见问题",[54],{"id":729,"title":730,"titles":731,"content":732,"level":320,"path":729,"to":729,"label":730},"/docs/guides/first-party#第一方模式会绕过-gdpr-同意要求吗","第一方模式会绕过 GDPR 同意要求吗？",[54,726],"不会。 第一方模式仅变更请求路由，不影响是否进行跟踪。您仍须在加载跟踪脚本前获得用户同意。使用同意触发器实现控制： const { accept } = useScriptTriggerConsent()\n\n// 仅在用户同意后加载脚本\nfunction onConsentGiven() {\n  accept()\n}",{"id":734,"title":735,"titles":736,"content":737,"level":320,"path":734,"to":734,"label":735},"/docs/guides/first-party#第三方修改了脚本分析还能正常吗","第三方修改了脚本，分析还能正常吗？",[54,726],"能，且支持自动更新。 脚本默认缓存 7 天，缓存过期后会自动重新下载并重写 URL。您可自定义缓存时长： export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      cacheMaxAge: 86400000 // 1 天，单位毫秒\n    }\n  }\n})",{"id":739,"title":740,"titles":741,"content":742,"level":320,"path":739,"to":739,"label":740},"/docs/guides/first-party#可以自定义代理路径吗","可以自定义代理路径吗？",[54,726],"可以。 通过 collectPrefix 配置修改默认的收集端点地址： export default defineNuxtConfig({\n  scripts: {\n    firstParty: {\n      collectPrefix: '/_tracking' // 代替默认的 /_scripts/c\n    }\n  }\n})",{"id":744,"title":745,"titles":746,"content":747,"level":320,"path":744,"to":744,"label":745},"/docs/guides/first-party#支持服务器端追踪吗","支持服务器端追踪吗？",[54,726],"第一方模式主要针对客户端脚本。服务器端追踪（如 Measurement Protocol）建议直接从服务器端发送请求，无需代理层。",{"id":749,"title":750,"titles":751,"content":752,"level":320,"path":749,"to":749,"label":750},"/docs/guides/first-party#如何调试被代理的请求","如何调试被代理的请求？",[54,726],"DevTools：打开 Nuxt DevTools → Scripts → 第一方标签页状态端点：开发时访问 /_scripts/status.json 检查状态日志输出：启用调试模式打印日志export default defineNuxtConfig({\n  scripts: {\n    debug: true\n  }\n})",{"id":754,"title":755,"titles":756,"content":757,"level":320,"path":754,"to":754,"label":755},"/docs/guides/first-party#会影响性能吗","会影响性能吗？",[54,726],"影响极小。 代理带来约 10–50 毫秒的延迟，但通常被以下因素抵消： 免去对第三方域名的 DNS 查询绕过可能阻止请求的广告拦截器重用连接减少 TLS 握手时间",{"id":759,"title":760,"titles":761,"content":762,"level":320,"path":759,"to":759,"label":760},"/docs/guides/first-party#哪些脚本支持第一方模式","哪些脚本支持第一方模式？",[54,726],"当前支持文档「支持的脚本」中列出的 11 个脚本。对其他脚本，您可以： 通过 Issue 请求支持使用（已废弃的）bundle 选项自托管脚本手动配置自定义路由规则",{"id":764,"title":765,"titles":766,"content":767,"level":314,"path":764,"to":764,"label":765},"/docs/guides/first-party#混合渲染","混合渲染",[54],"第一方模式兼容 Nuxt 的混合渲染架构：",{"id":769,"title":770,"titles":771,"content":772,"level":320,"path":769,"to":769,"label":770},"/docs/guides/first-party#路由级-ssr","路由级 SSR",[54,765],"禁用特定路由的 SSR 时，第一方模式依旧有效，因为： 脚本在构建阶段打包，不依赖运行时 SSR代理路由由 Nitro 全局配置管理收集请求由服务器转发代理 示例： export default defineNuxtConfig({\n  routeRules: {\n    '/dashboard/**': { ssr: false }, // 仪表盘 SPA 模式\n  },\n  scripts: {\n    firstParty: true, // 各路由均启用第一方\n  }\n})",{"id":774,"title":775,"titles":776,"content":777,"level":320,"path":774,"to":774,"label":775},"/docs/guides/first-party#isr增量静态再生成","ISR（增量静态再生成）",[54,765],"ISR 页面同样支持第一方模式。打包的脚本作为静态资源提供，收集请求由 Nitro 在运行时代理。",{"id":779,"title":780,"titles":781,"content":782,"level":320,"path":779,"to":779,"label":780},"/docs/guides/first-party#edge-渲染","Edge 渲染",[54,765],"支持部署到边缘平台（如 Cloudflare Workers、Vercel Edge）。代理请求通过 Nitro 内置代理功能支持多种目标环境。 部署到边缘时，请确保运行时允许跨域向分析端点发起外部 fetch 请求。",{"id":784,"title":785,"titles":786,"content":787,"level":314,"path":784,"to":784,"label":785},"/docs/guides/first-party#同意集成","同意集成",[54],"第一方模式作为隐私保护方案与同意管理配合增强： 第一方模式 控制请求发送的位置（通过您的服务器代理）同意触发器 控制脚本加载的时机（同意前不注入脚本）",{"id":789,"title":790,"titles":791,"content":792,"level":320,"path":789,"to":789,"label":790},"/docs/guides/first-party#联合使用示例","联合使用示例",[54,785],"\u003Cscript setup>\n// 第一方模式在 nuxt.config.ts 中全局启用\n// 通过同意触发器控制脚本加载\n\nconst { status, accept } = useScriptTriggerConsent()\n\nconst { gtag } = useScriptGoogleAnalytics({\n  id: 'G-XXXXXX',\n  scriptOptions: {\n    trigger: status, // 未同意前不加载\n  }\n})\n\nfunction onConsentGiven() {\n  accept() // 一旦同意，脚本通过第一方代理加载\n}\n\u003C/script>",{"id":794,"title":795,"titles":796,"content":797,"level":320,"path":794,"to":794,"label":795},"/docs/guides/first-party#同意横幅示例","同意横幅示例",[54,785],"\u003Ctemplate>\n  \u003Cdiv v-if=\"!hasConsent\" class=\"cookie-banner\">\n    \u003Cp>我们使用分析数据来提升您的体验。\u003C/p>\n    \u003Cbutton @click=\"acceptAll\">接受\u003C/button>\n    \u003Cbutton @click=\"rejectAll\">拒绝\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nimport { ref } from 'vue'\n\nconst hasConsent = ref(false)\n\nconst { accept: acceptGA } = useScriptTriggerConsent()\nconst { accept: acceptMeta } = useScriptTriggerConsent()\n\nuseScriptGoogleAnalytics({\n  id: 'G-XXXXXX',\n  scriptOptions: { trigger: useScriptTriggerConsent().status }\n})\n\nuseScriptMetaPixel({\n  id: '123456',\n  scriptOptions: { trigger: useScriptTriggerConsent().status }\n})\n\nfunction acceptAll() {\n  hasConsent.value = true\n  acceptGA()\n  acceptMeta()\n  // 脚本通过第一方代理加载\n}\n\nfunction rejectAll() {\n  hasConsent.value = true\n  // 不加载脚本\n}\n\u003C/script>",{"id":799,"title":800,"titles":801,"content":802,"level":320,"path":799,"to":799,"label":800},"/docs/guides/first-party#隐私流程示意","隐私流程示意",[54,785],"用户访问网站\n       │\n       ↓\n脚本注册但未加载（等待同意）\n       │\n       ↓\n用户同意 Cookie\n       │\n       ↓\n脚本通过您的服务器加载（/_scripts/...）\n       │\n       ↓\n分析请求通过您的服务器发送（/_scripts/c/...）\n       │\n       ↓\n第三方看到的是服务器 IP，而非用户 IP 此流程确保 GDPR 合规（先同意后追踪）并增强隐私保护（同意后第一方路由）。",{"id":804,"title":805,"titles":806,"content":807,"level":314,"path":804,"to":804,"label":805},"/docs/guides/first-party#健康检查","健康检查",[54],"验证第一方模式是否正常运行：",{"id":809,"title":810,"titles":811,"content":812,"level":320,"path":809,"to":809,"label":810},"/docs/guides/first-party#_1-检查-devtools","1. 检查 DevTools",[54,805],"打开 Nuxt DevTools → Scripts → 第一方标签页，查看是否启用第一方模式，已配置的脚本及活跃代理路由。",{"id":814,"title":815,"titles":816,"content":817,"level":320,"path":814,"to":814,"label":815},"/docs/guides/first-party#_2-查询状态端点","2. 查询状态端点",[54,805],"开发时访问 /_scripts/status.json，示例输出： {\n  \"enabled\": true,\n  \"scripts\": [\"googleAnalytics\", \"metaPixel\"],\n  \"routes\": {\n    \"/_scripts/c/ga/**\": \"https://www.google.com/**\",\n    \"/_scripts/c/meta/**\": \"https://connect.facebook.net/**\"\n  },\n  \"collectPrefix\": \"/_scripts/c\"\n}",{"id":819,"title":820,"titles":821,"content":822,"level":320,"path":819,"to":819,"label":820},"/docs/guides/first-party#_3-浏览器中验证","3. 浏览器中验证",[54,805],"打开浏览器开发者工具 → 网络面板过滤路径 /_scripts触发分析事件确认请求目标为 /_scripts/c/...，非直接第三方域检查响应状态码为 200",{"id":824,"title":825,"titles":826,"content":827,"level":320,"path":824,"to":824,"label":825},"/docs/guides/first-party#_4-cli-状态检查","4. CLI 状态检查",[54,805],"运行命令查看缓存及状态： npx nuxt-scripts status 显示已缓存的脚本文件及大小。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .si95b, html code.shiki .si95b{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C792EA}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sLn4B, html code.shiki .sLn4B{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sm_uT, html code.shiki .sm_uT{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F07178}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}",{"id":59,"title":58,"titles":829,"content":830,"level":308,"path":59,"to":59,"label":58},[],"通过将第三方脚本与您的应用打包来优化它们。 bundle 选项已弃用，建议使用 First-Party Mode，它提供相同的优势并增加了路由收集端点以提升隐私保护。新项目请使用 firstParty: true。",{"id":832,"title":311,"titles":833,"content":834,"level":314,"path":832,"to":832,"label":311},"/docs/guides/bundling#背景",[58],"当您在网站上使用来自其他站点的脚本时，会依赖另一个服务器来加载这些脚本。这可能会导致网站变慢，并引发安全和隐私方面的担忧。",{"id":836,"title":726,"titles":837,"content":838,"level":320,"path":836,"to":836,"label":726},"/docs/guides/bundling#常见问题",[58,311],"网站变慢，因为连接其他服务器需要时间。如果其他服务器被黑，存在安全风险。访客数据可能被其他服务器不当使用。广告拦截器或隐私工具可能阻止这些脚本运行。",{"id":840,"title":841,"titles":842,"content":843,"level":320,"path":840,"to":840,"label":841},"/docs/guides/bundling#如何解决","如何解决",[58,311],"通过打包这些脚本，您可以自行托管，从而避免这些问题，让您的网站运行更加顺畅。",{"id":845,"title":609,"titles":846,"content":847,"level":314,"path":845,"to":845,"label":609},"/docs/guides/bundling#工作原理",[58],"在构建过程中，会检查您的代码以查找需要打包的 useScript 实例。 当检测到需要打包的脚本时，它会被下载并保存为公共资源，路径为 /_scripts/[hash].js，其中 [hash] 表示脚本 URL 的哈希值。 关于打包的重要事项： 您需要为脚本 URL 和打包设置提供静态值。 // 好例子 - 静态值允许打包\nuseScript('https://example.com/script.js', {\n  bundle: true\n})\n// 坏例子 - 动态值阻止打包\nuseScript(scriptSrc, {\n  bundle: canBundle\n})\n// 好例子 - 脚本已打包\nuseScript('/_scripts/[hash].js', {})\n// 坏例子 - 脚本未打包（保持不变）\nuseScript(scriptSrc, {\n  bundle: canBundle\n}) 如果原始脚本更改但 URL 未变化，浏览器缓存中的打包版本不会更新。为此，请使用带版本号的 URL 或添加防缓存查询参数。",{"id":849,"title":614,"titles":850,"content":851,"level":314,"path":849,"to":849,"label":614},"/docs/guides/bundling#使用方法",[58],"脚本可以单独打包，也可以通过特定设置全局打包。",{"id":853,"title":854,"titles":855,"content":856,"level":320,"path":853,"to":853,"label":854},"/docs/guides/bundling#脚本选项","脚本选项",[58,614],"决定是否打包某个脚本，使用 bundle 选项。 // 选择性打包这个脚本\nuseScript('https://example.com/script.js', {\n  bundle: true,\n})\n\n// 强制下载绕过缓存\nuseScript('https://example.com/script.js', {\n  bundle: 'force',\n})\n// 使用 scriptOptions 打包注册脚本\nuseScriptGoogleAnalytics({\n  id: 'GA_MEASUREMENT_ID',\n  scriptOptions: {\n    bundle: true\n  }\n})\n\n// 无缓存打包\nuseScriptGoogleAnalytics({\n  id: 'GA_MEASUREMENT_ID',\n  scriptOptions: {\n    bundle: 'force'\n  }\n})",{"id":858,"title":859,"titles":860,"content":861,"level":401,"path":858,"to":858,"label":859},"/docs/guides/bundling#打包选项","打包选项",[58,614,854],"bundle 选项支持以下值： false - 不打包脚本（默认）true - 打包脚本，若有缓存则使用缓存版本'force' - 打包脚本，并强制下载绕过缓存 注意： 使用 'force' 会在每次构建时重新下载脚本，可能增加构建时间且安全性较低。",{"id":863,"title":864,"titles":865,"content":866,"level":320,"path":863,"to":863,"label":864},"/docs/guides/bundling#全局打包","全局打包",[58,614],"通过 Nuxt 配置调整所有脚本的默认行为。下例中所有脚本默认启用打包。 export default defineNuxtConfig({\n  scripts: {\n    defaultScriptOptions: {\n      bundle: true,\n    }\n  }\n})",{"id":868,"title":869,"titles":870,"content":871,"level":320,"path":868,"to":868,"label":869},"/docs/guides/bundling#构建时与运行时行为","构建时与运行时行为",[58,614],"理解打包发生时机及其对运行时行为的影响对有效使用至关重要。",{"id":873,"title":874,"titles":875,"content":876,"level":401,"path":873,"to":873,"label":874},"/docs/guides/bundling#构建时处理","构建时处理",[58,614,869],"打包通过静态代码分析在构建阶段完成： // ✅ 构建时打包（静态值）\nuseScript('https://example.com/script.js', { bundle: true })\n\n// ❌ 无法打包（动态值）\nconst scriptUrl = computed(() => getScriptUrl())\nuseScript(scriptUrl, { bundle: dynamic.value })",{"id":878,"title":879,"titles":880,"content":881,"level":401,"path":878,"to":878,"label":879},"/docs/guides/bundling#运行时行为","运行时行为",[58,614,869],"运行时，打包的脚本表现不同： // 原始代码\nuseScript('https://example.com/script.js', { bundle: true })\n\n// 构建转化后\nuseScript('/_scripts/abc123.js', {}) 重要：一旦打包，运行时无法访问原始 URL。如果需要原始 URL 用于追踪或分析，请额外保存。",{"id":883,"title":884,"titles":885,"content":886,"level":401,"path":883,"to":883,"label":884},"/docs/guides/bundling#静态-url-要求","静态 URL 要求",[58,614,869],"打包转换器要求 完全静态的值： // 静态字符串字面量\nuseScript('https://cdn.example.com/lib.js', { bundle: true })\n\n// 静态模板字符串（无变量）\nuseScript(`https://cdn.example.com/lib.js`, { bundle: true })\n\n// 在模块顶层定义的常量\nconst SCRIPT_URL = 'https://cdn.example.com/lib.js'\nuseScript(SCRIPT_URL, { bundle: true })\n// 运行时变量\nconst url = getScriptUrl()\nuseScript(url, { bundle: true })\n\n// 计算属性\nconst scriptUrl = computed(() => `https://cdn.example.com/${version.value}.js`)\nuseScript(scriptUrl, { bundle: true })\n\n// 运行时环境变量\nuseScript(process.env.SCRIPT_URL, { bundle: true })\n\n// Props 或响应式值\nuseScript(props.scriptUrl, { bundle: true })",{"id":888,"title":889,"titles":890,"content":891,"level":401,"path":888,"to":888,"label":889},"/docs/guides/bundling#手动注入模式","手动注入模式",[58,614,869],"当自动打包不可用时，可以手动注入打包脚本： // 1. 使用静态URL构建时打包\nconst staticScript = useScript('https://cdn.example.com/static.js', {\n  bundle: true,\n  trigger: 'manual' // 不自动加载\n})\n\n// 2. 根据运行时逻辑条件加载\nfunction loadScript() {\n  if (shouldLoadScript.value) {\n    staticScript.load()\n  }\n}\n\n// 3. 另一种方案：使用多个静态配置\nconst scriptVariants = {\n  dev: useScript('https://cdn.example.com/dev.js', { bundle: true, trigger: 'manual' }),\n  prod: useScript('https://cdn.example.com/prod.js', { bundle: true, trigger: 'manual' })\n}\n\n// 加载合适的版本\nconst currentScript = computed(() =>\n  isDev ? scriptVariants.dev : scriptVariants.prod\n)",{"id":893,"title":894,"titles":895,"content":896,"level":401,"path":893,"to":893,"label":894},"/docs/guides/bundling#动态-url-处理","动态 URL 处理",[58,614,869],"对于真正动态的场景，可考虑以下方案： // 选项1：预先打包已知变体\nconst analytics = {\n  google: useScript('https://www.googletagmanager.com/gtag/js', { bundle: true }),\n  plausible: useScript('https://plausible.io/js/script.js', { bundle: true })\n}\n\n// 选项2：回退运行时加载\nfunction loadDynamicScript(url: string) {\n  // 该脚本不会被打包，但运行时可用\n  return useScript(url, {\n    bundle: false, // 显式禁用\n    trigger: 'manual'\n  })\n}\n\n// 选项3：使用服务器端打包\n// 将脚本内容存入包内并手动注入\nconst { $script } = useNuxtApp()\n$script.add({\n  innerHTML: await $fetch('/api/dynamic-script-content'),\n})",{"id":898,"title":899,"titles":900,"content":901,"level":320,"path":898,"to":898,"label":899},"/docs/guides/bundling#资源配置","资源配置",[58,614],"利用配置中的 assets 选项定制脚本的打包和缓存行为。 export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      prefix: '/_custom-script-path/',\n      cacheMaxAge: 86400000, // 1 天，单位毫秒\n      integrity: true, // 启用 SRI 哈希生成\n    }\n  }\n})",{"id":903,"title":904,"titles":905,"content":906,"level":401,"path":903,"to":903,"label":904},"/docs/guides/bundling#可用选项","可用选项",[58,614,899],"prefix - 打包脚本服务的自定义路径（默认：/_scripts/）cacheMaxAge - 打包脚本缓存时长，单位毫秒（默认：7 天）integrity - 启用自动 SRI（子资源完整性）哈希生成（默认：false）",{"id":908,"title":909,"titles":910,"content":911,"level":401,"path":908,"to":908,"label":909},"/docs/guides/bundling#缓存行为","缓存行为",[58,614,899],"打包系统使用两种不同的缓存策略： 构建时缓存：由 cacheMaxAge 控制（默认 7 天）。超过该时长的脚本会在构建期间重新下载，确保新鲜度。运行时缓存：打包脚本带有 1 年缓存头，因为它们是基于内容哈希命名的。 这种双重策略平衡了构建性能与浏览器缓存的可靠性。",{"id":913,"title":914,"titles":915,"content":916,"level":320,"path":913,"to":913,"label":914},"/docs/guides/bundling#子资源完整性-sri","子资源完整性 (SRI)",[58,614],"子资源完整性（SRI）是一项安全特性，确保脚本未被篡改。启用时，会为每个打包脚本计算加密哈希，并添加为 integrity 属性。",{"id":918,"title":919,"titles":920,"content":921,"level":401,"path":918,"to":918,"label":919},"/docs/guides/bundling#启用-sri","启用 SRI",[58,614,914],"export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      integrity: true, // 默认使用 sha384\n    }\n  }\n})",{"id":923,"title":924,"titles":925,"content":926,"level":401,"path":923,"to":923,"label":924},"/docs/guides/bundling#哈希算法","哈希算法",[58,614,914],"您可以指定哈希算法： export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      integrity: 'sha384', // 默认，安全性与大小之间的推荐平衡\n      // integrity: 'sha256', // 哈希更小\n      // integrity: 'sha512', // 最强安全性\n    }\n  }\n})",{"id":928,"title":929,"titles":930,"content":931,"level":401,"path":928,"to":928,"label":929},"/docs/guides/bundling#工作流程","工作流程",[58,614,914],"当启用 integrity： 构建时，会对每个打包脚本内容计算哈希哈希存储在构建缓存中以便复用脚本标签中注入 integrity 属性自动添加 crossorigin=\"anonymous\" 属性（浏览器要求） \u003C!-- 启用 integrity 后的输出示例 -->\n\u003Cscript src=\"/_scripts/abc123.js\"\n        integrity=\"sha384-oqVuAfXRKap...\"\n        crossorigin=\"anonymous\">\u003C/script>",{"id":933,"title":934,"titles":935,"content":936,"level":401,"path":933,"to":933,"label":934},"/docs/guides/bundling#安全优势","安全优势",[58,614,914],"篡改检测：若哈希不匹配，浏览器拒绝执行脚本CDN 被攻破保护：即使 CDN 被篡改，修改的脚本也不会被执行构建时校验：哈希基于实际下载的内容计算，确保准确性 html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":63,"title":62,"titles":938,"content":939,"level":308,"path":63,"to":63,"label":62},[],"了解如何在加载脚本前获取用户同意。 尝试在 StackBlitz 上的实时示例：Cookie 同意示例 或 细粒度同意示例。",{"id":941,"title":311,"titles":942,"content":943,"level":314,"path":941,"to":941,"label":311},"/docs/guides/consent#背景",[62],"许多第三方脚本包含根据隐私法规需要用户同意的跟踪 Cookie。Nuxt Scripts 通过 useScriptTriggerConsent 组合函数简化了此过程，允许仅在获得用户同意后加载脚本。",{"id":945,"title":946,"titles":947,"content":948,"level":314,"path":945,"to":945,"label":946},"/docs/guides/consent#用法","用法",[62],"useScriptTriggerConsent 组合函数提供灵活的交互选项，适用于各种场景。 完整可用选项请参见 API 文档。",{"id":950,"title":951,"titles":952,"content":953,"level":320,"path":950,"to":950,"label":951},"/docs/guides/consent#以函数形式接受","以函数形式接受",[62,946],"使用 useScriptTriggerConsent 的最简单方式是在用户同意时调用 accept 方法。 以下示例展示了如何编写代码来处理该流程： export const agreedToCookiesScriptConsent = useScriptTriggerConsent()\n\u003Cscript setup lang=\"ts\">\nimport { agreedToCookiesScriptConsent } from '#imports'\n\nuseScript('https://www.google-analytics.com/analytics.js', {\n  trigger: agreedToCookiesScriptConsent\n})\n\u003C/script>\n\u003Cscript setup lang=\"ts\">\nimport { agreedToCookiesScriptConsent } from '#imports'\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"agreedToCookiesScriptConsent.accept()\">\n    接受 Cookies\n  \u003C/button>\n\u003C/template>",{"id":955,"title":956,"titles":957,"content":958,"level":320,"path":955,"to":955,"label":956},"/docs/guides/consent#以可解析布尔值接受","以可解析布尔值接受",[62,946],"另外，你可以将一个响应式引用传递给同意状态给 useScriptTriggerConsent 组合函数。当同意状态为 true 时，脚本将自动加载。 const agreedToCookies = ref(false)\nuseScript('https://www.google-analytics.com/analytics.js', {\n  trigger: useScriptTriggerConsent({\n    consent: agreedToCookies\n  })\n})",{"id":960,"title":961,"titles":962,"content":963,"level":320,"path":960,"to":960,"label":961},"/docs/guides/consent#在同意后延迟加载脚本","在同意后延迟加载脚本",[62,946],"有时你可能希望在特定事件后再触发脚本加载，且仅在用户已同意时加载。 此时可以使用 postConsentTrigger，它的 API 与 useScript 组合函数中的 trigger 相同。 const agreedToCookies = ref(false)\nuseScript('https://www.google-analytics.com/analytics.js', {\n  trigger: useScriptTriggerConsent({\n    consent: agreedToCookies,\n    // 用户同意后延迟 3 秒加载\n    postConsentTrigger: () => new Promise\u003Cvoid>(resolve =>\n      setTimeout(resolve, 3000),\n    ),\n  })\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}",{"id":67,"title":66,"titles":965,"content":966,"level":308,"path":67,"to":67,"label":66},[],"了解如何向您的分析提供商发送页面事件。",{"id":968,"title":311,"titles":969,"content":970,"level":314,"path":968,"to":968,"label":311},"/docs/guides/page-events#背景",[66],"在使用跟踪脚本时，通常会在页面更改时发送事件。由于 Nuxt 的 head 实现是异步的，页面标题在路由更改时不一定立即可用。 Nuxt Scripts 提供了 useScriptEventPage 组合式函数来解决这个问题。 有关可用选项的完整详细信息，请参阅 API 文档。",{"id":972,"title":946,"titles":973,"content":974,"level":320,"path":972,"to":972,"label":946},"/docs/guides/page-events#用法",[66,311],"该组合式函数通过提供一个函数来工作，该函数将在页面更改时调用，并提供新解析的标题和路径。 您可以将此函数与任何在路由更改时页面标题不准确的分析提供商配合使用。 const { proxy } = useScriptGoogleAnalytics()\n\nuseScriptEventPage(({ title, path }) => {\n  // 在路由更改时触发\n  proxy.gtag('event', 'page_view', {\n    page_title: title,\n    page_location: 'https://example.com',\n    page_path: path\n  })\n}) html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":71,"title":70,"titles":976,"content":977,"level":308,"path":71,"to":71,"label":70},[],"加载全局第三方脚本并为您的 Nuxt 应用优化它们。",{"id":979,"title":311,"titles":980,"content":981,"level":314,"path":979,"to":979,"label":311},"/docs/guides/global#背景",[70],"虽然 Nuxt 配置中的 app.head 方法允许加载全局脚本，但这可能比较繁琐且需要手动优化。 export default defineNuxtConfig({\n  head: {\n    script: [ { src: 'https://analytics.com/tracker.js',  async: true } ]\n  }\n}) 现在有一种更简单的方法：直接将脚本 URL 输入到 scripts.globals 中。您还可以包含可选设置，以针对特定优化自定义脚本加载过程。 您可以考虑在以下情况下使用全局脚本： 脚本不是支持的 注册脚本。您不关心与第三方脚本提供的 API 交互（例如，您不需要使用 Google Analytics 的 gtag）。您确实与第三方脚本提供的 API 交互，但不关心类型安全。 否则，建议使用 useScript 以更安全的方式加载脚本。",{"id":983,"title":946,"titles":984,"content":985,"level":314,"path":983,"to":983,"label":946},"/docs/guides/global#用法",[70],"globals 键支持字符串、对象和数组。 示例：仅使用 src 加载脚本 export default defineNuxtConfig({\n  scripts: {\n    globals: {\n      myScript: 'https://analytics.com/tracker.js',\n    }\n  }\n}) 示例：加载脚本同时提供额外的脚本属性 export default defineNuxtConfig({\n  scripts: {\n    globals: {\n      myScript: {\n        src: 'https://example.com/script.js',\n        integrity: 'sha256-abc123',\n      }\n    }\n  }\n}) 您还可以将脚本作为数组提供，这允许您传递 脚本选项。 export default defineNuxtConfig({\n  scripts: {\n    globals: {\n      myScript: [\n        { src: 'https://example.com/script.js' },\n        // 将脚本作为 hydration 过程的一部分加载，而非在空闲时加载\n        { trigger: 'client' }\n      ]\n    }\n  }\n})",{"id":987,"title":988,"titles":989,"content":990,"level":320,"path":987,"to":987,"label":988},"/docs/guides/global#访问全局脚本","访问全局脚本",[70,946],"所有 Nuxt 脚本都注册在 $scripts Nuxt 应用属性上。 对于通过 nuxt.config 注册的脚本，支持类型自动补全。 \u003Cscript setup lang=\"ts\">\nconst { $scripts } = useNuxtApp()\n$scripts.myScript // { $script, instance }\n\u003C/script>",{"id":992,"title":609,"titles":993,"content":994,"level":314,"path":992,"to":992,"label":609},"/docs/guides/global#工作原理",[70],"globals 配置将用于创建一个虚拟 Nuxt 插件，该插件使用 useScript 组合式函数加载脚本。 由于底层使用了 useScript，了解 useScript 组合式函数的默认值和行为非常重要。 export default defineNuxtConfig({\n  scripts: {\n    globals: {\n      tracker: 'https://analytics.com/tracker.js',\n    }\n  }\n})\n\u003Cscript setup lang=\"ts\">\n// 由于是通过 nuxt.config 全局脚本注册，这不会再次触发脚本加载\nconst { proxy, onLoaded } = useNuxtApp().$scripts.tracker\n\nonLoaded(() => {\n  console.log('脚本已加载')\n})\n\nfunction trackCustom() {\n  proxy.track('custom_event')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"trackCustom\">\n    追踪自定义事件\n  \u003C/button>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}",{"id":75,"title":74,"titles":996,"content":997,"level":308,"path":75,"to":75,"label":74},[],"门面组件是伪造的 UI 元素，一旦第三方脚本加载后会被替换。 Nuxt Scripts 提供了若干门面组件供你使用，以加速应用的性能。 使用它们有利弊，但可以帮助提升应用的性能体验。",{"id":999,"title":1000,"titles":1001,"content":1002,"level":314,"path":999,"to":999,"label":1000},"/docs/guides/facade-components#什么是门面组件","什么是门面组件？",[74],"为了渲染诸如视频嵌入、支付弹窗或聊天插件等第三方脚本所依赖的复杂组件，我们需要加载许多资源。\n在 Nuxt 启动时加载它们会降低你的应用性能。 然而，如果我们延迟加载脚本直到 Nuxt 启动完成，会导致有害的内容布局偏移（CLS）和视觉噪点，\n进而造成较差的用户体验。 门面组件的目标是通过渲染一个“假”的 UI 元素来解决这个问题，这个“假”元素会在第三方脚本加载后被替换。 通过钩住合适的 DOM 事件并提供用户反馈，我们可以使用这些假元素，同时仍然保障良好的用户体验。",{"id":1004,"title":1005,"titles":1006,"content":1007,"level":314,"path":1004,"to":1004,"label":1005},"/docs/guides/facade-components#使用门面组件的利弊是什么","使用门面组件的利弊是什么？",[74],"虽然性能上的提升非常明显，但在用户体验上可能存在权衡。 内容不匹配的闪烁：假 UI 元素可能与最终的 UI 元素外观不同，导致内容闪烁错位。Nuxt Scripts 只提供了最小化的样式，你可能需要调整以匹配你的应用设计。交互性可能中断：元素的交互性依赖于脚本的加载，如果脚本未加载，你需要提供降级处理。无障碍性问题：需要在脚本加载或加载失败时，向用户提供明确的无障碍（a11y）反馈。",{"id":1009,"title":1010,"titles":1011,"content":1012,"level":314,"path":1009,"to":1009,"label":1010},"/docs/guides/facade-components#nuxt-scripts-门面组件","Nuxt Scripts 门面组件",[74],"所有门面组件都是无样式组件，包装对应的 useScript\u003Cprovider> 组合式函数。文档中仅提供最小化样式，作为起点。",{"id":1014,"title":1015,"titles":1016,"content":330,"level":314,"path":1014,"to":1014,"label":1015},"/docs/guides/facade-components#使用门面组件的最佳实践","使用门面组件的最佳实践",[74],{"id":1018,"title":1019,"titles":1020,"content":1021,"level":320,"path":1018,"to":1018,"label":1019},"/docs/guides/facade-components#提供错误降级处理","提供错误降级处理",[74,1015],"如果脚本加载失败，提供一个降级方案，告知用户加载失败并提供访问内容的替代方式。 \u003CScriptYouTubePlayer>\n  \u003Ctemplate #error>\n    \u003CUAlert color=\"red\" title=\"YouTube 播放器加载失败\" description=\"请刷新页面重试。\" />\n  \u003C/template>\n\u003C/ScriptYouTubePlayer>",{"id":1023,"title":1024,"titles":1025,"content":1026,"level":320,"path":1023,"to":1023,"label":1024},"/docs/guides/facade-components#提供可访问的加载状态反馈","提供可访问的加载状态反馈",[74,1015],"脚本加载期间，提供加载状态，告知用户内容正在加载中。 ScriptLoadingIndicator 组件由 Nuxt Scripts 提供，帮助实现加载状态展示并提供无障碍反馈。 \u003CScriptYouTubePlayer>\n  \u003Ctemplate #loading>\n    \u003CScriptLoadingIndicator />\n  \u003C/template>\n\u003C/ScriptYouTubePlayer>",{"id":1028,"title":1029,"titles":1030,"content":1031,"level":320,"path":1028,"to":1028,"label":1029},"/docs/guides/facade-components#明智地选择触发事件","明智地选择触发事件",[74,1015],"门面组件预设了最佳的通用性能事件触发，但你可以自定义触发事件，使其更契合你的应用需求。 最佳触发事件是需要明确用户交互的事件，如点击。\n鼠标悬停加载可能导致用户体验问题，比如丢失后续点击事件。",{"id":1033,"title":1034,"titles":1035,"content":1036,"level":314,"path":1033,"to":1033,"label":1034},"/docs/guides/facade-components#门面组件-api","门面组件 API",[74],"所有门面组件共享相似的 API。",{"id":1038,"title":1039,"titles":1040,"content":1041,"level":320,"path":1038,"to":1038,"label":1039},"/docs/guides/facade-components#props","Props",[74,1034],"trigger - 触发脚本加载的事件。详情请参见 元素事件触发器。",{"id":1043,"title":1044,"titles":1045,"content":1046,"level":320,"path":1043,"to":1043,"label":1044},"/docs/guides/facade-components#插槽","插槽",[74,1034],"该组件默认只提供最小化 UI，保证功能和可访问性。你可通过多个插槽按需自定义组件。 default - 组件始终显示的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer>\n    \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n      Youtube!\n    \u003C/div>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> loading - 仅在脚本加载中显示的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer>\n    \u003Ctemplate #loading>\n      \u003CScriptLoadingIndicator />\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> awaitingLoad - 脚本等待加载时显示的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer>\n    \u003Ctemplate #awaitingLoad>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        点击播放！\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> error - 当脚本加载失败时显示的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer>\n    \u003Ctemplate #error>\n      \u003CUAlert color=\"red\" title=\"YouTube 播放器加载失败\" description=\"请刷新页面重试。\" />\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template>",{"id":1048,"title":1049,"titles":1050,"content":1051,"level":320,"path":1048,"to":1048,"label":1049},"/docs/guides/facade-components#事件","事件",[74,1034],"ready - 脚本加载完成时触发，提供底层脚本 API 的访问权限。error - 脚本加载失败时触发。 html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}",{"id":79,"title":78,"titles":1053,"content":1054,"level":308,"path":79,"to":79,"label":78},[],"了解 Nuxt 脚本如何处理跨域安全。",{"id":1056,"title":311,"titles":1057,"content":1058,"level":314,"path":1056,"to":1056,"label":311},"/docs/guides/cors#背景",[78],"当从外部域加载脚本时，浏览器会强制执行跨源资源共享（CORS）策略。CORS 控制一个域上的资源如何被另一个域运行的脚本请求。对于第三方脚本，这影响： 是否随请求发送 cookie访问错误详情以便调试子资源完整性（SRI）验证",{"id":1060,"title":458,"titles":1061,"content":1062,"level":314,"path":1060,"to":1060,"label":458},"/docs/guides/cors#默认行为",[78],"Nuxt 脚本对所有脚本应用以隐私为中心的默认设置： \u003Cscript\n  src=\"https://example.com/script.js\"\n  crossorigin=\"anonymous\"\n  referrerpolicy=\"no-referrer\"\n>\u003C/script> 这些默认设置： crossorigin=\"anonymous\" - 阻止脚本向第三方服务器发送 cookiereferrerpolicy=\"no-referrer\" - 阻止向第三方服务器共享页面 URL 这提高了用户隐私，但可能会导致需要 cookie 或来源信息的脚本无法正常工作。",{"id":1064,"title":1065,"titles":1066,"content":330,"level":314,"path":1064,"to":1064,"label":1065},"/docs/guides/cors#常见-cors-错误","常见 CORS 错误",[78],{"id":1068,"title":1069,"titles":1070,"content":1071,"level":320,"path":1068,"to":1068,"label":1069},"/docs/guides/cors#脚本加载失败","脚本加载失败",[78,1065],"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource 当服务器未返回正确的 CORS 头，而设置了 crossorigin=\"anonymous\" 时会发生此情况。一些第三方脚本不支持 CORS。",{"id":1073,"title":1074,"titles":1075,"content":1076,"level":320,"path":1073,"to":1073,"label":1074},"/docs/guides/cors#脚本加载但功能失败","脚本加载但功能失败",[78,1065],"脚本加载了但功能损坏，因为它期望有 cookie 或会话数据。",{"id":1078,"title":1079,"titles":1080,"content":1081,"level":320,"path":1078,"to":1078,"label":1079},"/docs/guides/cors#错误详情被隐藏","错误详情被隐藏",[78,1065],"window.onerror = (msg) => console.log(msg)\n// 显示为：“Script error.” 而非实际错误信息 没有设置 crossorigin，浏览器出于安全考虑会隐藏来自外部脚本的错误细节。",{"id":1083,"title":1084,"titles":1085,"content":330,"level":314,"path":1083,"to":1083,"label":1084},"/docs/guides/cors#配置-cors-属性","配置 CORS 属性",[78],{"id":1087,"title":1088,"titles":1089,"content":1090,"level":320,"path":1087,"to":1087,"label":1088},"/docs/guides/cors#针对单个脚本的配置","针对单个脚本的配置",[78,1084],"禁用不支持 CORS 属性的脚本： useScript({\n  src: 'https://example.com/script.js',\n  crossorigin: false, // 移除 crossorigin 属性\n  referrerpolicy: false, // 移除 referrerpolicy 属性\n}) 或者使用不同的 crossorigin 值： useScript({\n  src: 'https://example.com/script.js',\n  crossorigin: 'use-credentials', // 发送请求时带上 cookie\n})",{"id":1092,"title":1093,"titles":1094,"content":1095,"level":320,"path":1092,"to":1092,"label":1093},"/docs/guides/cors#全局配置","全局配置",[78,1084],"更改所有脚本的默认值： export default defineNuxtConfig({\n  scripts: {\n    defaultScriptOptions: {\n      crossorigin: false,\n      referrerpolicy: false,\n    }\n  }\n})",{"id":1097,"title":1098,"titles":1099,"content":1100,"level":314,"path":1097,"to":1097,"label":1098},"/docs/guides/cors#crossorigin-值说明","Crossorigin 值说明",[78],"值是否发送 cookie是否显示错误详情使用场景anonymous否是（如果服务器支持）注重隐私的默认值use-credentials是是需要身份验证的脚本false是否不支持 CORS 的脚本",{"id":1102,"title":1103,"titles":1104,"content":1105,"level":314,"path":1102,"to":1102,"label":1103},"/docs/guides/cors#注册脚本","注册脚本",[78],"许多注册脚本已禁用 CORS 属性，因为对应的第三方不支持： // 来自 useScriptStripe\nscriptInput: {\n  src: 'https://js.stripe.com/basil/stripe.js',\n  crossorigin: false,\n  referrerpolicy: false,\n} 设置 crossorigin: false 的脚本包括： StripeYouTube 播放器Google 登录Google reCAPTCHAMeta PixelTikTok PixelX（Twitter）PixelSnapchat PixelCloudflare Web AnalyticsLemon SqueezyMatomo Analytics 如果注册脚本失败，请检查是否需要调整 CORS 配置。",{"id":1107,"title":1108,"titles":1109,"content":1110,"level":314,"path":1107,"to":1107,"label":1108},"/docs/guides/cors#子资源完整性","子资源完整性",[78],"使用打包脚本并启用 SRI时，crossorigin=\"anonymous\" 是必需的，并会被自动添加： export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      integrity: true, // 会自动设置 crossorigin=\"anonymous\"\n    }\n  }\n})",{"id":1112,"title":1113,"titles":1114,"content":330,"level":314,"path":1112,"to":1112,"label":1113},"/docs/guides/cors#故障排除","故障排除",[78],{"id":1116,"title":1117,"titles":1118,"content":1119,"level":320,"path":1116,"to":1116,"label":1117},"/docs/guides/cors#脚本无法加载","脚本无法加载",[78,1113],"检查浏览器控制台中的 CORS 错误设置 crossorigin: false 来禁用 CORS 模式验证第三方服务器是否支持 CORS 头",{"id":1121,"title":1122,"titles":1123,"content":1124,"level":320,"path":1121,"to":1121,"label":1122},"/docs/guides/cors#脚本加载但功能异常","脚本加载但功能异常",[78,1113],"脚本可能需要 cookie — 尝试 crossorigin: 'use-credentials'脚本可能需要来源信息 — 设置 referrerpolicy: false检查脚本是否预期不带 CORS 属性加载",{"id":1126,"title":1127,"titles":1128,"content":1129,"level":320,"path":1126,"to":1126,"label":1127},"/docs/guides/cors#调试外部脚本错误","调试外部脚本错误",[78,1113],"查看外部脚本的完整错误信息步骤： 确保脚本有 crossorigin=\"anonymous\"验证服务器返回了 Access-Control-Allow-Origin 头如果服务器不支持 CORS，将无法获得详细错误",{"id":1131,"title":1132,"titles":1133,"content":1134,"level":320,"path":1131,"to":1131,"label":1132},"/docs/guides/cors#使用打包作为备选方案","使用打包作为备选方案",[78,1113],"如果 CORS 问题持续存在，可以考虑打包脚本，将其托管在自己的域名下，从而完全避免 CORS 问题。 html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}",{"id":83,"title":82,"titles":1136,"content":1137,"level":308,"path":83,"to":83,"label":82},[],"从 v0.x 升级到 v1.0 的迁移指南。",{"id":1139,"title":1140,"titles":1141,"content":1142,"level":314,"path":1139,"to":1139,"label":1140},"/docs/guides/v1-migration#v1-新特性","v1 新特性",[82],"v1 着重于隐私和性能——通过您自己的域名路由分析，脚本移出主线程，并在服务器端渲染社交嵌入内容。",{"id":1144,"title":54,"titles":1145,"content":1146,"level":320,"path":1144,"to":1144,"label":54},"/docs/guides/v1-migration#第一方模式",[82,1140],"通过您自己的域名路由所有脚本流量，以保障隐私和广告拦截器兼容性。 export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      googleAnalytics: { id: 'G-XXXXXX' },\n      metaPixel: { id: '123456' },\n    }\n  }\n}) 用户 IP 保持私密 — 第三方只看到您服务器的 IP无第三方 Cookie — 请求是同源的兼容广告拦截器 — 请求表现为第一方 支持：Google Analytics、GTM、Meta Pixel、TikTok、Segment、Clarity、Hotjar、X/Twitter、Snapchat、Reddit。",{"id":1148,"title":1149,"titles":1150,"content":1151,"level":320,"path":1148,"to":1148,"label":1149},"/docs/guides/v1-migration#partytown-支持","Partytown 支持",[82,1140],"利用 web workers 将脚本从主线程加载。 export default defineNuxtConfig({\n  modules: ['@nuxtjs/partytown', '@nuxt/scripts'],\n  scripts: {\n    partytown: ['plausible', 'fathom', 'umami'],\n    registry: {\n      plausible: { domain: 'example.com' }\n    }\n  }\n}) 转发数组对支持的脚本会自动配置。 GA4 在 Partytown 中存在已知问题。GTM 不兼容。建议使用 Plausible、Fathom 或 Umami。",{"id":1153,"title":1154,"titles":1155,"content":1156,"level":320,"path":1153,"to":1153,"label":1154},"/docs/guides/v1-migration#ssr-社交嵌入","SSR 社交嵌入",[82,1140],"服务器端渲染 X（原 Twitter）和 Instagram 嵌入，无需加载第三方 JavaScript。 \u003CScriptXEmbed tweet-id=\"1754336034228171055\">\n  \u003Ctemplate #default=\"{ userName, text, likesFormatted }\">\n    \u003C!-- 通过作用域插槽完全控制样式 -->\n  \u003C/template>\n\u003C/ScriptXEmbed>\n\n\u003CScriptInstagramEmbed post-url=\"https://instagram.com/p/ABC123/\">\n  \u003Ctemplate #default=\"{ html }\">\n    \u003Cdiv v-html=\"html\" />\n  \u003C/template>\n\u003C/ScriptInstagramEmbed> 零第三方 JavaScriptX/Instagram 不会设置 Cookie不共享用户 IP所有内容均从您的域名提供",{"id":1158,"title":1159,"titles":1160,"content":1161,"level":320,"path":1158,"to":1158,"label":1159},"/docs/guides/v1-migration#脚本重载","脚本重载",[82,1140],"SPA 导航后重新执行 DOM 扫描脚本： const script = useScript('/third-party.js')\nawait script.reload()",{"id":1163,"title":1164,"titles":1165,"content":1166,"level":320,"path":1163,"to":1163,"label":1164},"/docs/guides/v1-migration#sri-完整性哈希","SRI 完整性哈希",[82,1140],"export default defineNuxtConfig({\n  scripts: {\n    assets: {\n      integrity: 'sha384' // 或 'sha256'、'sha512'\n    }\n  }\n})",{"id":1168,"title":1169,"titles":1170,"content":1171,"level":320,"path":1168,"to":1168,"label":1169},"/docs/guides/v1-migration#gtm-默认同意","GTM 默认同意",[82,1140],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: {\n        id: 'GTM-XXXX',\n        defaultConsent: {\n          ad_storage: 'denied',\n          analytics_storage: 'denied'\n        }\n      }\n    }\n  }\n})",{"id":1173,"title":1174,"titles":1175,"content":1176,"level":320,"path":1173,"to":1173,"label":1174},"/docs/guides/v1-migration#新增注册脚本","新增注册脚本",[82,1140],"PostHog — 产品分析及功能开关Google reCAPTCHA v3 — 隐形机器人防护TikTok Pixel — 转化跟踪Google Sign-In — 一键登录认证",{"id":1178,"title":1179,"titles":1180,"content":1181,"level":320,"path":1178,"to":1178,"label":1179},"/docs/guides/v1-migration#google-地图配色模式","Google 地图配色模式",[82,1140],"\u003CScriptGoogleMaps\n  :map-ids=\"{ light: 'LIGHT_MAP_ID', dark: 'DARK_MAP_ID' }\"\n/> 自动根据 @nuxtjs/color-mode 或手动 color-mode 属性切换。",{"id":1183,"title":1184,"titles":1185,"content":330,"level":314,"path":1183,"to":1183,"label":1184},"/docs/guides/v1-migration#重大变更","重大变更",[82],{"id":1187,"title":208,"titles":1188,"content":330,"level":320,"path":1187,"to":1187,"label":208},"/docs/guides/v1-migration#youtube-播放器",[82,1184],{"id":1190,"title":1191,"titles":1192,"content":1193,"level":401,"path":1190,"to":1190,"label":1191},"/docs/guides/v1-migration#宽高比","宽高比",[82,1184,208],"使用 ratio 属性替代从 width/height 推导： \u003CScriptYouTubePlayer\n  video-id=\"...\"\n-  :width=\"1280\"\n-  :height=\"720\"\n+  ratio=\"16/9\"\n/> 默认是 16/9。",{"id":1195,"title":1196,"titles":1197,"content":1198,"level":401,"path":1195,"to":1195,"label":1196},"/docs/guides/v1-migration#占位图像","占位图像",[82,1184,208],"默认的 object-fit 从 contain 改为 cover： \u003CScriptYouTubePlayer video-id=\"...\" placeholder-object-fit=\"contain\" />",{"id":1200,"title":1201,"titles":1202,"content":1203,"level":401,"path":1200,"to":1200,"label":1201},"/docs/guides/v1-migration#多播放器","多播放器",[82,1184,208],"现在播放器实例已正确隔离。请移除任何针对多播放器的解决方案。",{"id":1205,"title":260,"titles":1206,"content":330,"level":320,"path":1205,"to":1205,"label":260},"/docs/guides/v1-migration#google-tag-manager",[82,1184],{"id":1208,"title":1209,"titles":1210,"content":1211,"level":401,"path":1208,"to":1208,"label":1209},"/docs/guides/v1-migration#onbeforegtmstart-回调","onBeforeGtmStart 回调",[82,1184,260],"现会在缓存/预初始化脚本时触发。需防止多次调用： let initialized = false\nuseScriptGoogleTagManager({\n  onBeforeGtmStart: (gtag) => {\n    if (initialized) return\n    initialized = true\n    // 你的初始化代码\n  }\n})",{"id":1213,"title":1214,"titles":1215,"content":1216,"level":320,"path":1213,"to":1213,"label":1214},"/docs/guides/v1-migration#类型增强","类型增强",[82,1184],"模板结构已重新组织。升级后请执行 nuxi prepare。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s5fEm, html code.shiki .s5fEm{--shiki-light:#B31D28;--shiki-default:#B31D28;--shiki-dark:#89DDFF}html pre.shiki code .sn8kP, html code.shiki .sn8kP{--shiki-light:#B31D28;--shiki-default:#B31D28;--shiki-dark:#F07178}html pre.shiki code .sp6US, html code.shiki .sp6US{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#89DDFF}html pre.shiki code .sIsLN, html code.shiki .sIsLN{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#C3E88D}",{"id":93,"title":92,"titles":1218,"content":1219,"level":308,"path":93,"to":93,"label":92},[],"useScript 函数的 API 文档。 试用 StackBlitz 上的 自定义脚本示例。 此组合函数是对 Unhead useScript 的封装，添加了 Nuxt 特有的增强功能，有关完整文档请参考此处。",{"id":1221,"title":1222,"titles":1223,"content":1224,"level":314,"path":1221,"to":1221,"label":1222},"/docs/api/use-script#函数签名","函数签名",[92],"export function useScript\u003CT extends Record\u003Cstring | symbol, any>>(input: UseScriptInput, options?: NuxtUseScriptOptions): T & { $script: Promise\u003CT> & VueScriptInstance\u003CT> } {}",{"id":1226,"title":1227,"titles":1228,"content":330,"level":314,"path":1226,"to":1226,"label":1227},"/docs/api/use-script#参数","参数",[92],{"id":1230,"title":1231,"titles":1232,"content":1233,"level":320,"path":1230,"to":1230,"label":1231},"/docs/api/use-script#usescriptinput","UseScriptInput",[92,1227],"这是脚本标签的输入。例如，可以传入一个 URL 字符串，或包含脚本标签属性的对象。 export type UseScriptInput = string | {\n  src?: string\n  async?: boolean\n  defer?: boolean\n  type?: string\n  integrity?: string\n  crossorigin?: string\n  text?: string\n  innerHTML?: string\n  innerText?: string\n  content?: string\n  referrerPolicy?: string\n  attributes?: Record\u003Cstring, string>\n} 更多参数信息请参阅 脚本输入 文档。",{"id":1235,"title":1236,"titles":1237,"content":1238,"level":320,"path":1235,"to":1235,"label":1236},"/docs/api/use-script#nuxtusescriptoptions","NuxtUseScriptOptions",[92,1227],"更多参数信息请参阅 脚本选项 文档。 use - 用于解析脚本的函数。trigger - 触发脚本加载bundle - 远程脚本打包 相关信息。 export type NuxtUseScriptOptions\u003CT = any> = Omit\u003CUseScriptOptions\u003CT>, 'trigger'> & {\n  /**\n   * 加载脚本的触发时机：\n   * - `onNuxtReady` - 当 Nuxt 准备就绪时加载脚本。\n   * - `manual` - 通过调用 `load()` 手动加载脚本。\n   * - `Promise` - 当 Promise 解析完成时加载脚本。\n   */\n  trigger?: UseScriptOptions\u003CT>['trigger'] | 'onNuxtReady'\n  /**\n   * 是否将脚本打包为资源并从服务器加载。这有利于提升性能，减少额外的 DNS 查询和请求数，\n   * 同时提升隐私保护，避免将用户 IP 地址泄露给第三方服务器。\n   * - `true` - 将脚本打包为资源。\n   * - `false` - 不打包脚本。（默认）\n   */\n  bundle?: boolean\n  /**\n   * [实验性] 使用 Partytown 在 web worker 中加载脚本。\n   * 启用后，会为脚本标签添加 `type=\"text/partytown\"`。\n   * 需要另外安装和配置 @nuxtjs/partytown。\n   * 注意：需要访问 DOM 的脚本（如 GTM、Hotjar、聊天小部件）不兼容。\n   * @see https://partytown.qwik.dev/\n   */\n  partytown?: boolean\n  /**\n   * 跳过对脚本输入的任何模式校验。这对于开发时加载脚本存根不加载实际脚本且避免警告非常有用。\n   */\n  skipValidation?: boolean\n}",{"id":1240,"title":1241,"titles":1242,"content":1243,"level":314,"path":1240,"to":1240,"label":1241},"/docs/api/use-script#返回值","返回值",[92],"更多返回值信息请参阅 理解代理函数 和 $script 文档。 返回对象包含： status - 响应式 ref，代表脚本状态： 'awaitingLoad' | 'loading' | 'loaded' | 'error'load() - 手动加载脚本的函数remove() - 从 DOM 中移除脚本的函数reload() - 移除并重新加载脚本的函数（详见下文）",{"id":1245,"title":1246,"titles":1247,"content":1248,"level":320,"path":1245,"to":1245,"label":1246},"/docs/api/use-script#reload","reload()",[92,1241],"移除脚本并重新加载，强制重新执行。适用于某些第三方脚本仅在首次加载时扫描 DOM 的场景，需在 SPA 导航后重新运行。 const { reload } = useScript('https://example.com/dom-scanner.js')\n\n// 导航时重新加载\nwatch(() => route.path, () => reload()) 许多第三方脚本自带 SPA 支持（例如 iubenda 的 _iub.cs.api.activateSnippets()）。使用 reload() 前请先查看脚本文档——它们自带的方法通常更高效。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}",{"id":97,"title":96,"titles":1250,"content":1251,"level":308,"path":97,"to":97,"label":96},[],"useScriptTriggerConsent 函数的 API 文档。 在通过可解析的 consent 或调用 accept 方法提供同意后，加载脚本。 该触发器本身不会执行任何操作——脚本只有在通过调用 accept() 方法或提供解析为 true 的 consent 选项时获得同意后才会加载。",{"id":1253,"title":1222,"titles":1254,"content":1255,"level":314,"path":1253,"to":1253,"label":1222},"/docs/api/use-script-trigger-consent#函数签名",[96],"function useScriptTriggerConsent(options?: ConsentScriptTriggerOptions): UseConsentScriptTriggerApi {}",{"id":1257,"title":1227,"titles":1258,"content":1259,"level":314,"path":1257,"to":1257,"label":1227},"/docs/api/use-script-trigger-consent#参数",[96],"export interface ConsentScriptTriggerOptions {\n  /**\n   * 一个可选的响应式（或 Promise）引用，表示同意状态。你可以使用它来代替调用 accept() 方法接受脚本的同意。\n   */\n  consent?: Promise\u003Cboolean | void> | Ref\u003Cboolean> | ComputedRef\u003Cboolean> | boolean\n  /**\n   * 是否应在 `requestIdleCallback` 回调中加载脚本。对于已同意加载的非关键脚本，这非常有用。\n   */\n  postConsentTrigger?: NuxtUseScriptOptions['trigger']\n}",{"id":1261,"title":1241,"titles":1262,"content":1263,"level":314,"path":1261,"to":1261,"label":1241},"/docs/api/use-script-trigger-consent#返回值",[96],"一个扩展的 Promise API，带有一个 accept 方法用于接受同意并加载脚本。 interface UseConsentScriptTriggerApi extends Promise\u003Cvoid> {\n  /**\n   * 一个可以调用以接受同意并加载脚本的函数。\n   */\n  accept: () => void\n}",{"id":1265,"title":1266,"titles":1267,"content":330,"level":314,"path":1265,"to":1265,"label":1266},"/docs/api/use-script-trigger-consent#示例","示例",[96],{"id":1269,"title":1270,"titles":1271,"content":1272,"level":320,"path":1269,"to":1269,"label":1270},"/docs/api/use-script-trigger-consent#基本用法","基本用法",[96,1266],"\u003Cscript setup lang=\"ts\">\nconst trigger = useScriptTriggerConsent()\nuseScript('https://example.com/script.js', { trigger })\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"trigger.accept\">\n    接受同意\n  \u003C/button>\n\u003C/template> html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}",{"id":101,"title":100,"titles":1274,"content":1275,"level":308,"path":101,"to":101,"label":100},[],"useScriptTriggerElement 函数的 API 文档。 创建一个触发器，根据特定的元素事件来加载脚本。",{"id":1277,"title":1278,"titles":1279,"content":1280,"level":314,"path":1277,"to":1277,"label":1278},"/docs/api/use-script-trigger-element#签名","签名",[100],"function useScriptTriggerElement(options: ElementScriptTriggerOptions): Promise\u003Cvoid> & { ssrAttrs?: Record\u003Cstring, string> } | 'onNuxtReady' {}",{"id":1282,"title":1227,"titles":1283,"content":1284,"level":314,"path":1282,"to":1282,"label":1227},"/docs/api/use-script-trigger-element#参数",[100],"export interface ElementScriptTriggerOptions {\n  /**\n   * 触发脚本加载的事件。\n   * \n   * 例如我们可以绑定通常使用 addEventListener 的事件：`mousedown`、`mouseenter`、`scroll` 等。\n   */\n  trigger?: 'immediate' | 'visible' | string | string[] | false | undefined\n  /**\n   * 监听触发事件的元素。\n   * @default document.body\n   */\n  el?: HTMLElement | Ref\u003CHTMLElement | undefined> | null\n}",{"id":1286,"title":1241,"titles":1287,"content":1288,"level":314,"path":1286,"to":1286,"label":1241},"/docs/api/use-script-trigger-element#返回值",[100],"返回一个 Promise，当脚本加载完成时会被解析。",{"id":1290,"title":1291,"titles":1292,"content":1293,"level":314,"path":1290,"to":1290,"label":1291},"/docs/api/use-script-trigger-element#处理预水合事件","处理预水合事件",[100],"当注册依赖用户输入的触发器时（例如 mousedown），用户可能会在水合（hydration）过程完成之前与元素互动。 此时，事件监听器还未绑定到元素上，脚本也不会被加载。 为了确保正确处理，应该将 ssrAttrs 值绑定到你附加事件的元素上。注意，在使用 ssrAttrs 值之前，应确认函数返回的是 Promise。 \u003Cscript setup lang=\"ts\">\nimport { ref, useScriptTriggerElement } from '#imports'\n\nconst el = ref\u003CHTMLElement>()\nconst trigger = useScriptTriggerElement({\n  trigger: 'mousedown',\n  el,\n})\n\nconst elAttrs = computed(() => {\n  return {\n    ...(trigger instanceof Promise ? trigger.ssrAttrs : {}),\n  }\n})\n\u003C/script>\n\u003Ctemplate>\n  \u003Cdiv ref=\"el\" v-bind=\"elAttrs\">\n    点击我以加载脚本\n  \u003C/div>\n\u003C/template>",{"id":1295,"title":1266,"titles":1296,"content":1297,"level":314,"path":1295,"to":1295,"label":1266},"/docs/api/use-script-trigger-element#示例",[100],"当元素出现在视口时加载脚本。 \u003Cscript setup lang=\"ts\">\nconst el = ref\u003CHTMLElement>()\nuseScript('/script.js', {\n  trigger: useScriptTriggerElement({\n    trigger: 'visible',\n    el,\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv style=\"height: 100vh;\">\n    \u003Ch1>向下滚动以加载脚本\u003C/h1>\n  \u003C/div>\n  \u003Cdiv ref=\"el\">\n    \u003Ch1>脚本已加载！\u003C/h1>\n  \u003C/div>\n\u003C/template> 当元素被悬停时加载脚本。 \u003Cscript setup lang=\"ts\">\nconst el = ref\u003CHTMLElement>()\nuseScript('/script.js', {\n  trigger: useScriptTriggerElement({\n    trigger: 'hover',\n    el,\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv ref=\"el\">\n    \u003Ch1>鼠标悬停我以加载脚本\u003C/h1>\n  \u003C/div>\n\u003C/template> html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}",{"id":105,"title":104,"titles":1299,"content":1300,"level":308,"path":105,"to":105,"label":104},[],"useScriptTriggerIdleTimeout 函数的 API 文档。 创建一个触发器，在 Nuxt 准备就绪后，经过空闲超时后加载脚本。这对于非关键脚本非常有用，可以延迟加载以进一步减少对初始页面性能的影响。",{"id":1302,"title":1222,"titles":1303,"content":1304,"level":314,"path":1302,"to":1302,"label":1222},"/docs/api/use-script-trigger-idle-timeout#函数签名",[104],"function useScriptTriggerIdleTimeout(options: IdleTimeoutScriptTriggerOptions): Promise\u003Cboolean>",{"id":1306,"title":1227,"titles":1307,"content":1308,"level":314,"path":1306,"to":1306,"label":1227},"/docs/api/use-script-trigger-idle-timeout#参数",[104],"export interface IdleTimeoutScriptTriggerOptions {\n  /**\n   * 在加载脚本之前等待的超时时间（毫秒）。\n   */\n  timeout: number\n}",{"id":1310,"title":1241,"titles":1311,"content":1312,"level":314,"path":1310,"to":1310,"label":1241},"/docs/api/use-script-trigger-idle-timeout#返回值",[104],"返回一个 Promise，当超时完成且应加载脚本时，解析为 true，如果触发器被取消，则解析为 false。",{"id":1314,"title":1315,"titles":1316,"content":1317,"level":314,"path":1314,"to":1314,"label":1315},"/docs/api/use-script-trigger-idle-timeout#nuxt-配置用法","Nuxt 配置用法",[104],"为了方便起见，您可以直接在 nuxt.config 中使用此触发器，而不需要显式调用组合函数： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAnalytics: [{\n        id: 'GA_MEASUREMENT_ID'\n      }, {\n        trigger: { idleTimeout: 3000 } // Nuxt 准备后 3 秒加载\n      }]\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    globals: {\n      chatWidget: ['https://widget.example.com/chat.js', {\n        trigger: { idleTimeout: 5000 } // Nuxt 准备后 5 秒加载\n      }]\n    }\n  }\n})",{"id":1319,"title":1266,"titles":1320,"content":330,"level":314,"path":1319,"to":1319,"label":1266},"/docs/api/use-script-trigger-idle-timeout#示例",[104],{"id":1322,"title":1270,"titles":1323,"content":1324,"level":320,"path":1322,"to":1322,"label":1270},"/docs/api/use-script-trigger-idle-timeout#基本用法",[104,1266],"在 Nuxt 准备就绪后 5 秒加载脚本： const script = useScript({\n  src: 'https://example.com/analytics.js',\n}, {\n  trigger: useScriptTriggerIdleTimeout({ timeout: 5000 })\n})",{"id":1326,"title":1327,"titles":1328,"content":1329,"level":320,"path":1326,"to":1326,"label":1327},"/docs/api/use-script-trigger-idle-timeout#延迟加载分析脚本","延迟加载分析脚本",[104,1266],"非常适合不需要立即加载的分析脚本： \u003Cscript setup lang=\"ts\">\n// 在 3 秒延迟后加载 Google Analytics\nconst { $script } = useScriptGoogleAnalytics({\n  id: 'GA_MEASUREMENT_ID'\n}, {\n  trigger: useScriptTriggerIdleTimeout({ timeout: 3000 })\n})\n\n// 脚本加载完成后追踪事件\nwatch($script.status, (status) => {\n  if (status === 'loaded') {\n    // 现在可以使用分析功能\n    gtag('event', 'page_view')\n  }\n})\n\u003C/script>",{"id":1331,"title":1332,"titles":1333,"content":1334,"level":320,"path":1331,"to":1331,"label":1332},"/docs/api/use-script-trigger-idle-timeout#渐进增强","渐进增强",[104,1266],"延迟加载增强脚本以优先保证关键资源： \u003Cscript setup lang=\"ts\">\n// 10 秒后加载聊天窗口脚本\nconst chatScript = useScript({\n  src: 'https://widget.intercom.io/widget/abc123'\n}, {\n  trigger: useScriptTriggerIdleTimeout({ timeout: 10000 })\n})\n\n// 5 秒后加载搜索增强脚本\nconst searchScript = useScript({\n  src: 'https://cdn.example.com/search-enhancement.js'\n}, {\n  trigger: useScriptTriggerIdleTimeout({ timeout: 5000 })\n})\n\u003C/script>",{"id":1336,"title":1337,"titles":1338,"content":1339,"level":314,"path":1336,"to":1336,"label":1337},"/docs/api/use-script-trigger-idle-timeout#最佳实践","最佳实践",[104],"使用合适的超时时间：分析脚本建议 3-5 秒，窗口小部件建议 5-10 秒，非必要功能更长时间考虑用户行为：高互动页面使用较短超时，内容为主页面使用较长超时监控性能：确保延迟加载确实改善了核心网页指标（Core Web Vitals）结合其他触发器使用：与交互触发器结合，获得最佳用户体验 html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":109,"title":108,"titles":1341,"content":1342,"level":308,"path":109,"to":109,"label":108},[],"useScriptTriggerInteraction 函数的 API 文档。 创建一个触发器，在任意指定的用户交互事件发生时加载脚本。这非常适合仅在用户真正与您的网站交互时加载脚本，从而提供出色的性能优化。",{"id":1344,"title":1222,"titles":1345,"content":1346,"level":314,"path":1344,"to":1344,"label":1222},"/docs/api/use-script-trigger-interaction#函数签名",[108],"function useScriptTriggerInteraction(options: InteractionScriptTriggerOptions): Promise\u003Cboolean>",{"id":1348,"title":1227,"titles":1349,"content":1350,"level":314,"path":1348,"to":1348,"label":1227},"/docs/api/use-script-trigger-interaction#参数",[108],"export interface InteractionScriptTriggerOptions {\n  /**\n   * 要监听的交互事件。\n   */\n  events: string[]\n  /**\n   * 监听事件的目标元素。\n   * @default document.documentElement\n   */\n  target?: EventTarget | null\n}",{"id":1352,"title":1241,"titles":1353,"content":1354,"level":314,"path":1352,"to":1352,"label":1241},"/docs/api/use-script-trigger-interaction#返回值",[108],"当任意指定的交互事件发生且应加载脚本时，返回一个解析为 true 的 Promise；如果触发器被取消，则解析为 false。",{"id":1356,"title":1357,"titles":1358,"content":1359,"level":314,"path":1356,"to":1356,"label":1357},"/docs/api/use-script-trigger-interaction#在-nuxt-配置中的使用","在 Nuxt 配置中的使用",[108],"为了方便起见，您可以直接在 nuxt.config 中使用此触发器，而无需显式调用组合式函数： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAnalytics: [{\n        id: 'GA_MEASUREMENT_ID'\n      }, {\n        trigger: { interaction: ['scroll', 'click', 'keydown'] }\n      }]\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    globals: {\n      chatWidget: ['https://widget.example.com/chat.js', {\n        trigger: { interaction: ['scroll', 'click', 'touchstart'] }\n      }]\n    }\n  }\n})",{"id":1361,"title":1362,"titles":1363,"content":1364,"level":314,"path":1361,"to":1361,"label":1362},"/docs/api/use-script-trigger-interaction#常见事件类型","常见事件类型",[108],"以下是一些常用的交互事件： 鼠标事件：click、mousedown、mouseup、mouseover、mouseenter、mouseleave触摸事件：touchstart、touchend、touchmove键盘事件：keydown、keyup、keypress滚动事件：scroll、wheel聚焦事件：focus、blur、focusin、focusout",{"id":1366,"title":1266,"titles":1367,"content":330,"level":314,"path":1366,"to":1366,"label":1266},"/docs/api/use-script-trigger-interaction#示例",[108],{"id":1369,"title":1270,"titles":1370,"content":1371,"level":320,"path":1369,"to":1369,"label":1270},"/docs/api/use-script-trigger-interaction#基本用法",[108,1266],"当用户滚动、点击或按键时加载脚本： const script = useScript({\n  src: 'https://example.com/chat-widget.js',\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['scroll', 'click', 'keydown']\n  })\n})",{"id":1373,"title":1374,"titles":1375,"content":1376,"level":320,"path":1373,"to":1373,"label":1374},"/docs/api/use-script-trigger-interaction#首次交互时加载分析脚本","首次交互时加载分析脚本",[108,1266],"仅当用户实际与您的网站交互时加载分析脚本： \u003Cscript setup lang=\"ts\">\n// 在任意用户交互时加载分析脚本\nconst { $script } = useScriptGoogleAnalytics({\n  id: 'GA_MEASUREMENT_ID'\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['click', 'scroll', 'keydown', 'touchstart']\n  })\n})\n\n// 追踪首次交互\nwatch($script.status, (status) => {\n  if (status === 'loaded') {\n    gtag('event', 'first_interaction', {\n      event_category: 'engagement'\n    })\n  }\n})\n\u003C/script>",{"id":1378,"title":1379,"titles":1380,"content":1381,"level":320,"path":1378,"to":1378,"label":1379},"/docs/api/use-script-trigger-interaction#监听特定元素","监听特定元素",[108,1266],"在特定元素上监听事件： \u003Cscript setup lang=\"ts\">\nconst headerEl = ref\u003CHTMLElement>()\n\nconst script = useScript({\n  src: 'https://example.com/header-widget.js'\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['click', 'mouseover'],\n    target: headerEl\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cheader ref=\"headerEl\">\n    \u003C!-- 该脚本在此 header 被点击或悬停时加载 -->\n    \u003Cnav>...\u003C/nav>\n  \u003C/header>\n\u003C/template>",{"id":1383,"title":1384,"titles":1385,"content":1386,"level":320,"path":1383,"to":1383,"label":1384},"/docs/api/use-script-trigger-interaction#渐进式功能加载","渐进式功能加载",[108,1266],"根据不同的交互类型加载功能： \u003Cscript setup lang=\"ts\">\n// 用户进行任意输入交互时加载搜索增强功能\nconst searchScript = useScript({\n  src: 'https://cdn.example.com/search.js'\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['click', 'focus', 'keydown']\n  })\n})\n\n// 用户滚动或点击分享按钮时加载社交分享功能\nconst socialScript = useScript({\n  src: 'https://cdn.example.com/social-sharing.js'\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['scroll', 'click']\n  })\n})\n\u003C/script>",{"id":1388,"title":1389,"titles":1390,"content":1391,"level":320,"path":1388,"to":1388,"label":1389},"/docs/api/use-script-trigger-interaction#移动端优化加载","移动端优化加载",[108,1266],"使用触摸事件实现移动端特性优化加载： \u003Cscript setup lang=\"ts\">\n// 在触摸交互时加载移动端特定功能\nconst mobileScript = useScript({\n  src: 'https://cdn.example.com/mobile-features.js'\n}, {\n  trigger: useScriptTriggerInteraction({\n    events: ['touchstart', 'touchmove', 'scroll']\n  })\n})\n\u003C/script>",{"id":1393,"title":1337,"titles":1394,"content":1395,"level":314,"path":1393,"to":1393,"label":1337},"/docs/api/use-script-trigger-interaction#最佳实践",[108],"从常见事件开始：对大多数用例来说，使用 ['scroll', 'click', 'keydown'] 是不错的默认选择考虑移动用户：包含 touchstart 等触摸事件以优化移动端体验针对特定元素监听：使用 target 选项只监听页面相关部分的事件合理组合事件：避免事件类型过多，专注于有意义的交互测试性能影响：验证基于交互的加载是否真正改善了性能指标回退方案考虑：考虑用户不交互时的情况（例如结合超时触发器） html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":113,"title":112,"titles":1397,"content":1398,"level":308,"path":113,"to":113,"label":112},[],"useScriptEventPage 函数的 API 文档。 访问当前页面的标题和路径，并在它们变化时触发事件。",{"id":1400,"title":1278,"titles":1401,"content":1402,"level":314,"path":1400,"to":1400,"label":1278},"/docs/api/use-script-event-page#签名",[112],"function useScriptEventPage(callback?: (title: string, path: string) => void): Ref\u003C{ title: string, path: string }> {}",{"id":1404,"title":1227,"titles":1405,"content":1406,"level":401,"path":1404,"to":1404,"label":1227},"/docs/api/use-script-event-page#参数",[112,1278],"callback（可选） - 当页面标题或路径发生变化时调用的函数。",{"id":1408,"title":1241,"titles":1409,"content":1410,"level":401,"path":1408,"to":1408,"label":1241},"/docs/api/use-script-event-page#返回值",[112,1278],"一个包含当前页面标题和路径的 ref。",{"id":1412,"title":1266,"titles":1413,"content":1414,"level":314,"path":1412,"to":1412,"label":1266},"/docs/api/use-script-event-page#示例",[112],"在元素可见时加载脚本。 \u003Cscript setup lang=\"ts\">\nuseScriptEventPage((ctx) => {\n  console.log(ctx.title, ctx.path)\n})\n\u003C/script> html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}",{"id":117,"title":116,"titles":1416,"content":1417,"level":308,"path":117,"to":117,"label":116},[],"使用你的 Nuxt 配置配置 Nuxt 脚本。",{"id":1419,"title":1420,"titles":1421,"content":1422,"level":314,"path":1419,"to":1419,"label":1420},"/docs/api/nuxt-config#registry","registry",[116],"类型: ScriptRegistry 应加载的全局注册脚本。 有关更多详细信息，请参阅 脚本注册。",{"id":1424,"title":1425,"titles":1426,"content":1427,"level":314,"path":1424,"to":1424,"label":1425},"/docs/api/nuxt-config#partytown-实验性","partytown 实验性",[116],"类型: (keyof ScriptRegistry)[]默认值: [] 通过 Partytown（Web Worker）加载的注册脚本。 这是为单个注册脚本设置 partytown: true 的简写。当脚本列在此处时，它将以 type=\"text/partytown\" 加载，以便 Partytown 可以在 Web Worker 中执行它。 export default defineNuxtConfig({\n  scripts: {\n    partytown: ['googleAnalytics', 'plausible', 'fathom'],\n    registry: {\n      googleAnalytics: { id: 'G-XXXXX' },\n      plausible: { domain: 'example.com' },\n      fathom: { site: 'XXXXX' }\n    }\n  }\n}) 需要安装 @nuxtjs/partytown 。对于支持的注册脚本，forward 数组会自动配置。",{"id":1429,"title":648,"titles":1430,"content":1431,"level":320,"path":1429,"to":1429,"label":648},"/docs/api/nuxt-config#支持的脚本",[116,1425],"自动转发配置的脚本： googleAnalytics、plausible、fathom、umami、matomo、segmentmetaPixel、xPixel、tiktokPixel、snapchatPixel、redditPixelcloudflareWebAnalytics",{"id":1433,"title":1434,"titles":1435,"content":1436,"level":320,"path":1433,"to":1433,"label":1434},"/docs/api/nuxt-config#限制","限制",[116,1425],"不兼容的脚本 —— 由于需要访问 DOM，以下脚本不能与 Partytown 一起使用：标签管理器：Google Tag Manager、Adobe Launch会话重放：Hotjar、Clarity、FullStory、LogRocket聊天窗口：Intercom、Crisp、Drift、HubSpot Chat视频播放器：YouTube、Vimeo 嵌入A/B 测试：Optimizely、VWO、Google Optimize 通用限制：脚本不能直接访问或修改 DOMdocument.cookie 访问需要附加的 Partytown 配置调试更复杂（代码在 Web Worker 中运行）与主线程执行相比，某些脚本可能存在时序差异localStorage/sessionStorage 访问可能需要转发配置",{"id":1438,"title":1439,"titles":1440,"content":1441,"level":314,"path":1438,"to":1438,"label":1439},"/docs/api/nuxt-config#defaultscriptoptions","defaultScriptOptions",[116],"类型: NuxtUseScriptOptions默认值: { trigger: 'onNuxtReady' } 脚本的默认选项。有关更多详细信息，请参阅 useScript 文档。",{"id":1443,"title":1444,"titles":1445,"content":1446,"level":314,"path":1443,"to":1443,"label":1444},"/docs/api/nuxt-config#globals","globals",[116],"类型: (NuxtUseScriptInput | [NuxtUseScriptInput, NuxtUseScriptOptions])[]默认值: [] 应在所有页面加载的全局脚本。这是针对 useScript 组合式函数的配置。 有关更多详细信息，请参阅 全局 文档。",{"id":1448,"title":1449,"titles":1450,"content":1451,"level":314,"path":1448,"to":1448,"label":1449},"/docs/api/nuxt-config#enabled","enabled",[116],"类型: boolean默认值: true 禁用 Nuxt Scripts 模块。",{"id":1453,"title":1454,"titles":1455,"content":1456,"level":314,"path":1453,"to":1453,"label":1454},"/docs/api/nuxt-config#debug","debug",[116],"类型: boolean默认值: false 启用以查看调试日志。",{"id":1458,"title":1459,"titles":1460,"content":1461,"level":314,"path":1458,"to":1458,"label":1459},"/docs/api/nuxt-config#assets","assets",[116],"类型: object默认值: { prefix: '/_scripts/', strategy: 'public' } 控制脚本打包和由 Nuxt 提供的方式。 有关更多详细信息，请参阅 打包 文档。",{"id":1463,"title":1464,"titles":1465,"content":1466,"level":314,"path":1463,"to":1463,"label":1464},"/docs/api/nuxt-config#assetsfallbackonsrconbundlefail","assets.fallbackOnSrcOnBundleFail",[116],"类型: boolean默认值: false 启用时，当打包失败时回退到远程 src URL。默认情况下，如果第三方脚本无法下载，打包过程将停止。",{"id":1468,"title":1469,"titles":1470,"content":1471,"level":314,"path":1468,"to":1468,"label":1469},"/docs/api/nuxt-config#assetsfetchoptions","assets.fetchOptions",[116],"类型: object默认值: { retry: 3, retryDelay: 2000, timeout: 15_000 } 下载脚本时传递给 fetch 函数的选项。",{"id":1473,"title":1474,"titles":1475,"content":1476,"level":314,"path":1473,"to":1473,"label":1474},"/docs/api/nuxt-config#assetsintegrity","assets.integrity",[116],"类型: boolean | 'sha256' | 'sha384' | 'sha512'默认值: false 启用自动子资源完整性 (SRI) 哈希生成以用于打包的脚本。启用后，会计算每个打包脚本的加密哈希，并注入 integrity 属性以及 crossorigin=\"anonymous\"。 有关更多详细信息，请参阅 打包 - 子资源完整性 文档。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":121,"title":120,"titles":1478,"content":1479,"level":308,"path":121,"to":121,"label":120},[],"使用 Nuxt 应用钩子来扩展 Nuxt 脚本的运行时行为。",{"id":1481,"title":1482,"titles":1483,"content":1484,"level":314,"path":1481,"to":1481,"label":1482},"/docs/api/nuxt-app-hooks#scriptsupdated","scripts:updated",[120],"类型: async (ctx: { scripts: ScriptRegistry }) => HookResult 在脚本状态更新后触发。 此钩子在内部用于开发工具，但你也可以根据需要使用它。 export default defineNuxtPlugin({\n  setup() {\n    useNuxtApp().hooks.hook('scripts:updated', (ctx) => {\n      console.log('Scripts updated', ctx.scripts)\n    })\n  }\n})",{"id":1486,"title":1487,"titles":1488,"content":1489,"level":314,"path":1486,"to":1486,"label":1487},"/docs/api/nuxt-app-hooks#scriptinstance-fn","script:instance-fn",[120],"类型: (ctx: { script: ScriptInstance\u003Cany>, fn: string | symbol, args: any, exists: boolean }) => HookResult 此钩子仅由 Unhead 暴露，在通过代理实例访问属性时触发。 这同样在内部用于开发工具，但你也可以根据需要使用它。 export default defineNuxtPlugin({\n  setup() {\n    const head = injectHead()\n    head.hooks.hook('script:instance-fn', ({ fn, args }) => {\n      console.log('Function called:', ctx)\n    })\n    const { proxy } = useScript()\n    proxy.doSomething() // Function called: doSomething\n  }\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":125,"title":124,"titles":1491,"content":1492,"level":308,"path":125,"to":125,"label":124},[],"使用 Nuxt 钩子来扩展 Nuxt 脚本模块。",{"id":1494,"title":1495,"titles":1496,"content":1497,"level":314,"path":1494,"to":1494,"label":1495},"/docs/api/nuxt-hooks#scriptsregistry","scripts:registry",[124],"类型：async (registry: RegistryScripts) => HookResult 在构建时添加注册表脚本，允许通过 scripts.registry 加载它们，并在可用时进行打包。 此功能旨在供模块使用。 export default defineNuxtModule({\n  setup() {\n    nuxt.hooks.hook('scripts:registry', async (registry) => {\n      registry.push({\n        // 在开发工具中使用\n        label: '我的自定义脚本',\n        logo: `\u003Csvg class=\"w-10 h-10\" xmlns=\"http://www.w3.org/2000/svg\" width=\"28.85\" height=\"32\" viewBox=\"0 0 256 284\">\u003Cpath fill=\"#F9AB00\" d=\"M256.003 247.933a35.224 35.224 0 0 1-39.376 35.161c-18.044-2.67-31.266-18.371-30.826-36.606V36.845C185.365 18.591 198.62 2.881 216.687.24a35.221 35.221 0 0 1 39.316 35.16z\"/>\u003Cpath fill=\"#E37400\" d=\"M35.101 213.193c19.386 0 35.101 15.716 35.101 35.101c0 19.386-15.715 35.101-35.101 35.101S0 267.68 0 248.295c0-19.386 15.715-35.102 35.101-35.102m92.358-106.387c-19.477 1.068-34.59 17.406-34.137 36.908v94.285c0 25.588 11.259 41.122 27.755 44.433a35.161 35.161 0 0 0 42.146-34.56V142.089a35.222 35.222 0 0 0-35.764-35.282\"/>\u003C/svg>`,\n        // 如果脚本支持打包，我们需要定义一个解析器\n        scriptBundling: 'https://cdn.jsdelivr.net/npm/my-custom-script@1.0.0',\n        // 加载脚本的方式，将作为自动导入添加\n        import: {\n          name: 'useScriptMyCustomScript',\n          from: resolve('./runtime/scripts/my-custom-script'),\n        },\n      })\n    })\n  },\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"id":139,"title":138,"titles":1499,"content":1500,"level":308,"path":139,"to":139,"label":138},[],"在您的 Nuxt 应用中使用 Vue 组件展示碳广告。 Carbon Ads 是一种广告服务，提供对网站展示广告的性能友好型方案。 Nuxt Scripts 提供了一个无头（headless）ScriptCarbonAds 组件，用于在您的 Nuxt 应用中嵌入碳广告。",{"id":1502,"title":1503,"titles":1504,"content":1505,"level":314,"path":1502,"to":1502,"label":1503},"/scripts/ads/carbon-ads#scriptcarbonads","ScriptCarbonAds",[138],"ScriptCarbonAds 组件的工作方式与其他 Nuxt Scripts 组件不同，它不依赖于 useScript，而是在组件挂载时简单地将一个 script 标签插入组件的 div 中。 默认情况下，组件使用 CarbonAds 的最佳实践，即在挂载时立即加载。如果您希望在特定事件触发时加载广告，可以使用元素事件触发器。 \u003Ctemplate>\n  \u003CScriptCarbonAds\n    serve=\"...\"\n    placement=\"...\"\n    format=\"...\"\n  />\n\u003C/template>",{"id":1507,"title":1508,"titles":1509,"content":1510,"level":320,"path":1507,"to":1507,"label":1508},"/scripts/ads/carbon-ads#处理广告拦截器","处理广告拦截器",[138,1503],"当 CarbonAds 被拦截时，您可以使用这些插槽来添加备用内容。 \u003Ctemplate>\n  \u003CScriptCarbonAds\n    serve=\"...\"\n    placement=\"...\"\n    format=\"...\"\n  >\n    \u003Ctemplate #error>\n      \u003C!-- 备用广告 -->\n      请关闭广告拦截器支持我们。\n    \u003C/template>\n  \u003C/ScriptCarbonAds>\n\u003C/template>",{"id":1512,"title":1513,"titles":1514,"content":1515,"level":320,"path":1512,"to":1512,"label":1513},"/scripts/ads/carbon-ads#添加用户界面样式","添加用户界面样式",[138,1503],"该组件无头渲染，意味着没有内置样式。如果您想自定义广告外观，可以使用来自 nuxt.com 的示例。 \u003Ctemplate>\n  \u003CScriptCarbonAds\n    class=\"Carbon border border-gray-200 dark:border-gray-800 rounded-lg bg-white dark:bg-white/5\"\n    serve=\"...\"\n    placement=\"...\"\n    format=\"...\"\n  />\n\u003C/template>\n\n\u003Cstyle lang=\"postcss\">\n/* 感谢 nuxt.com */\n.dark .Carbon {\n  min-height: 220px;\n  .carbon-text {\n    @apply text-gray-400;\n\n    &:hover {\n      @apply text-gray-200;\n    }\n  }\n}\n\n.light .Carbon {\n  .carbon-text {\n    @apply text-gray-600;\n\n    &:hover {\n      @apply text-gray-800;\n    }\n  }\n}\n\n.Carbon {\n  @apply p-3 flex flex-col max-w-full;\n\n  @screen sm {\n    @apply max-w-xs;\n  }\n\n  @screen lg {\n    @apply mt-0;\n  }\n\n  #carbonads span {\n    @apply flex flex-col justify-between;\n\n    .carbon-wrap {\n      @apply flex flex-col;\n\n      flex: 1;\n\n      @media (min-width: 320px) {\n        @apply flex-row;\n      }\n\n      @screen lg {\n        @apply flex-col;\n      }\n\n      .carbon-img {\n        @apply flex items-start justify-center mb-4;\n\n        @media (min-width: 320px) {\n          @apply mb-0;\n        }\n\n        @screen lg {\n          @apply mb-4;\n        }\n      }\n\n      .carbon-text {\n        @apply flex-1 text-sm w-full m-0 text-left block;\n\n        &:hover {\n          @apply no-underline;\n        }\n\n        @media (min-width: 320px) {\n          @apply ml-4;\n        }\n\n        @screen lg {\n          @apply ml-0;\n        }\n      }\n    }\n  }\n\n  img {\n    @apply w-full;\n  }\n\n  & .carbon-poweredby {\n    @apply ml-2 text-xs text-right text-gray-400 block pt-2;\n\n    &:hover {\n      @apply no-underline text-gray-500;\n    }\n  }\n}\n\u003C/style>",{"id":1517,"title":1518,"titles":1519,"content":1520,"level":320,"path":1517,"to":1517,"label":1518},"/scripts/ads/carbon-ads#组件-api","组件 API",[138,1503],"完整的 props、事件和插槽请参阅门面组件 API。 注意：Carbon Ads 脚本不扩展 useScript 组合函数。访问该脚本会返回 HTMLScriptElement。",{"id":1522,"title":1039,"titles":1523,"content":1524,"level":320,"path":1522,"to":1522,"label":1039},"/scripts/ads/carbon-ads#props",[138,1503],"ScriptCarbonAds 组件接受以下属性： serve：Carbon Ads 提供的服务 URL。placement：Carbon Ads 提供的广告位 ID。format：Carbon Ads 提供的格式。 html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}",{"id":143,"title":142,"titles":1526,"content":1527,"level":308,"path":143,"to":143,"label":142},[],"在您的 Nuxt 应用中显示 Google Adsense 广告。 Google AdSense 允许您通过展示与内容相关的 Google 广告来实现网站的盈利。 Nuxt Scripts 提供： useScriptGoogleAdsense：用于动态管理 Google AdSense 的组合函数。\u003CScriptGoogleAdsense>：一个无头组件，用于将广告直接嵌入您的 Nuxt 应用。",{"id":1529,"title":1093,"titles":1530,"content":1531,"level":314,"path":1529,"to":1529,"label":1093},"/scripts/ads/google-adsense#全局配置",[142],"您可以在 nuxt.config.ts 中全局配置 Google AdSense，这样脚本将在所有页面自动加载。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAdsense: {\n        client: \"ca-pub-\u003Cyour-id>\", // 您的 Google AdSense 发布者 ID\n        autoAds: true, // 启用自动广告\n      },\n    },\n  },\n});",{"id":1533,"title":1534,"titles":1535,"content":1536,"level":314,"path":1533,"to":1533,"label":1534},"/scripts/ads/google-adsense#如何找到-your-id发布者-id","如何找到 \u003Cyour-id>（发布者 ID）",[142],"您的 Google AdSense 发布者 ID（也称为 ca-pub-XXXXXXX）可以在您的 Google AdSense 账户中找到： 登录您的 Google AdSense 账户。进入 账户 > 设置（点击您的头像图标 > “账户信息”）。在 账户信息 下找到 发布者 ID。将上述配置中的 \u003Cyour-id> 替换为您的实际 ID。 您也可以在 Google AdSense 控制台中管理 自动广告设置，以控制广告类型、广告位置及营收优化。",{"id":1538,"title":1539,"titles":1540,"content":330,"level":314,"path":1538,"to":1538,"label":1539},"/scripts/ads/google-adsense#站点所有权验证","站点所有权验证",[142],{"id":1542,"title":1543,"titles":1544,"content":1545,"level":320,"path":1542,"to":1542,"label":1543},"/scripts/ads/google-adsense#自动插入-meta-标签","自动插入 Meta 标签",[142,1539],"如果提供了 client，页面将自动插入一个用于 Google 验证您站点所有权的 meta 标签。 export default defineNuxtConfig({\n  scripts: {\n      registry: {\n        googleAdsense: {\n          client: \"ca-pub-\u003Cyour-id>\", // AdSense 发布者 ID\n        },\n      },\n  },\n});\n\u003Cmeta name=\"google-adsense-account\" content=\"ca-pub-\u003Cyour-id>\" />",{"id":1547,"title":1548,"titles":1549,"content":1550,"level":320,"path":1547,"to":1547,"label":1548},"/scripts/ads/google-adsense#使用-adstxt-进行验证","使用 ads.txt 进行验证",[142,1539],"Google 建议添加 ads.txt 文件以确保广告收入资格。",{"id":1552,"title":1553,"titles":1554,"content":1555,"level":401,"path":1552,"to":1552,"label":1553},"/scripts/ads/google-adsense#步骤","步骤：",[142,1539,1548],"新建文件：public/ads.txt添加以下内容：\ngoogle.com, pub-\u003Cyour-id>, DIRECT, f08c47fec0942fa0\n将 \u003Cyour-id> 替换为您的 AdSense 发布者 ID。 为什么使用 ads.txt？ 它有助于防止广告欺诈，确保只有您的网站可以展示您的广告。",{"id":1557,"title":1558,"titles":1559,"content":1560,"level":314,"path":1557,"to":1557,"label":1558},"/scripts/ads/google-adsense#启用自动广告","启用自动广告",[142],"自动广告允许 Google 自动投放广告，实现更优的优化。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAdsense: {\n        client: \"ca-pub-\u003Cyour-id>\", // AdSense 发布者 ID\n        autoAds: true, // 启用自动广告\n      },\n    },\n  },\n});\n\u003Cscript>\n(adsbygoogle = window.adsbygoogle || []).push({\n  google_ad_client: \"ca-pub-\u003Cyour-id>\",\n  enable_page_level_ads: true,\n});\n\u003C/script>",{"id":1562,"title":1563,"titles":1564,"content":1565,"level":314,"path":1562,"to":1562,"label":1563},"/scripts/ads/google-adsense#使用-scriptgoogleadsense-组件","使用 ScriptGoogleAdsense 组件",[142],"它提供了一种简单方式，将广告嵌入您的 Nuxt 应用。 \u003Ctemplate>\n  \u003CScriptGoogleAdsense\n    data-ad-client=\"ca-pub-\u003Cyour-id>\"\n    data-ad-slot=\"1234567890\"\n    data-ad-format=\"auto\"\n  />\n\u003C/template>",{"id":1567,"title":1568,"titles":1569,"content":1570,"level":320,"path":1567,"to":1567,"label":1568},"/scripts/ads/google-adsense#组件属性","组件属性",[142,1563],"属性说明data-ad-client您的 Google Adsense 发布者 ID（ca-pub-XXXXXXXXXX）。data-ad-slot您的 广告位 ID（可在 AdSense 控制台获得）。data-ad-format广告格式类型（auto，rectangle，horizontal，vertical，fluid，autorelaxed）。data-ad-layout布局（in-article，in-feed，fixed）。data-full-width-responsive设置为 true 可使广告响应式。",{"id":1572,"title":1573,"titles":1574,"content":1575,"level":401,"path":1572,"to":1572,"label":1573},"/scripts/ads/google-adsense#使用-data-ad-layout-的示例","使用 data-ad-layout 的示例",[142,1563,1568],"若要为广告指定布局（如 “in-article”），可使用 data-ad-layout 属性： \u003Ctemplate>\n  \u003CScriptGoogleAdsense\n    data-ad-client=\"ca-pub-\u003Cyour-id>\"\n    data-ad-slot=\"1234567890\"\n    data-ad-format=\"fluid\"\n    data-ad-layout=\"in-article\"\n  />\n\u003C/template>",{"id":1577,"title":1578,"titles":1579,"content":1580,"level":314,"path":1577,"to":1577,"label":1578},"/scripts/ads/google-adsense#如何处理广告屏蔽程序","如何处理广告屏蔽程序？",[142],"如果用户启用了广告屏蔽程序，您可以显示备用内容。 \u003Ctemplate>\n  \u003CScriptGoogleAdsense data-ad-client=\"ca-pub-...\" data-ad-slot=\"...\">\n    \u003Ctemplate #error>\n      \u003C!-- 备用内容 -->\n      \u003Cp>请支持我们，关闭您的广告屏蔽程序。\u003C/p>\n    \u003C/template>\n  \u003C/ScriptGoogleAdsense>\n\u003C/template>",{"id":1582,"title":1583,"titles":1584,"content":1585,"level":314,"path":1582,"to":1582,"label":1583},"/scripts/ads/google-adsense#使用-usescriptgoogleadsense-组合函数","使用 useScriptGoogleAdsense 组合函数",[142],"useScriptGoogleAdsense 组合函数允许您对 AdSense 脚本进行细粒度控制。 export function useScriptGoogleAdsense\u003CT extends GoogleAdsenseApi>(\n  _options?: GoogleAdsenseInput\n) {} 请参阅 Registry Scripts 指南 获取高级用法。",{"id":1587,"title":1588,"titles":1589,"content":1590,"level":314,"path":1587,"to":1587,"label":1588},"/scripts/ads/google-adsense#googleadsenseapi-接口","GoogleAdsenseApi 接口",[142],"该接口定义了 Google Adsense API 结构，增强 TypeScript 支持。 export interface GoogleAdsenseApi {\n  adsbygoogle: any[] & { loaded: boolean };\n}",{"id":1592,"title":1593,"titles":1594,"content":1595,"level":314,"path":1592,"to":1592,"label":1593},"/scripts/ads/google-adsense#googleadsenseinput","GoogleAdsenseInput",[142],"您可以使用以下结构定义传给 useScriptGoogleAdsense 组合函数的输入选项： export const GoogleAdsenseOptions = object({\n  /**\n   * Google Adsense 发布者 ID。\n   */\n  client: optional(string()),\n  /**\n   * 启用或禁用自动广告。\n   */\n  autoAds: optional(boolean()),\n}); 需要更多帮助？请查看官方 Google AdSense 指南 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .suYPm, html code.shiki .suYPm{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#C3E88D;--shiki-dark-font-style:inherit}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}",{"id":152,"title":151,"titles":1597,"content":1598,"level":308,"path":152,"to":152,"label":151},[],"在你的 Nuxt 应用中使用 Cloudflare Web Analytics。 Cloudflare Web Analytics 与 Nuxt 结合是一个极佳的隐私分析解决方案。它为您的网站提供免费的、以隐私为中心的分析。它不会收集访问者的个人数据，但仍能提供访问者体验中的网页性能详细洞察。 在 Nuxt 应用中全局加载 Cloudflare Web Analytics 最简单的方法是使用 Nuxt 配置。或者你也可以直接使用 useScriptCloudflareWebAnalytics 组合函数。",{"id":1600,"title":1601,"titles":1602,"content":1603,"level":314,"path":1600,"to":1600,"label":1601},"/scripts/analytics/cloudflare-web-analytics#全局加载","全局加载",[151],"如果你想避免在开发环境中加载分析，可以在 Nuxt 配置中使用 环境覆盖。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      cloudflareWebAnalytics: {\n        token: 'YOUR_TOKEN_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        cloudflareWebAnalytics: {\n          token: 'YOUR_TOKEN_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      cloudflareWebAnalytics: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        cloudflareWebAnalytics: {\n          // .env 文件\n          // NUXT_PUBLIC_SCRIPTS_CLOUDFLARE_WEB_ANALYTICS_TOKEN=\u003Cyour-token>\n          token: '', \n        },\n      },\n    },\n  },\n})",{"id":1605,"title":1606,"titles":1607,"content":1608,"level":314,"path":1605,"to":1605,"label":1606},"/scripts/analytics/cloudflare-web-analytics#usescriptcloudflarewebanalytics","useScriptCloudflareWebAnalytics",[151],"useScriptCloudflareWebAnalytics 组合函数让你对 Cloudflare Web Analytics 在网站上的加载时机和方式有更细粒度的控制。 function useScriptCloudflareWebAnalytics\u003CT extends CloudflareWebAnalyticsApi>(_options?: CloudflareWebAnalyticsInput) {} 请参见 Registry Scripts 指南，了解更多高级用法。 该组合函数的默认配置包括： 触发时机：客户端 脚本将在 Nuxt 完成水合时加载，以保持网页核心指标的准确性。",{"id":1610,"title":1611,"titles":1612,"content":1613,"level":320,"path":1610,"to":1610,"label":1611},"/scripts/analytics/cloudflare-web-analytics#cloudflarewebanalyticsinput","CloudflareWebAnalyticsInput",[151,1606],"export const CloudflareWebAnalyticsOptions = object({\n  /**\n   * Cloudflare Web Analytics 令牌。\n   */\n  token: string([minLength(32)]),\n  /**\n   * Cloudflare Web Analytics 通过覆盖 History API 的 pushState 方法并监听 onpopstate 自动测量 SPA。\n   * 不支持基于哈希的路由。\n   *\n   * @default true\n   */\n  spa: optional(boolean()),\n})",{"id":1615,"title":1616,"titles":1617,"content":1618,"level":320,"path":1615,"to":1615,"label":1616},"/scripts/analytics/cloudflare-web-analytics#cloudflarewebanalyticsapi","CloudflareWebAnalyticsApi",[151,1606],"export interface CloudflareWebAnalyticsApi {\n  __cfBeacon: {\n    load: 'single'\n    spa: boolean\n    token: string\n  }\n}",{"id":1620,"title":1266,"titles":1621,"content":1622,"level":314,"path":1620,"to":1620,"label":1266},"/scripts/analytics/cloudflare-web-analytics#示例",[151],"通过 app.vue 在 Nuxt 准备好后加载 Cloudflare Web Analytics。 \u003Cscript setup lang=\"ts\">\nuseScriptCloudflareWebAnalytics({\n  token: '12ee46bf598b45c2868bbc07a3073f58',\n  scriptOptions: {\n    trigger: 'onNuxtReady'\n  }\n})\n\u003C/script> Cloudflare Web Analytics 组合函数会将 window.__cfBeacon 对象注入全局作用域。如果你需要访问它，可以通过等待脚本加载来实现。 const { onLoaded } = useScriptCloudflareWebAnalytics()\nonLoaded(({ cfBeacon }) => {\n  console.log(cfBeacon)\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":156,"title":155,"titles":1624,"content":1625,"level":308,"path":156,"to":156,"label":155},[],"在你的 Nuxt 应用中使用 Databuddy Analytics。 Databuddy 是一个隐私优先的分析平台，专注于性能和最小的数据收集。 使用 registry 可以轻松注入带有合理默认值的 Databuddy CDN 脚本，或者调用组合函数以实现细粒度控制。",{"id":1627,"title":1601,"titles":1628,"content":1629,"level":314,"path":1627,"to":1627,"label":1601},"/scripts/analytics/databuddy-analytics#全局加载",[155],"启用 Databuddy 全局的最简单方法是通过 nuxt.config（或模块配置）。你可以使用环境变量覆盖，仅在生产环境中启用。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      databuddyAnalytics: {\n        clientId: 'YOUR_CLIENT_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        databuddyAnalytics: {\n          clientId: 'YOUR_CLIENT_ID'\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      databuddyAnalytics: true,\n    }\n  },\n  runtimeConfig: {\n    public: {\n      scripts: {\n        databuddyAnalytics: {\n          // .env\n          // NUXT_PUBLIC_SCRIPTS_DATABUDDY_ANALYTICS_CLIENT_ID=\u003Cyour-client-id>\n          clientId: ''\n        },\n      },\n    },\n  },\n})",{"id":1631,"title":1632,"titles":1633,"content":1634,"level":314,"path":1631,"to":1631,"label":1632},"/scripts/analytics/databuddy-analytics#usescriptdatabuddyanalytics","useScriptDatabuddyAnalytics",[155],"useScriptDatabuddyAnalytics 组合函数让你控制何时以及如何加载 Databuddy。 const db = useScriptDatabuddyAnalytics({\n  clientId: 'YOUR_CLIENT_ID',\n  trackWebVitals: true,\n  trackErrors: true,\n  enableBatching: true,\n}) 该组合函数返回脚本代理（如果可用）。你可以通过 db 或者 window.db / window.databuddy 与全局 API 交互。",{"id":1636,"title":1637,"titles":1638,"content":1639,"level":320,"path":1636,"to":1636,"label":1637},"/scripts/analytics/databuddy-analytics#cdn-自托管","CDN / 自托管",[155,1632],"默认情况下，registry 会注入 https://cdn.databuddy.cc/databuddy.js。如果你自行托管脚本，可以通过选项传入 scriptUrl 来覆盖 src。 useScriptDatabuddyAnalytics({\n  scriptInput: { src: 'https://my-host/databuddy.js' },\n  clientId: 'YOUR_CLIENT_ID'\n})",{"id":1641,"title":1642,"titles":1643,"content":1644,"level":320,"path":1641,"to":1641,"label":1642},"/scripts/analytics/databuddy-analytics#databuddyanalyticsapi","DatabuddyAnalyticsApi",[155,1632],"export interface DatabuddyAnalyticsApi {\n  track: (eventName: string, properties?: Record\u003Cstring, any>) => Promise\u003Cany> | any | void\n  screenView: (path?: string, properties?: Record\u003Cstring, any>) => void\n  setGlobalProperties: (properties: Record\u003Cstring, any>) => void\n  trackCustomEvent: (eventName: string, properties?: Record\u003Cstring, any>) => void\n  clear: () => void\n  flush: () => void\n}",{"id":1646,"title":1647,"titles":1648,"content":1649,"level":320,"path":1646,"to":1646,"label":1647},"/scripts/analytics/databuddy-analytics#配置模式","配置模式",[155,1632],"首次配置 registry 时，必须提供 clientId。registry 支持大量传递给脚本的 Databuddy 选项，这些选项通过 data- 属性传递。 export const DatabuddyAnalyticsOptions = object({\n  clientId: string(),\n  scriptUrl: optional(string()),\n  apiUrl: optional(string()),\n  disabled: optional(boolean()),\n  trackScreenViews: optional(boolean()),\n  trackPerformance: optional(boolean()),\n  trackSessions: optional(boolean()),\n  trackWebVitals: optional(boolean()),\n  trackErrors: optional(boolean()),\n  trackOutgoingLinks: optional(boolean()),\n  trackScrollDepth: optional(boolean()),\n  trackEngagement: optional(boolean()),\n  trackInteractions: optional(boolean()),\n  trackAttributes: optional(boolean()),\n  trackHashChanges: optional(boolean()),\n  trackExitIntent: optional(boolean()),\n  trackBounceRate: optional(boolean()),\n  enableBatching: optional(boolean()),\n  batchSize: optional(number()),\n  batchTimeout: optional(number()),\n  enableRetries: optional(boolean()),\n  maxRetries: optional(number()),\n  initialRetryDelay: optional(number()),\n  samplingRate: optional(number()),\n  sdk: optional(string()),\n  sdkVersion: optional(string()),\n  enableObservability: optional(boolean()),\n  observabilityService: optional(string()),\n  observabilityEnvironment: optional(string()),\n  observabilityVersion: optional(string()),\n  enableLogging: optional(boolean()),\n  enableTracing: optional(boolean()),\n  enableErrorTracking: optional(boolean()),\n})",{"id":1651,"title":1266,"titles":1652,"content":1653,"level":314,"path":1651,"to":1651,"label":1266},"/scripts/analytics/databuddy-analytics#示例",[155],"使用组合函数代理跟踪自定义事件（在 SSR / 开发环境中为无操作）： \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptDatabuddyAnalytics({ clientId: 'YOUR_CLIENT_ID' })\n\nfunction sendEvent() {\n  proxy?.track('signup_completed', { plan: 'pro' })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"sendEvent\">发送事件\u003C/button>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":160,"title":159,"titles":1655,"content":1656,"level":308,"path":160,"to":160,"label":159},[],"在你的 Nuxt 应用中使用 Fathom Analytics。 Fathom Analytics 是一款适用于你的 Nuxt 应用的出色隐私分析解决方案。它不会收集访客的个人数据，却能提供详细的站点使用情况洞察。",{"id":1658,"title":1601,"titles":1659,"content":1660,"level":314,"path":1658,"to":1658,"label":1601},"/scripts/analytics/fathom-analytics#全局加载",[159],"在你的 Nuxt 应用中全局加载 Fathom Analytics 最简单的方法是使用 Nuxt 配置，提供你的站点 ID 字符串。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      fathomAnalytics: {\n        site: 'YOUR_TOKEN_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        fathomAnalytics: {\n          site: 'YOUR_SITE_ID'\n        }\n      }\n    }\n  },\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      fathomAnalytics: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        fathomAnalytics: {\n          // .env\n          // NUXT_PUBLIC_SCRIPTS_FATHOM_ANALYTICS_SITE=\u003Cyour-token>\n          token: '',\n        },\n      },\n    },\n  },\n})",{"id":1662,"title":1663,"titles":1664,"content":1665,"level":314,"path":1662,"to":1662,"label":1663},"/scripts/analytics/fathom-analytics#组合函数-usescriptfathomanalytics","组合函数 useScriptFathomAnalytics",[159],"useScriptFathomAnalytics 组合函数让你可以细粒度地控制 Fathom Analytics 在你站点上的加载时机和方式。 useScriptFathomAnalytics(options)",{"id":1667,"title":1668,"titles":1669,"content":1670,"level":314,"path":1667,"to":1667,"label":1668},"/scripts/analytics/fathom-analytics#默认值","默认值",[159],"触发时机：脚本将在 Nuxt 被水合（hydrated）时加载。",{"id":1672,"title":1673,"titles":1674,"content":1675,"level":314,"path":1672,"to":1672,"label":1673},"/scripts/analytics/fathom-analytics#选项","选项",[159],"export const FathomAnalyticsOptions = object({\n  /**\n   * Fathom Analytics 的站点 ID。\n   */\n  site: string(),\n  /**\n   * Fathom Analytics 的跟踪模式。\n   */\n  spa: optional(union([literal('auto'), literal('history'), literal('hash')])),\n  /**\n   * 是否自动跟踪页面浏览。\n   */\n  auto: optional(boolean()),\n  /**\n   * 启用规范 URL 跟踪。\n   */\n  canonical: optional(boolean()),\n  /**\n   * 遵守“请勿追踪”请求。\n   */\n  honorDnt: optional(boolean()),\n}) 此外，和所有注册脚本一样，你可以提供额外配置： scriptInput - 要添加到 script 标签的 HTML 属性。scriptOptions - 详见 Script Options。不支持打包，bundle: true 不会生效。",{"id":1677,"title":1241,"titles":1678,"content":1679,"level":314,"path":1677,"to":1677,"label":1241},"/scripts/analytics/fathom-analytics#返回值",[159],"Fathom Analytics 组合函数会向全局范围注入一个 window.fathom 对象。 export interface FathomAnalyticsApi {\n  beacon: (ctx: { url: string, referrer?: string }) => void\n  blockTrackingForMe: () => void\n  enableTrackingForMe: () => void\n  isTrackingEnabled: () => boolean\n  send: (type: string, data: unknown) => void\n  setSite: (siteId: string) => void\n  sideId: string\n  trackPageview: (ctx?: { url: string, referrer?: string }) => void\n  trackGoal: (goalId: string, cents: number) => void\n  trackEvent: (eventName: string, value: { _value: number }) => void\n} 你可以直接通过代理访问 fathom 对象，或者等待 $script Promise 以访问该对象。建议对于无返回值的函数使用代理。 const { proxy } = useScriptFathomAnalytics()\nfunction trackMyGoal() {\n  proxy.trackGoal('MY_GOAL_ID', 100)\n}\nconst { onLoaded } = useScriptFathomAnalytics()\nonLoaded(({ trackGoal }) => {\n  trackGoal('MY_GOAL_ID', 100)\n})",{"id":1681,"title":1266,"titles":1682,"content":1683,"level":314,"path":1681,"to":1681,"label":1266},"/scripts/analytics/fathom-analytics#示例",[159],"通过 app.vue 在 Nuxt 准备好时加载 Fathom Analytics。 \u003Cscript setup>\nuseScriptFathomAnalytics({\n  site: 'YOUR_SITE_ID',\n  scriptOptions: {\n    trigger: 'onNuxtReady'\n  }\n})\n\u003C/script> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":164,"title":163,"titles":1685,"content":1686,"level":308,"path":164,"to":164,"label":163},[],"在你的 Nuxt 应用中使用 Google Analytics。 Google Analytics 是 Nuxt 应用的分析解决方案。 它提供了详细的洞察，让你了解网站的性能、用户如何与内容互动以及用户如何导航你的网站。 在 Nuxt 应用中全局加载 Google Analytics 最简单的方式是通过 Nuxt 配置。或者你也可以直接使用 useScriptGoogleAnalytics 组合函数。",{"id":1688,"title":1601,"titles":1689,"content":1690,"level":320,"path":1688,"to":1688,"label":1601},"/scripts/analytics/google-analytics#全局加载",[163],"如果你不打算发送自定义事件，可以使用 环境变量覆盖 来在开发环境禁用脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAnalytics: {\n        id: 'YOUR_ID',\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        googleAnalytics: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleAnalytics: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        googleAnalytics: {\n          // .env 文件\n          // NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID=\u003Cyour-id>\n          id: '',\n        },\n      },\n    },\n  },\n})",{"id":1692,"title":1693,"titles":1694,"content":1695,"level":314,"path":1692,"to":1692,"label":1693},"/scripts/analytics/google-analytics#usescriptgoogleanalytics","useScriptGoogleAnalytics",[163],"useScriptGoogleAnalytics 组合函数让你可以细粒度控制 Google Analytics 在网站上的加载时机和方式。 const googleAnalytics = useScriptGoogleAnalytics({\n  id: 'YOUR_ID'\n})\n// 1. 设置 .env 中的 NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID=\u003Cyour-id>\n// 2. 将 runtimeConfig.public.scripts.googleAnalytics.id 设为空字符串或回退值\nconst googleAnalytics = useScriptGoogleAnalytics() 请参阅注册脚本指南，了解更多高级用法。",{"id":1697,"title":500,"titles":1698,"content":1699,"level":320,"path":1697,"to":1697,"label":500},"/scripts/analytics/google-analytics#使用",[163,1693],"与 Google Analytics API 交互，推荐使用脚本的代理。 const { proxy } = useScriptGoogleAnalytics()\n\nproxy.gtag('event', 'page_view') 代理对象暴露了 gtag 和 dataLayer 属性，应遵循 Google Analytics 的最佳实践使用它们。",{"id":1701,"title":1702,"titles":1703,"content":1704,"level":320,"path":1701,"to":1701,"label":1702},"/scripts/analytics/google-analytics#googleanalyticsapi","GoogleAnalyticsApi",[163,1693],"export interface GTag {\n  // 使用时间戳初始化 gtag.js\n  (command: 'js', value: Date): void\n\n  // 配置一个 GA4 属性\n  (command: 'config', targetId: string, configParams?: ConfigParams): void\n\n  // 从 gtag 获取值\n  (command: 'get', targetId: string, fieldName: string, callback?: (field: any) => void): void\n\n  // 向 GA4 发送事件\n  (command: 'event', eventName: DefaultEventName, eventParams?: EventParameters): void\n\n  // 为所有后续事件设置默认参数\n  (command: 'set', params: GtagCustomParams): void\n\n  // 更新同意状态\n  (command: 'consent', consentArg: 'default' | 'update', consentParams: ConsentOptions): void\n}\n\ninterface GoogleAnalyticsApi {\n  dataLayer: Record\u003Cstring, any>[]\n  gtag: GTag\n}",{"id":1706,"title":1707,"titles":1708,"content":1709,"level":320,"path":1706,"to":1706,"label":1707},"/scripts/analytics/google-analytics#配置-schema","配置 Schema",[163,1693],"首次设置脚本时必须提供选项。 export const GoogleAnalyticsOptions = object({\n  /**\n   * Google Analytics ID。可选 - 允许加载 gtag.js 但不做初始配置。\n   */\n  id: optional(string()),\n  /**\n   * 你希望关联的数据层（datalayer）的名称\n   */\n  l: optional(string())\n})",{"id":1711,"title":1712,"titles":1713,"content":1714,"level":320,"path":1711,"to":1711,"label":1712},"/scripts/analytics/google-analytics#客户用户-id-追踪","客户/用户 ID 追踪",[163,1693],"对于需要同时追踪客户特定分析的电子商务或多租户应用： \u003Cscript setup lang=\"ts\">\n// 带有客户特定追踪的产品页面\nconst route = useRoute()\nconst pageData = await $fetch(`/api/product/${route.params.id}`)\n\n// 以自定义 dataLayer 名加载 gtag 以进行客户追踪\nconst { proxy: customerGtag, load } = useScriptGoogleAnalytics({\n  key: 'gtag-customer',\n  l: 'customerDataLayer', // 自定义 dataLayer 名称\n})\n\n// 当可用时配置客户的追踪 ID\nconst consumerGtagId = computed(() => pageData?.gtag)\n\nif (consumerGtagId.value) {\n  // 配置客户的 GA4 属性\n  customerGtag.gtag('config', consumerGtagId.value)\n\n  // 发送客户特定事件\n  customerGtag.gtag('event', 'product_view', {\n    item_id: pageData.id,\n    customer_id: pageData.customerId,\n    value: pageData.price\n  })\n}\n\u003C/script>",{"id":1716,"title":1717,"titles":1718,"content":1719,"level":314,"path":1716,"to":1716,"label":1717},"/scripts/analytics/google-analytics#first-party-模式","First-Party 模式",[163],"该脚本支持第一方模式，通过你的域名路由所有流量以提升隐私并绕过广告拦截。 当通过 scripts.firstParty: true 全局启用时，该脚本将会： 从你的域名加载资源，而非第三方服务器通过你的服务器路由收集请求（/g/collect）匿名化 IP 地址、语言和硬件指纹（canvas、webgl、浏览器版本）保留用户代理、屏幕分辨率和时区以确保设备、操作系统和时间基础报告的准确性 export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      googleAnalytics: { id: 'G-XXXXXX' }\n    }\n  }\n}) 若想为此脚本单独关闭： useScriptGoogleAnalytics({\n  id: 'G-XXXXXX',\n  scriptOptions: {\n    firstParty: false // 直接从 Google 加载\n  }\n})",{"id":1721,"title":1266,"titles":1722,"content":1723,"level":314,"path":1721,"to":1721,"label":1266},"/scripts/analytics/google-analytics#示例",[163],"仅在生产环境使用 Google Analytics，同时用 gtag 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptGoogleAnalytics()\n\n// 开发环境及 SSR 中为无操作\n// 仅生产环境和客户端生效\nproxy.gtag('event', 'conversion-test')\nfunction sendConversion() {\n  proxy.gtag('event', 'conversion')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化\n    \u003C/button>\n  \u003C/div>\n\u003C/template>",{"id":1725,"title":1726,"titles":1727,"content":1728,"level":314,"path":1725,"to":1725,"label":1726},"/scripts/analytics/google-analytics#自定义维度和用户属性","自定义维度和用户属性",[163],"const { proxy } = useScriptGoogleAnalytics()\n\n// 用户属性（跨会话持久化）\nproxy.gtag('set', 'user_properties', {\n  user_tier: 'premium',\n  account_type: 'business'\n})\n\n// 带自定义维度的事件（在 GA4 管理 > 自定义定义中注册）\nproxy.gtag('event', 'purchase', {\n  transaction_id: 'T12345',\n  value: 99.99,\n  payment_method: 'credit_card',  // 自定义维度\n  discount_code: 'SAVE10'         // 自定义维度\n})\n\n// 以后所有事件的默认参数\nproxy.gtag('set', { country: 'US', currency: 'USD' })",{"id":1730,"title":1731,"titles":1732,"content":1733,"level":314,"path":1730,"to":1730,"label":1731},"/scripts/analytics/google-analytics#手动页面浏览追踪spa","手动页面浏览追踪（SPA）",[163],"GA4 默认自动追踪页面浏览。若想禁用并手动追踪： const { proxy } = useScriptGoogleAnalytics()\n\n// 禁用自动页面浏览\nproxy.gtag('config', 'G-XXXXXXXX', { send_page_view: false })\n\n// 路由切换时手动追踪\nconst router = useRouter()\nrouter.afterEach((to) => {\n  proxy.gtag('event', 'page_view', { page_path: to.fullPath })\n})",{"id":1735,"title":1736,"titles":1737,"content":1738,"level":314,"path":1735,"to":1735,"label":1736},"/scripts/analytics/google-analytics#代理排队","代理排队",[163],"代理会在脚本加载前排队所有的 gtag 调用。调用可在服务端渲染时安全使用，抗广告拦截且保持顺序。 const { proxy, onLoaded } = useScriptGoogleAnalytics()\n\n// 立即调用（排队等待 GA 加载）\nproxy.gtag('event', 'cta_click', { button_id: 'hero-signup' })\n\n// 需要返回值时等待加载完成\nonLoaded(({ gtag }) => {\n  gtag('get', 'G-XXXXXXXX', 'client_id', (id) => console.log(id))\n})",{"id":1740,"title":1741,"titles":1742,"content":1743,"level":314,"path":1740,"to":1740,"label":1741},"/scripts/analytics/google-analytics#常用事件模式","常用事件模式",[163],"const { proxy } = useScriptGoogleAnalytics()\n\n// 电子商务\nproxy.gtag('event', 'purchase', {\n  transaction_id: 'T_12345',\n  value: 59.98,\n  currency: 'USD',\n  items: [{ item_id: 'SKU_12345', item_name: 'Widget', price: 29.99, quantity: 2 }]\n})\n\n// 交互事件\nproxy.gtag('event', 'login', { method: 'Google' })\nproxy.gtag('event', 'search', { search_term: 'nuxt scripts' })\n\n// 自定义事件\nproxy.gtag('event', 'feature_used', { feature_name: 'dark_mode' })",{"id":1745,"title":1746,"titles":1747,"content":1748,"level":314,"path":1745,"to":1745,"label":1746},"/scripts/analytics/google-analytics#调试","调试",[163],"通过配置或 URL 参数 ?debug_mode=true 启用调试模式： proxy.gtag('config', 'G-XXXXXXXX', { debug_mode: true }) 在 GA4 查看事件：管理员 > 调试视图。安装 GA 调试器插件 以便控制台日志。 有关同意模式设置，请参阅同意指南。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}",{"id":168,"title":167,"titles":1750,"content":1751,"level":308,"path":168,"to":168,"label":167},[],"在你的 Nuxt 应用中使用 Matomo 分析。 Matomo 分析 是一个适合 Nuxt 应用的优秀分析解决方案。 它可以提供关于你的网站表现、用户如何与你的内容互动以及他们如何在你的网站中导航的详细洞察。 在你的 Nuxt 应用中，全局加载 Matomo 分析最简单的方法是使用 Nuxt 配置。或者你也可以直接使用 useScriptMatomoAnalytics 组合式函数。",{"id":1753,"title":1601,"titles":1754,"content":1755,"level":314,"path":1753,"to":1753,"label":1601},"/scripts/analytics/matomo-analytics#全局加载",[167],"下面的配置假设你正在使用默认 siteId 为 1 的 Matomo 云版本。页面浏览量默认会在导航时自动跟踪。 如果你自托管，你需要提供 matomoUrl。如果你还有其他需要跟踪的网站，可以通过 siteId 添加。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      matomoAnalytics: {\n        cloudId: 'YOUR_CLOUD_ID', // 例如 nuxt.matomo.cloud\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        matomoAnalytics: {\n          cloudId: 'YOUR_CLOUD_ID', // 例如 nuxt.matomo.cloud\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      matomoAnalytics: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        matomoAnalytics: {\n          // .env\n          // NUXT_PUBLIC_SCRIPTS_MATOMO_ANALYTICS_CLOUD_ID=\u003Cyour-id>\n          cloudId: '', // NUXT_PUBLIC_SCRIPTS_MATOMO_ANALYTICS_CLOUD_ID\n        },\n      },\n    },\n  },\n})",{"id":1757,"title":1758,"titles":1759,"content":1760,"level":314,"path":1757,"to":1757,"label":1758},"/scripts/analytics/matomo-analytics#usescriptmatomoanalytics","useScriptMatomoAnalytics",[167],"useScriptMatomoAnalytics 组合式函数让你可以精细控制 Matomo 分析在你的网站何时以及如何加载。 const matomoAnalytics = useScriptMatomoAnalytics({\n  cloudId: 'YOUR_CLOUD_ID', // 例如 nuxt.matomo.cloud\n}) 默认情况下，使用 siteId 为 1，且通过 watch 选项自动启用页面跟踪。 const matomoAnalytics = useScriptMatomoAnalytics({\n  cloudId: 'YOUR_CLOUD_ID', // 例如 nuxt.matomo.cloud\n  siteId: 2,\n  // watch: true, // 默认启用 - 自动页面跟踪！\n}) 如果你想更灵活地控制跟踪，例如设置自定义维度，可以用 proxy 对象发送事件。 const { proxy } = useScriptMatomoAnalytics({\n  cloudId: 'YOUR_CLOUD_ID', // 例如 nuxt.matomo.cloud\n})\n\n// 设置自定义维度\nproxy._paq.push(['setCustomDimension', 1, 'value'])\n// 发送页面事件\nproxy._paq.push(['trackPageView']) 请参阅 配置 Schema 获取所有可用选项。",{"id":1762,"title":1763,"titles":1764,"content":1765,"level":314,"path":1762,"to":1762,"label":1763},"/scripts/analytics/matomo-analytics#自定义页面跟踪","自定义页面跟踪",[167],"默认情况下，所有页面都会自动跟踪，若你想禁用自动跟踪，可设置 watch: false。 import { useScriptEventPage } from '#nuxt-scripts'\n\nconst { proxy } = useScriptMatomoAnalytics({\n  cloudId: 'YOUR_CLOUD_ID',\n  watch: false, // 禁用自动跟踪\n})\n\n// 结合额外逻辑的自定义页面跟踪\nuseScriptEventPage((payload) => {\n  // 根据路由设置自定义维度\n  if (payload.path.startsWith('/products')) {\n    proxy._paq.push(['setCustomDimension', 1, '产品页面'])\n  }\n\n  // 标准的 Matomo 跟踪调用（与内置的 watch 行为相同）\n  proxy._paq.push(['setDocumentTitle', payload.title])\n  proxy._paq.push(['setCustomUrl', payload.path])\n  proxy._paq.push(['trackPageView'])\n\n  // 跟踪额外的自定义事件\n  proxy._paq.push(['trackEvent', 'Navigation', 'PageView', payload.path])\n})",{"id":1767,"title":1768,"titles":1769,"content":1770,"level":320,"path":1767,"to":1767,"label":1768},"/scripts/analytics/matomo-analytics#使用自托管-matomo","使用自托管 Matomo",[167,1763],"对于自托管 Matomo，设置 matomoUrl 来自定义跟踪，如果你自定义了地址，可能还需要设置 trackerUrl。 const matomoAnalytics = useScriptMatomoAnalytics({\n  // 例如 https://your-url.com/tracker.js 和 https://your-url.com//matomo.php 都存在\n  matomoUrl: 'https://your-url.com',\n})",{"id":1772,"title":1773,"titles":1774,"content":1775,"level":320,"path":1772,"to":1772,"label":1773},"/scripts/analytics/matomo-analytics#使用-matomo-白标版本","使用 Matomo 白标版本",[167,1763],"对于 Matomo 白标版本，需要通过设置 trackerUrl 和 scriptInput.src 来自定义跟踪。 const matomoAnalytics = useScriptMatomoAnalytics({\n  trackerUrl: 'https://c.staging.cookie3.co/lake',\n  scriptInput: {\n    src: 'https://cdn.cookie3.co/scripts/analytics/latest/cookie3.analytics.min.js',\n  },\n}) 请参考 Registry Scripts 指南了解更多高级用法。",{"id":1777,"title":1778,"titles":1779,"content":1780,"level":320,"path":1777,"to":1777,"label":1778},"/scripts/analytics/matomo-analytics#matomoanalyticsapi","MatomoAnalyticsApi",[167,1763],"interface MatomoAnalyticsApi {\n  _paq: unknown[]\n}",{"id":1782,"title":1707,"titles":1783,"content":1784,"level":320,"path":1782,"to":1782,"label":1707},"/scripts/analytics/matomo-analytics#配置-schema",[167,1763],"首次设置脚本时必须提供如下选项。 // matomoUrl 和 siteId 是必需的\nexport const MatomoAnalyticsOptions = object({\n  matomoUrl: optional(string()),\n  siteId: optional(union([string(), number()])),\n  cloudId: optional(string()),\n  trackerUrl: optional(string()),\n  trackPageView: optional(boolean()), // 已废弃 - 请改用 watch\n  enableLinkTracking: optional(boolean()),\n  disableCookies: optional(boolean()),\n  watch: optional(boolean()), // 默认：true\n})",{"id":1786,"title":1266,"titles":1787,"content":1788,"level":314,"path":1786,"to":1786,"label":1266},"/scripts/analytics/matomo-analytics#示例",[167],"仅在生产环境中使用 Matomo 分析，并通过 _paq 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptMatomoAnalytics()\n\n// 开发环境和 SSR 不起作用\n// 仅在生产客户端生效\nfunction sendConversion() {\n  proxy._paq.push(['trackGoal', 1])\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":172,"title":171,"titles":1790,"content":1791,"level":308,"path":172,"to":172,"label":171},[],"在您的 Nuxt 应用中使用 Plausible Analytics。 Plausible Analytics 是一个注重隐私保护的 Nuxt 应用分析解决方案，允许您在不侵犯用户隐私的情况下跟踪网站流量。 在 Nuxt 应用中全局加载 Plausible Analytics 的最简单方式是使用 Nuxt 配置。或者，您也可以直接使用 useScriptPlausibleAnalytics 组合函数。",{"id":1793,"title":1601,"titles":1794,"content":1795,"level":314,"path":1793,"to":1793,"label":1601},"/scripts/analytics/plausible-analytics#全局加载",[171],"如果您不打算发送自定义事件，可以使用 环境覆盖 在开发环境中禁用脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      plausibleAnalytics: {\n        // 从您的 Plausible 脚本 URL 获取：\n        // https://plausible.io/js/pa-gYyxvZhkMzdzXBAtSeSNz.js\n        //                         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n        scriptId: 'gYyxvZhkMzdzXBAtSeSNz'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        plausibleAnalytics: {\n          scriptId: 'YOUR_SCRIPT_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      plausibleAnalytics: true,\n    }\n  },\n  // 需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        plausibleAnalytics: {\n          // .env\n          // NUXT_PUBLIC_SCRIPTS_PLAUSIBLE_ANALYTICS_SCRIPT_ID=\u003Cyour-script-id>\n          scriptId: ''\n        },\n      },\n    },\n  },\n})",{"id":1797,"title":1798,"titles":1799,"content":1800,"level":314,"path":1797,"to":1797,"label":1798},"/scripts/analytics/plausible-analytics#usescriptplausibleanalytics","useScriptPlausibleAnalytics",[171],"useScriptPlausibleAnalytics 组合函数让您可以精细控制 Plausible Analytics 在网站上的加载时机和方式。 // 2025年10月更新格式\nconst plausible = useScriptPlausibleAnalytics({\n  // 从：https://plausible.io/js/pa-gYyxvZhkMzdzXBAtSeSNz.js 提取\n  //                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^\n  scriptId: 'gYyxvZhkMzdzXBAtSeSNz'\n}) 请参阅 Registry Scripts 指南以了解更多高级用法。",{"id":1802,"title":1803,"titles":1804,"content":1805,"level":320,"path":1802,"to":1802,"label":1803},"/scripts/analytics/plausible-analytics#自托管-plausible","自托管 Plausible",[171,1798],"如果您使用自托管版本的 Plausible，需要提供脚本的明确 src 以确保事件 API 发送到正确的端点。 useScriptPlausibleAnalytics({\n  scriptInput: {\n    src: 'https://my-self-hosted-plausible.io/js/script.js'\n  }\n})",{"id":1807,"title":1808,"titles":1809,"content":1810,"level":320,"path":1807,"to":1807,"label":1808},"/scripts/analytics/plausible-analytics#plausibleanalyticsapi","PlausibleAnalyticsApi",[171,1798],"export interface PlausibleAnalyticsApi {\n  plausible: ((event: '404', options: Record\u003Cstring, any>) => void) &\n  ((event: 'event', options: Record\u003Cstring, any>) => void) &\n  ((...params: any[]) => void) & {\n    q: any[]\n  }\n}",{"id":1812,"title":1813,"titles":1814,"content":1815,"level":320,"path":1812,"to":1812,"label":1813},"/scripts/analytics/plausible-analytics#配置方案","配置方案",[171,1798],"首次设置脚本时必须提供选项。 export interface PlausibleAnalyticsOptions {\n  /**\n   * 您网站的唯一脚本 ID（推荐 - 2025年10月新格式）\n   * 从：\u003Cscript src=\"https://plausible.io/js/pa-{scriptId}.js\">\u003C/script> 提取\n   */\n  scriptId?: string\n  /** 每个页面浏览都要跟踪的自定义属性 */\n  customProperties?: Record\u003Cstring, any>\n  /** 自定义跟踪端点 URL */\n  endpoint?: string\n  /** 配置文件下载跟踪 */\n  fileDownloads?: {\n    fileExtensions?: string[]\n  }\n  /** 为单页应用启用基于哈希的路由 */\n  hashBasedRouting?: boolean\n  /** 设置为 false 时需手动触发页面浏览事件 */\n  autoCapturePageviews?: boolean\n  /** 启用本地主机跟踪 */\n  captureOnLocalhost?: boolean\n  /** 启用表单提交跟踪 */\n  trackForms?: boolean\n} export interface PlausibleAnalyticsDeprecatedOptions {\n  /**\n   * 您的网站域名\n   * @deprecated 请使用 `scriptId`（2025年10月新格式）代替\n   */\n  domain?: string\n  /**\n   * 用于额外功能的脚本扩展\n   * @deprecated 请改用如 `hashBasedRouting`、`captureOnLocalhost` 等初始化选项\n   */\n  extension?: 'hash' | 'outbound-links' | 'file-downloads' | 'tagged-events' | 'revenue' | 'pageview-props' | 'compat' | 'local' | 'manual'\n} 注意： scriptId 可以在您的 Plausible 仪表盘中，网站设置的 网站安装 部分找到。 提取您的 Script ID： Plausible 提供给您的脚本标签如下： \u003Cscript async src=\"https://plausible.io/js/pa-gYyxvZhkMzdzXBAtSeSNz.js\">\u003C/script> 您的 scriptId 是 pa- 和 .js 之间的部分： scriptId: 'gYyxvZhkMzdzXBAtSeSNz'\n//         ^^^^^^^^^^^^^^^^^^^^^^^\n//         从 pa-{scriptId}.js 中提取",{"id":1817,"title":1266,"titles":1818,"content":1819,"level":314,"path":1817,"to":1817,"label":1266},"/scripts/analytics/plausible-analytics#示例",[171],"只在生产环境使用 Plausible Analytics，同时使用 plausible 发送转换事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptPlausibleAnalytics()\n\n// 开发和服务端渲染时无操作\n// 生产客户端时正常工作\nproxy.plausible('event', { name: 'conversion-step' })\nfunction sendConversion() {\n  proxy.plausible('event', { name: 'conversion' })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转换事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":176,"title":175,"titles":1821,"content":1822,"level":308,"path":176,"to":176,"label":175},[],"在你的 Nuxt 应用中使用 PostHog。 PostHog 是一个开源的产品分析平台，提供分析、会话回放、功能标记、A/B 测试等功能。 Nuxt Scripts 提供了一个注册脚本组合函数 useScriptPostHog，可以轻松地在你的 Nuxt 应用中集成 PostHog。",{"id":1824,"title":16,"titles":1825,"content":1826,"level":314,"path":1824,"to":1824,"label":16},"/scripts/analytics/posthog#安装",[175],"你需要安装 posthog-js 依赖： pnpm add posthog-js",{"id":1828,"title":1829,"titles":1830,"content":1831,"level":320,"path":1828,"to":1828,"label":1829},"/scripts/analytics/posthog#nuxt-配置设置","Nuxt 配置设置",[175,16],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      posthog: {\n        apiKey: 'YOUR_API_KEY'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        posthog: {\n          apiKey: 'YOUR_API_KEY'\n        }\n      }\n    }\n  }\n})",{"id":1833,"title":1834,"titles":1835,"content":1836,"level":401,"path":1833,"to":1833,"label":1834},"/scripts/analytics/posthog#使用环境变量","使用环境变量",[175,16,1829],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      posthog: true,\n    }\n  },\n  runtimeConfig: {\n    public: {\n      scripts: {\n        posthog: {\n          apiKey: '', // NUXT_PUBLIC_SCRIPTS_POSTHOG_API_KEY\n        },\n      },\n    },\n  },\n})",{"id":1838,"title":1839,"titles":1840,"content":1841,"level":314,"path":1838,"to":1838,"label":1839},"/scripts/analytics/posthog#usescriptposthog","useScriptPostHog",[175],"const { proxy } = useScriptPostHog({\n  apiKey: 'YOUR_API_KEY'\n})\n\n// 捕获事件\nproxy.posthog.capture('button_clicked', {\n  button_name: 'signup'\n}) 请参阅 注册脚本 指南，了解更多高级用法。",{"id":1843,"title":1844,"titles":1845,"content":1846,"level":320,"path":1843,"to":1843,"label":1844},"/scripts/analytics/posthog#posthogapi","PostHogApi",[175,1839],"import type { PostHog } from 'posthog-js'\n\nexport interface PostHogApi {\n  posthog: PostHog\n}",{"id":1848,"title":1647,"titles":1849,"content":1850,"level":320,"path":1848,"to":1848,"label":1647},"/scripts/analytics/posthog#配置模式",[175,1839],"export const PostHogOptions = object({\n  apiKey: string(),\n  region: optional(union([literal('us'), literal('eu')])),\n  apiHost: optional(string()), // 自定义 API 主机 URL（例如用于反向代理的 '/ph'）\n  autocapture: optional(boolean()),\n  capturePageview: optional(boolean()),\n  capturePageleave: optional(boolean()),\n  disableSessionRecording: optional(boolean()),\n  config: optional(record(string(), any())), // 完整的 PostHogConfig 透传\n})",{"id":1852,"title":1266,"titles":1853,"content":1854,"level":314,"path":1852,"to":1852,"label":1266},"/scripts/analytics/posthog#示例",[175],"使用 PostHog 跟踪注册事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptPostHog()\n\nfunction onSignup(email: string) {\n  proxy.posthog.identify(email, {\n    email,\n    signup_date: new Date().toISOString()\n  })\n  proxy.posthog.capture('user_signed_up')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"onSignup(email)\">\n    \u003Cinput v-model=\"email\" type=\"email\" />\n    \u003Cbutton type=\"submit\">注册\u003C/button>\n  \u003C/form>\n\u003C/template>",{"id":1856,"title":1857,"titles":1858,"content":1859,"level":314,"path":1856,"to":1856,"label":1857},"/scripts/analytics/posthog#欧盟托管","欧盟托管",[175],"使用 PostHog 的欧盟云： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      posthog: {\n        apiKey: 'YOUR_API_KEY',\n        region: 'eu'\n      }\n    }\n  }\n})",{"id":1861,"title":1862,"titles":1863,"content":1864,"level":314,"path":1861,"to":1861,"label":1862},"/scripts/analytics/posthog#首方代理","首方代理",[175],"当启用首方模式时，PostHog 请求会自动通过你自己的服务器代理转发。这通过绕过广告拦截器，提高了事件捕获的可靠性。不会应用隐私匿名处理——PostHog 是一个受信任的开源工具，需完整数据以进行 GeoIP 丰富化、功能标记和会话回放。 无需额外配置——该模块会自动将 apiHost 设置为通过你服务器的代理端点路由： export default defineNuxtConfig({\n  scripts: {\n    firstParty: true, // 默认为启用\n    registry: {\n      posthog: {\n        apiKey: 'YOUR_API_KEY',\n        // apiHost 会自动设置为 '/_proxy/ph'（或针对欧盟区域为 '/_proxy/ph-eu'）\n      }\n    }\n  }\n}) 代理会处理 API 请求和静态资源（如会话录制 SDK），路由到正确的 PostHog 端点。",{"id":1866,"title":1867,"titles":1868,"content":1869,"level":314,"path":1866,"to":1866,"label":1867},"/scripts/analytics/posthog#自定义-api-主机","自定义 API 主机",[175],"如需使用自定义的反向代理或自托管的 PostHog 实例，直接设置 apiHost： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      posthog: {\n        apiKey: 'YOUR_API_KEY',\n        apiHost: '/my-proxy'\n      }\n    }\n  }\n}) apiHost 选项支持任何 URL 或相对路径，会覆盖 region 默认设置和首方代理的自动配置。对于 ui_host 等额外的 PostHog SDK 选项，可通过 config 透传。",{"id":1871,"title":1872,"titles":1873,"content":1874,"level":314,"path":1871,"to":1871,"label":1872},"/scripts/analytics/posthog#功能标记","功能标记",[175],"功能标记方法会返回值，因此需要先等待 PostHog 加载完成： const { onLoaded } = useScriptPostHog()\n\nonLoaded(({ posthog }) => {\n  // 检查功能标记\n  if (posthog.isFeatureEnabled('new-dashboard')) {\n    // 显示新仪表盘\n  }\n\n  // 获取标记负载\n  const payload = posthog.getFeatureFlagPayload('experiment-config')\n})",{"id":1876,"title":1877,"titles":1878,"content":1879,"level":314,"path":1876,"to":1876,"label":1877},"/scripts/analytics/posthog#禁用会话录制","禁用会话录制",[175],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      posthog: {\n        apiKey: 'YOUR_API_KEY',\n        disableSessionRecording: true\n      }\n    }\n  }\n}) html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}",{"id":180,"title":179,"titles":1881,"content":1882,"level":308,"path":180,"to":180,"label":179},[],"在您的 Nuxt 应用中使用 Rybbit Analytics。 Rybbit Analytics 是一款注重隐私保护的分析解决方案，能够在不侵犯用户隐私的前提下跟踪您网站上的用户活动。 在您的 Nuxt 应用中全局加载 Rybbit Analytics 最简单的方法是使用 Nuxt 配置。或者，您也可以直接使用 useScriptRybbitAnalytics 组合函数。",{"id":1884,"title":1601,"titles":1885,"content":1886,"level":314,"path":1884,"to":1884,"label":1601},"/scripts/analytics/rybbit-analytics#全局加载",[179],"如果您不打算发送自定义事件，可以使用 环境覆盖 在开发环境中禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      rybbitAnalytics: {\n        siteId: 'YOUR_SITE_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        rybbitAnalytics: {\n          siteId: 'YOUR_SITE_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      rybbitAnalytics: true,\n    }\n  },\n  // 您需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        rybbitAnalytics: {\n          // .env 文件中\n          // NUXT_PUBLIC_SCRIPTS_RYBBIT_ANALYTICS_SITE_ID=\u003Cyour-site-id>\n          siteId: ''\n        },\n      },\n    },\n  },\n})",{"id":1888,"title":1889,"titles":1890,"content":1891,"level":314,"path":1888,"to":1888,"label":1889},"/scripts/analytics/rybbit-analytics#usescriptrybbitanalytics","useScriptRybbitAnalytics",[179],"useScriptRybbitAnalytics 组合函数允许您精细控制何时以及如何在您的网站上加载 Rybbit Analytics。 const rybbit = useScriptRybbitAnalytics({\n  siteId: 'YOUR_SITE_ID'\n}) 请参考 注册脚本 指南，了解更多高级用法。",{"id":1893,"title":1894,"titles":1895,"content":1896,"level":320,"path":1893,"to":1893,"label":1894},"/scripts/analytics/rybbit-analytics#自托管-rybbit-analytics","自托管 Rybbit Analytics",[179,1889],"如果您使用的是自托管版本的 Rybbit Analytics，您可以提供自定义脚本源： useScriptRybbitAnalytics({\n  scriptInput: {\n    src: 'https://your-rybbit-instance.com/api/script.js'\n  },\n  siteId: 'YOUR_SITE_ID'\n})",{"id":1898,"title":1899,"titles":1900,"content":1901,"level":320,"path":1898,"to":1898,"label":1899},"/scripts/analytics/rybbit-analytics#rybbitanalyticsapi","RybbitAnalyticsApi",[179,1889],"export interface RybbitAnalyticsApi {\n  /**\n   * 跟踪页面浏览\n   */\n  pageview: () => void\n\n  /**\n   * 跟踪自定义事件\n   * @param name 事件名称\n   * @param properties 事件的可选属性\n   */\n  event: (name: string, properties?: Record\u003Cstring, any>) => void\n\n  /**\n   * 为登录用户设置自定义用户 ID\n   * @param userId 要设置的用户 ID（会存储在 localStorage 中）\n   */\n  identify: (userId: string) => void\n\n  /**\n   * 清除存储的用户 ID\n   */\n  clearUserId: () => void\n\n  /**\n   * 获取当前设置的用户 ID\n   * @returns 当前用户 ID，未设置时返回 null\n   */\n  getUserId: () => string | null\n  /**\n   * @deprecated 请改用顶层函数\n   */\n  rybbit: RybbitAnalyticsApi\n}",{"id":1903,"title":1647,"titles":1904,"content":1905,"level":320,"path":1903,"to":1903,"label":1647},"/scripts/analytics/rybbit-analytics#配置模式",[179,1889],"首次设置脚本时，必须提供选项。 export const RybbitAnalyticsOptions = object({\n  siteId: union([string(), number()]), // 必须项\n  autoTrackPageview: optional(boolean()),\n  trackSpa: optional(boolean()),\n  trackQuery: optional(boolean()),\n  trackOutbound: optional(boolean()),\n  trackErrors: optional(boolean()),\n  sessionReplay: optional(boolean()),\n  webVitals: optional(boolean()),\n  skipPatterns: optional(array(string())),\n  maskPatterns: optional(array(string())),\n  debounce: optional(number()),\n  apiKey: optional(string()),\n})",{"id":1907,"title":1908,"titles":1909,"content":1910,"level":401,"path":1907,"to":1907,"label":1908},"/scripts/analytics/rybbit-analytics#配置选项说明","配置选项说明",[179,1889,1647],"siteId（必填）：您的 Rybbit Analytics 网站 IDautoTrackPageview：设置为 false 以禁用脚本加载时自动跟踪初始页面浏览。您需要手动调用 pageview 函数来跟踪页面浏览。默认值：truetrackSpa：设置为 false 以禁用单页面应用的自动页面浏览跟踪trackQuery：设置为 false 以禁用 URL 查询字符串的跟踪trackOutbound：设置为 false 以禁用自动跟踪外链点击。默认值：truetrackErrors：设置为 true 以启用 JavaScript 错误和未处理 Promise 拒绝的自动跟踪。仅跟踪同源错误，避免第三方脚本噪声。默认值：falsesessionReplay：设置为 true 以启用会话重放录制。捕获用户交互、鼠标移动和 DOM 变更，用于调试和用户体验分析。默认值：falsewebVitals：设置为 true 以启用 Web Vitals 性能指标收集（LCP，CLS，INP，FCP，TTFB）。Web Vitals 默认禁用，以减少脚本大小和网络请求。默认值：falseskipPatterns：忽略的 URL 路径模式数组maskPatterns：用于隐私保护的 URL 路径屏蔽模式数组debounce：在 URL 变化后延迟多少毫秒再跟踪页面浏览apiKey：开发时用于从 localhost 跟踪的 API 密钥。绕过自托管 Rybbit Analytics 实例的来源校验",{"id":1912,"title":1266,"titles":1913,"content":1914,"level":314,"path":1912,"to":1912,"label":1266},"/scripts/analytics/rybbit-analytics#示例",[179],"仅在生产环境使用 Rybbit Analytics 并跟踪自定义事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptRybbitAnalytics()\n\n// 手动跟踪页面浏览\nfunction trackPage() {\n  proxy.pageview()\n}\n\n// 跟踪自定义事件\nfunction trackEvent() {\n  proxy.event('button_click', { buttonId: 'signup' })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"trackPage\">\n      跟踪自定义页面\n    \u003C/button>\n    \u003Cbutton @click=\"trackEvent\">\n      跟踪自定义事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":184,"title":183,"titles":1916,"content":1917,"level":308,"path":184,"to":184,"label":183},[],"在你的 Nuxt 应用中使用 Umami Analytics。 Umami 收集你关心的所有指标，帮助你做出更好的决策。 在你的 Nuxt 应用中全局加载 Umami Analytics 的最简单方式是使用 Nuxt 配置。或者你也可以直接使用 useScriptUmamiAnalytics 组合式函数。",{"id":1919,"title":1601,"titles":1920,"content":1921,"level":314,"path":1919,"to":1919,"label":1601},"/scripts/analytics/umami-analytics#全局加载",[183],"如果你不打算发送自定义事件，可以使用环境覆盖来在开发环境禁用脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      umamiAnalytics: {\n        websiteId: '你的_WEBSITE_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        umamiAnalytics: {\n          websiteId: '你的_WEBSITE_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      umamiAnalytics: true,\n    }\n  },\n  // 你需要提供运行时配置来访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        umamiAnalytics: {\n          // .env 配置\n          // NUXT_PUBLIC_SCRIPTS_UMAMI_ANALYTICS_WEBSITE_ID=\u003C你的 websiteId>\n          websiteId: ''\n        },\n      },\n    },\n  },\n})",{"id":1923,"title":1924,"titles":1925,"content":1926,"level":314,"path":1923,"to":1923,"label":1924},"/scripts/analytics/umami-analytics#usescriptumamianalytics","useScriptUmamiAnalytics",[183],"useScriptUmamiAnalytics 组合式函数让你可以精细地控制 Umami Analytics 在你网站上的加载时机和方式。 const umami = useScriptUmamiAnalytics({\n  websiteId: '你的_WEBSITE_ID'\n}) 请参阅 注册脚本指南 了解更多高级用法。",{"id":1928,"title":1929,"titles":1930,"content":1931,"level":320,"path":1928,"to":1928,"label":1929},"/scripts/analytics/umami-analytics#自托管-umami","自托管 Umami",[183,1924],"如果你使用的是自托管版本的 Umami，则需要显式提供脚本的 src，确保 API 事件发送到正确的端点。 useScriptUmamiAnalytics({\n  scriptInput: {\n    src: 'https://my-self-hosted/script.js'\n  }\n})",{"id":1933,"title":1934,"titles":1935,"content":1936,"level":320,"path":1933,"to":1933,"label":1934},"/scripts/analytics/umami-analytics#umamianalyticsapi","UmamiAnalyticsApi",[183,1924],"export interface UmamiAnalyticsApi {\n  track: ((payload?: Record\u003Cstring, any>) => void) &((event_name: string, event_data: Record\u003Cstring, any>) => void)\n  identify: (session_data?: Record\u003Cstring, any> | string) => void\n}",{"id":1938,"title":1647,"titles":1939,"content":1940,"level":320,"path":1938,"to":1938,"label":1647},"/scripts/analytics/umami-analytics#配置模式",[183,1924],"首次设置脚本时必须提供以下选项。 export const UmamiAnalyticsOptions = object({\n  websiteId: string(), // 必填\n  /**\n   * 默认情况下，Umami 会将数据发送到脚本所在的位置。\n   * 你可以通过此项重写数据发送到其他地址。\n   */\n  hostUrl: optional(string()),\n  /**\n   * 默认情况下，Umami 会自动跟踪所有页面访问和事件。\n   * 你可以禁用此功能，手动使用跟踪器函数跟踪事件。\n   * https://umami.is/docs/tracker-functions\n   */\n  autoTrack: optional(boolean()),\n  /**\n   * 如果你希望跟踪器只在特定域名下运行，可以将它们添加到跟踪器脚本中。\n   * 这是以逗号分隔的域名列表。\n   * 对于处于预发布或开发环境时非常有用。\n   */\n  domains: optional(array(string())),\n  /**\n   * 如果你希望跟踪器在特定标签下收集事件。\n   * 仪表盘可以基于标签过滤事件。\n   */\n  tag: optional(string()),\n  /**\n   * 发送数据到 Umami 前调用的函数。\n   * 该函数接收两个参数：type 和 payload。\n   * 返回 payload 继续发送，返回假值则取消发送。\n   */\n  beforeSend: optional(union([\n    custom\u003C(type: string, payload: Record\u003Cstring, any>) => Record\u003Cstring, any> | null | false>(input => typeof input === 'function'),\n    string(),\n  ])),\n})",{"id":1942,"title":1943,"titles":1944,"content":330,"level":314,"path":1942,"to":1942,"label":1943},"/scripts/analytics/umami-analytics#高级功能","高级功能",[183],{"id":1946,"title":1947,"titles":1948,"content":1949,"level":320,"path":1946,"to":1946,"label":1947},"/scripts/analytics/umami-analytics#会话识别","会话识别",[183,1943],"Umami v2.18.0 以上支持通过 identify 函数设置唯一的会话 ID。你可以传入字符串（唯一 ID）或包含会话数据的对象： const { proxy } = useScriptUmamiAnalytics({\n  websiteId: '你的_WEBSITE_ID'\n})\n\n// 使用唯一字符串 ID\nproxy.identify('user-12345')\n\n// 使用会话数据对象\nproxy.identify({\n  userId: 'user-12345',\n  plan: 'premium'\n})",{"id":1951,"title":1952,"titles":1953,"content":1954,"level":320,"path":1951,"to":1951,"label":1952},"/scripts/analytics/umami-analytics#使用-beforesend-进行数据过滤","使用 beforeSend 进行数据过滤",[183,1943],"beforeSend 选项允许你检查、修改或取消发送到 Umami 的数据。这对于实现自定义隐私控制或数据过滤非常有用： useScriptUmamiAnalytics({\n  websiteId: '你的_WEBSITE_ID',\n  beforeSend: (type, payload) => {\n    // 打印发送数据（用于调试）\n    console.log('发送到 Umami:', type, payload)\n    \n    // 过滤包含敏感数据的网址\n    if (payload.url && payload.url.includes('private')) {\n      return false // 取消发送\n    }\n    \n    // 修改发送数据\n    return {\n      ...payload,\n      referrer: '' // 隐藏来源页以保护隐私\n    }\n  }\n}) 你也可以提供全局定义函数的函数名字符串： // 全局定义函数\nwindow.myBeforeSendHandler = (type, payload) => {\n  return checkPrivacyRules(payload) ? payload : false\n}\n\nuseScriptUmamiAnalytics({\n  websiteId: '你的_WEBSITE_ID',\n  beforeSend: 'myBeforeSendHandler'\n})",{"id":1956,"title":1266,"titles":1957,"content":1958,"level":314,"path":1956,"to":1956,"label":1266},"/scripts/analytics/umami-analytics#示例",[183],"仅在生产环境使用 Umami Analytics，并通过 track 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptUmamiAnalytics()\n\n// 开发环境和 SSR 下为 noop\n// 仅在生产环境客户端正常工作\nproxy.track('event', { name: 'conversion-step' })\n\nfunction sendConversion() {\n  proxy.track('event', { name: 'conversion' })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":193,"title":192,"titles":1960,"content":1961,"level":308,"path":193,"to":193,"label":192},[],"在你的 Nuxt 应用中展示性能优化的谷歌地图。 谷歌地图 允许你将地图嵌入你的网站并用自己的内容进行自定义。 Nuxt Scripts 提供了一个 useScriptGoogleMaps 组合式函数和一个无 UI 的 ScriptGoogleMaps 组件，用于与谷歌地图交互。",{"id":1963,"title":1964,"titles":1965,"content":1966,"level":314,"path":1963,"to":1963,"label":1964},"/scripts/content/google-maps#类型","类型",[192],"要使用带有完整 TypeScript 支持的谷歌地图，你需要安装 @types/google.maps 依赖。 pnpm add -D @types/google.maps",{"id":1968,"title":1969,"titles":1970,"content":1971,"level":314,"path":1968,"to":1968,"label":1969},"/scripts/content/google-maps#scriptgooglemaps","ScriptGoogleMaps",[192],"ScriptGoogleMaps 组件是对 useScriptGoogleMaps 组合式函数的封装。它提供了一种简单方式在你的 Nuxt 应用中嵌入谷歌地图。 它通过利用元素事件触发器进行了性能优化，仅在特定元素事件发生时加载谷歌地图。 在谷歌地图加载之前，它会使用静态地图 API显示一个占位图。 默认情况下，地图会在 mouseover 和 mouseclick 事件触发时加载。",{"id":1973,"title":1974,"titles":1975,"content":1976,"level":320,"path":1973,"to":1973,"label":1974},"/scripts/content/google-maps#计费与权限","计费与权限",[192,1969],"你需要一个拥有访问地图 JavaScript API权限的 API 密钥。可选地，你可以提供对静态地图 API（使用懒加载和占位地图时必需）和地点 API（使用查询搜索时，例如“纽约”）的权限。 显示交互式 JS 地图需要地图 JavaScript API，它是一个付费服务。如果用户与地图交互，将产生以下费用： 地图 JavaScript API：每 1000 次加载 7 美元（默认使用谷歌地图）静态地图 API：每 1000 次加载 2 美元——仅当你没有提供 placeholder 插槽时使用地理编码 API：每 1000 次加载 5 美元——仅当你没有为 center 属性提供 google.maps.LatLng 对象而是使用查询字符串时使用 但是，如果用户从未与地图互动，且你使用了静态地图 API，则只会产生静态地图 API 的费用（每 1000 次加载 2 美元）。 计费将在未来更新中优化。 如果你想避免这些费用，并且能接受功能较弱的地图，可以考虑改用iframe 嵌入。",{"id":1978,"title":1979,"titles":1980,"content":1981,"level":320,"path":1978,"to":1978,"label":1979},"/scripts/content/google-maps#演示","演示",[192,1969],"\u003Cscript setup lang=\"ts\">\nimport { ref } from 'vue'\n\nconst isLoaded = ref(false)\nconst center = ref()\nconst maps = ref()\n\nconst query = ref({\n  lat:  -37.7995487,\n  lng: 144.9867841,\n})\n\nconst markers = ref([])\n\nlet increment = 1\nfunction addMarker() {\n  // 向 markers 中添加标记，我们希望从中心位置添加但随机稍微偏移\n  const _center = center.value || query.value\n  // lat 和 lng 可能是函数\n  const _lat = typeof _center.lat === 'function' ? _center.lat() : _center.lat\n  const _lng = typeof _center.lng === 'function' ? _center.lng() : _center.lng\n  const lat = (1000 * _lat + increment) / 1000\n  const lng = (1000 * _lng + increment) / 1000\n  increment += 1\n\n  markers.value.push(`${lat},${lng}`)\n}\n\nfunction removeMarkers() {\n  markers.value = []\n  increment = 1\n}\nfunction handleReady({ map }) {\n  center.value = map.value.getCenter()\n  map.value.addListener('center_changed', () => {\n    center.value = map.value.getCenter()\n  })\n  isLoaded.value = true\n}\n\u003C/script>\n\n\u003Ctemplate>\n\u003Cdiv class=\"not-prose\">\n  \u003Cdiv class=\"flex items-center justify-center p-5\">\n    \u003CScriptGoogleMaps\n      ref=\"maps\"\n      :center=\"query\"\n      :markers=\"markers\"\n      api-key=\"AIzaSyAOEIQ_xOdLx2dNwnFMzyJoswwvPCTcGzU\"\n      class=\"group\"\n      above-the-fold\n      @ready=\"handleReady\"\n    />\n  \u003C/div>\n  \u003Cdiv class=\"text-center\">\n    \u003CUAlert v-if=\"!isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"静态图像：移动鼠标加载交互地图\" description=\"鼠标悬停地图时将触发谷歌地图脚本加载并初始化地图。\" />\n    \u003CUAlert v-if=\"isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"交互式地图\">\n      \u003Ctemplate #description>\n      中心：{{ center }}\n      \u003C/template>\n    \u003C/UAlert>\n    \u003CUButton @click=\"addMarker\" type=\"button\" class=\"\">\n      添加标记\n    \u003C/UButton>\n    \u003CUButton v-if=\"markers.length\" @click=\"removeMarkers\" type=\"button\" color=\"gray\" variant=\"ghost\" class=\"\">\n      移除标记\n    \u003C/UButton>\n  \u003C/div>\n\u003C/div>\n\u003C/template>",{"id":1983,"title":1984,"titles":1985,"content":1986,"level":320,"path":1983,"to":1983,"label":1984},"/scripts/content/google-maps#属性","属性",[192,1969],"ScriptGoogleMaps 组件支持以下属性。 你必须提供 center 属性以正确加载地图，或者提供 mapOptions 并在其中配置 center 选项。 地图 center：地图中心所在的位置。你可以提供一个位置字符串或 { lat: 0, lng: 0 } 对象。apiKey：谷歌地图 API 密钥，必须也有访问静态地图 API 的权限。你也可以通过运行时配置 public.scripts.googleMaps.apiKey 提供。centerMarker：是否在中心位置显示标记。默认值为 true。mapOptions：地图选项。详见 MapOptions。 占位符 你可以通过以下属性自定义占位图，或者使用 #placeholder 插槽自定义占位图。 placeholderOptions：自定义占位图的属性。详见 静态地图 API。placeholderAttrs：自定义占位图的 HTML 属性。 尺寸 如果你想渲染大于 640x640 的地图，应自行提供占位图，因为静态地图 API不支持渲染超过这个尺寸的地图。 width：地图宽度，默认 640。height：地图高度，默认 400。 优化 trigger：加载谷歌地图的触发事件，默认是 mouseover。更多信息见元素事件触发器。aboveTheFold：针对首屏内容优化占位图，默认 false。 标记 你可以通过提供标记数组添加标记，数组内元素类型为 MarkerOptions。详见MarkerOptions。 markers：用于地图上显示的标记数组。 详细信息请参考 markers 示例。",{"id":1988,"title":1834,"titles":1989,"content":1990,"level":401,"path":1988,"to":1988,"label":1834},"/scripts/content/google-maps#使用环境变量",[192,1969,1984],"如果你希望通过环境变量配置 API 密钥。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleMaps: true,\n    }\n  },\n  // 需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        googleMaps: {\n          apiKey: '', // NUXT_PUBLIC_SCRIPTS_GOOGLE_MAPS_API_KEY\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_GOOGLE_MAPS_API_KEY=\u003C你的API密钥>",{"id":1992,"title":1993,"titles":1994,"content":330,"level":320,"path":1992,"to":1992,"label":1993},"/scripts/content/google-maps#指南","指南",[192,1969],{"id":1996,"title":1997,"titles":1998,"content":1999,"level":401,"path":1996,"to":1996,"label":1997},"/scripts/content/google-maps#预加载占位图","预加载占位图",[192,1969,1993],"谷歌地图的占位图默认采用懒加载。如果你的地图位于首屏位置，建议修改此行为或使用 #placeholder 插槽自定义占位图。 \u003CScriptGoogleMaps above-the-fold />\n\u003CScriptGoogleMaps>\n  \u003Ctemplate #placeholder=\"{ placeholder }\">\n    \u003Cimg :src=\"placeholder\" alt=\"地图占位图\">\n  \u003C/template>\n\u003C/ScriptGoogleMaps>",{"id":2001,"title":2002,"titles":2003,"content":2004,"level":401,"path":2001,"to":2001,"label":2002},"/scripts/content/google-maps#高级标记控制","高级标记控制",[192,1969,1993],"如果你需要对地图标记有更高级的控制，可以使用暴露的 createAdvancedMapMarker 方法，它会返回标记实例。 \u003Cscript lang=\"ts\" setup>\nconst googleMapsRef = ref()\nonMounted(() => {\n  const marker = googleMapsRef.value.createAdvancedMapMarker({\n    position: { }\n  })\n})\n\u003C/script>\n\u003Ctemplate>\n    \u003CScriptGoogleMaps ref=\"googleMapsRef\" />\n\u003C/template>",{"id":2006,"title":2007,"titles":2008,"content":2009,"level":401,"path":2006,"to":2006,"label":2007},"/scripts/content/google-maps#高级地图控制","高级地图控制",[192,1969,1993],"该组件暴露了所有内部 API，你可以根据需要进行地图定制。 \u003Cscript lang=\"ts\" setup>\nconst googleMapsRef = ref()\nonMounted(async () => {\n  const api = googleMapsRef.value\n  \n  // 访问内部 API\n  const googleMaps = api.googleMaps.value // google.maps api\n  const mapInstance = api.map.value // google.maps.Map 实例\n  \n  // 将查询转换为经纬度\n  const query = await api.resolveQueryToLatLang('Space Needle, Seattle, WA') // { lat: 0, lng: 0 }\n  \n  // 导入谷歌地图库\n  const geometry = await api.importLibrary('geometry')\n  const distance = new googleMaps.geometry.spherical.computeDistanceBetween(\n    new googleMaps.LatLng(0, 0),\n    new googleMaps.LatLng(0, 0)\n  )\n})\n\u003C/script>\n\u003Ctemplate>\n    \u003CScriptGoogleMaps ref=\"googleMapsRef\" />\n\u003C/template>",{"id":2011,"title":2012,"titles":2013,"content":2014,"level":401,"path":2011,"to":2011,"label":2012},"/scripts/content/google-maps#立即加载","立即加载",[192,1969,1993],"如果你想立即加载谷歌地图，可以使用 trigger 属性。 \u003Ctemplate>\n\u003CScriptGoogleMaps trigger=\"immediate\">\n\u003C/ScriptGoogleMaps>\n\u003C/template>",{"id":2016,"title":2017,"titles":2018,"content":2019,"level":401,"path":2016,"to":2016,"label":2017},"/scripts/content/google-maps#地图样式","地图样式",[192,1969,1993],"你可以通过 mapOptions.styles 属性为地图设置样式。你可以在Snazzy Maps上找到预制样式。 这会同时应用于静态地图占位图和交互式地图。 \u003Cscript setup lang=\"ts\">\nconst mapOptions = {\n  styles: [{ elementType: 'labels', stylers: [{ visibility: 'off' }, { color: '#f49f53' }] }, { featureType: 'landscape', stylers: [{ color: '#f9ddc5' }, { lightness: -7 }] }, { featureType: 'road', stylers: [{ color: '#813033' }, { lightness: 43 }] }, { featureType: 'poi.business', stylers: [{ color: '#645c20' }, { lightness: 38 }] }, { featureType: 'water', stylers: [{ color: '#1994bf' }, { saturation: -69 }, { gamma: 0.99 }, { lightness: 43 }] }, { featureType: 'road.local', elementType: 'geometry.fill', stylers: [{ color: '#f19f53' }, { weight: 1.3 }, { visibility: 'on' }, { lightness: 16 }] }, { featureType: 'poi.business' }, { featureType: 'poi.park', stylers: [{ color: '#645c20' }, { lightness: 39 }] }, { featureType: 'poi.school', stylers: [{ color: '#a95521' }, { lightness: 35 }] }, {}, { featureType: 'poi.medical', elementType: 'geometry.fill', stylers: [{ color: '#813033' }, { lightness: 38 }, { visibility: 'off' }] },\n}\n\u003C/script>\n\u003Ctemplate>\n\u003CScriptGoogleMaps :mapOptions=\"mapOptions\" />\n\u003C/template>",{"id":2021,"title":1518,"titles":2022,"content":2023,"level":320,"path":2021,"to":2021,"label":1518},"/scripts/content/google-maps#组件-api",[192,1969],"完整的 Props、事件和插槽详情，参见Facade 组件 API。",{"id":2025,"title":1049,"titles":2026,"content":2027,"level":320,"path":2025,"to":2025,"label":1049},"/scripts/content/google-maps#事件",[192,1969],"ScriptGoogleMaps 组件在谷歌地图加载完成时触发单个 ready 事件。 const emits = defineEmits\u003C{\n  ready: [map: google.maps.Map]\n}>() 你可以通过监听 ready 事件来订阅谷歌地图事件。 \u003Cscript setup lang=\"ts\">\nfunction handleReady({ map }) {\n  map.addListener('center_changed', () => {\n    console.log('中心已改变', map.getCenter())\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptGoogleMaps @ready=\"handleReady\" />\n\u003C/template>",{"id":2029,"title":1044,"titles":2030,"content":2031,"level":320,"path":2029,"to":2029,"label":1044},"/scripts/content/google-maps#插槽",[192,1969],"组件默认只提供最小化的 UI，仅保证功能和无障碍性。你可以通过多个插槽自由定制地图显示。 default 默认插槽用于显示始终可见的内容。 \u003Ctemplate>\n  \u003CScriptGoogleMaps>\n    \u003Cdiv class=\"absolute top-0 left-0 right-0 p-5 bg-white text-black\">\n      \u003Ch1 class=\"text-xl font-bold\">\n        我的自定义地图\n      \u003C/h1>\n    \u003C/div>\n  \u003C/ScriptGoogleMaps>\n\u003C/template> awaitingLoad 该插槽用于谷歌地图加载过程中的显示内容。 \u003Ctemplate>\n  \u003CScriptGoogleMaps>\n    \u003Ctemplate #awaitingLoad>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        点击加载地图！\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptGoogleMaps>\n\u003C/template> loading 该插槽用于谷歌地图加载时的显示内容。 注意：默认会显示一个 ScriptLoadingIndicator 以提升无障碍性和用户体验，若自定义此插槽会覆盖该默认组件，请确保提供加载指示器。 \u003Ctemplate>\n  \u003CScriptGoogleMaps>\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        加载中...\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptGoogleMaps>\n\u003C/template> placeholder 该插槽用于谷歌地图加载前显示占位图。默认情况下，显示谷歌地图静态 API 的图片。 若你提供了自定义占位图槽，将禁用默认占位图，且不会产生静态地图 API 的费用。 \u003Ctemplate>\n  \u003CScriptGoogleMaps>\n    \u003Ctemplate #placeholder=\"{ placeholder }\">\n      \u003Cimg :src=\"placeholder\">\n    \u003C/template>\n  \u003C/ScriptGoogleMaps>\n\u003C/template>",{"id":2033,"title":2034,"titles":2035,"content":2036,"level":314,"path":2033,"to":2033,"label":2034},"/scripts/content/google-maps#谷歌地图单文件组件sfc","谷歌地图单文件组件（SFC）",[192],"Nuxt Scripts 提供了多个独立的单文件组件（SFC），用于不同的谷歌地图元素。这些组件允许你通过 Vue 模板语法声明式地组合复杂地图。",{"id":2038,"title":16,"titles":2039,"content":2040,"level":320,"path":2038,"to":2038,"label":16},"/scripts/content/google-maps#安装",[192,2034],"要使用标记聚合（marker clustering）功能，你需要安装对应的同级依赖包： npm install @googlemaps/markerclusterer\n# 或者\nyarn add @googlemaps/markerclusterer\n# 或者\npnpm add @googlemaps/markerclusterer",{"id":2042,"title":2043,"titles":2044,"content":2045,"level":320,"path":2042,"to":2042,"label":2043},"/scripts/content/google-maps#可用组件","可用组件",[192,2034],"所有谷歌地图 SFC 组件必须嵌套在 \u003CScriptGoogleMaps> 组件内使用： \u003CScriptGoogleMapsMarker> - 经典标记，支持图标\u003CScriptGoogleMapsAdvancedMarkerElement> - 现代高级标记，支持 HTML 内容\u003CScriptGoogleMapsPinElement> - 可定制的针型标记（用于高级标记中）\u003CScriptGoogleMapsInfoWindow> - 点击时显示的信息窗口\u003CScriptGoogleMapsMarkerClusterer> - 将附近标记聚合成群组\u003CScriptGoogleMapsCircle> - 圆形覆盖层\u003CScriptGoogleMapsPolygon> - 多边形形状\u003CScriptGoogleMapsPolyline> - 线条路径\u003CScriptGoogleMapsRectangle> - 矩形覆盖层\u003CScriptGoogleMapsHeatmapLayer> - 热力图可视化层",{"id":2047,"title":1270,"titles":2048,"content":2049,"level":320,"path":2047,"to":2047,"label":1270},"/scripts/content/google-maps#基本用法",[192,2034],"\u003Ctemplate>\n  \u003CScriptGoogleMaps\n    :center=\"{ lat: -34.397, lng: 150.644 }\"\n    :zoom=\"8\"\n    api-key=\"your-api-key\"\n  >\n    \u003C!-- 添加标记 -->\n    \u003CScriptGoogleMapsMarker\n      :options=\"{ position: { lat: -34.397, lng: 150.644 } }\"\n    >\n      \u003C!-- 点击标记显示信息窗口 -->\n      \u003CScriptGoogleMapsInfoWindow>\n        \u003Cdiv>\n          \u003Ch3>澳大利亚，悉尼\u003C/h3>\n          \u003Cp>一座伟大的城市！\u003C/p>\n        \u003C/div>\n      \u003C/ScriptGoogleMapsInfoWindow>\n    \u003C/ScriptGoogleMapsMarker>\n\n    \u003C!-- 高级标记，带自定义针 -->\n    \u003CScriptGoogleMapsAdvancedMarkerElement\n      :options=\"{ position: { lat: -34.407, lng: 150.654 } }\"\n    >\n      \u003CScriptGoogleMapsPinElement\n        :options=\"{ scale: 1.5, background: '#FF0000' }\"\n      />\n    \u003C/ScriptGoogleMapsAdvancedMarkerElement>\n\n    \u003C!-- 圆形覆盖层 -->\n    \u003CScriptGoogleMapsCircle\n      :options=\"{\n        center: { lat: -34.397, lng: 150.644 },\n        radius: 1000,\n        fillColor: '#FF0000',\n        fillOpacity: 0.35\n      }\"\n    />\n  \u003C/ScriptGoogleMaps>\n\u003C/template>",{"id":2051,"title":2052,"titles":2053,"content":2054,"level":320,"path":2051,"to":2051,"label":2052},"/scripts/content/google-maps#组件组合示例","组件组合示例",[192,2034],"标记聚合 \u003Ctemplate>\n  \u003CScriptGoogleMaps api-key=\"your-api-key\">\n    \u003CScriptGoogleMapsMarkerClusterer>\n      \u003CScriptGoogleMapsMarker\n        v-for=\"location in locations\"\n        :key=\"location.id\"\n        :options=\"{ position: location.position }\"\n      >\n        \u003CScriptGoogleMapsInfoWindow>\n          \u003Cdiv>{{ location.name }}\u003C/div>\n        \u003C/ScriptGoogleMapsInfoWindow>\n      \u003C/ScriptGoogleMapsMarker>\n    \u003C/ScriptGoogleMapsMarkerClusterer>\n  \u003C/ScriptGoogleMaps>\n\u003C/template> 热力图与数据点 \u003Cscript setup>\nconst heatmapData = ref([])\n\nonMounted(() => {\n  // 用 google.maps.LatLng 对象填充热力图数据\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptGoogleMaps api-key=\"your-api-key\">\n    \u003CScriptGoogleMapsHeatmapLayer\n      :options=\"{ data: heatmapData }\"\n    />\n  \u003C/ScriptGoogleMaps>\n\u003C/template> 完整示例请参阅SFC Playground 示例。",{"id":2056,"title":2057,"titles":2058,"content":330,"level":320,"path":2056,"to":2056,"label":2057},"/scripts/content/google-maps#组件详情","组件详情",[192,2034],{"id":2060,"title":2061,"titles":2062,"content":2063,"level":401,"path":2060,"to":2060,"label":2061},"/scripts/content/google-maps#scriptgooglemapsmarker","ScriptGoogleMapsMarker",[192,2034,2057],"经典谷歌地图标记，支持图标。 属性: options - google.maps.MarkerOptions（不包括 map） 事件: 标准标记事件：click、mousedown、mouseover 等。",{"id":2065,"title":2066,"titles":2067,"content":2068,"level":401,"path":2065,"to":2065,"label":2066},"/scripts/content/google-maps#scriptgooglemapsadvancedmarkerelement","ScriptGoogleMapsAdvancedMarkerElement",[192,2034,2057],"现代高级标记，支持 HTML 内容和更好的自定义。 属性: options - google.maps.marker.AdvancedMarkerElementOptions（不包括 map） 事件: 标准标记事件：click、drag、position_changed 等。",{"id":2070,"title":2071,"titles":2072,"content":2073,"level":401,"path":2070,"to":2070,"label":2071},"/scripts/content/google-maps#scriptgooglemapsinfowindow","ScriptGoogleMapsInfoWindow",[192,2034,2057],"显示内容的窗口。 属性: options - google.maps.InfoWindowOptions 行为: 会在父级标记点击时自动打开也可作为独立组件使用，并显式定义位置支持通过默认插槽传入自定义 HTML 内容",{"id":2075,"title":2076,"titles":2077,"content":2078,"level":401,"path":2075,"to":2075,"label":2076},"/scripts/content/google-maps#scriptgooglemapsmarkerclusterer","ScriptGoogleMapsMarkerClusterer",[192,2034,2057],"将相近标记聚合，提升性能和用户体验。 属性: options - MarkerClustererOptions（不包括 map） 依赖: 需要安装 @googlemaps/markerclusterer 同级依赖",{"id":2080,"title":2081,"titles":2082,"content":2083,"level":401,"path":2080,"to":2080,"label":2081},"/scripts/content/google-maps#其他组件","其他组件",[192,2034,2057],"ScriptGoogleMapsPinElement：用于高级标记的可定制针ScriptGoogleMapsCircle：带半径和样式的圆形覆盖层ScriptGoogleMapsPolygon/Polyline：形状和线条覆盖层ScriptGoogleMapsRectangle：矩形覆盖层ScriptGoogleMapsHeatmapLayer：数据可视化热力图 所有组件支持： 响应式 options 属性，自动更新谷歌地图对象组件卸载时自动清理TypeScript 类型支持",{"id":2085,"title":1337,"titles":2086,"content":330,"level":320,"path":2085,"to":2085,"label":1337},"/scripts/content/google-maps#最佳实践",[192,2034],{"id":2088,"title":2089,"titles":2090,"content":2091,"level":401,"path":2088,"to":2088,"label":2089},"/scripts/content/google-maps#性能建议","性能建议",[192,2034,1337],"大量标记时使用 MarkerClusterer \u003C!-- ✅ 推荐：超过 10 个标记使用聚合器 -->\n\u003CScriptGoogleMapsMarkerClusterer>\n  \u003CScriptGoogleMapsMarker v-for=\"marker in manyMarkers\" />\n\u003C/ScriptGoogleMapsMarkerClusterer>\n\n\u003C!-- ❌ 避免：大量独立标记 -->\n\u003CScriptGoogleMapsMarker v-for=\"marker in manyMarkers\" /> 现代应用推荐使用 AdvancedMarkerElement \u003C!-- ✅ 推荐：性能与样式更佳 -->\n\u003CScriptGoogleMapsAdvancedMarkerElement :options=\"options\">\n  \u003CScriptGoogleMapsPinElement :options=\"{ background: '#FF0000' }\" />\n\u003C/ScriptGoogleMapsAdvancedMarkerElement>\n\n\u003C!-- ⚠️ 旧版：仅在不支持高级标记时使用 -->\n\u003CScriptGoogleMapsMarker :options=\"options\" />",{"id":2093,"title":2094,"titles":2095,"content":2096,"level":401,"path":2093,"to":2093,"label":2094},"/scripts/content/google-maps#组件层级关系","组件层级关系",[192,2034,1337],"组件应遵循如下嵌套结构： ScriptGoogleMaps (根组件)\n├── ScriptGoogleMapsMarkerClusterer (可选)\n│   └── ScriptGoogleMapsMarker/AdvancedMarkerElement\n│       └── ScriptGoogleMapsInfoWindow (可选)\n├── ScriptGoogleMapsAdvancedMarkerElement\n│   ├── ScriptGoogleMapsPinElement (可选)\n│   └── ScriptGoogleMapsInfoWindow (可选)\n└── 其他覆盖层（Circle、Polygon 等）",{"id":2098,"title":2099,"titles":2100,"content":2101,"level":401,"path":2098,"to":2098,"label":2099},"/scripts/content/google-maps#响应式数据示例","响应式数据示例",[192,2034,1337],"响应式标记更新 \u003Cscript setup>\nconst markers = ref([\n  { id: 1, position: { lat: -34.397, lng: 150.644 }, title: '悉尼' }\n])\n\n// 数据变更时标记自动更新\nfunction addMarker() {\n  markers.value.push({\n    id: Date.now(),\n    position: getRandomPosition(),\n    title: '新地点'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptGoogleMaps>\n    \u003CScriptGoogleMapsMarker\n      v-for=\"marker in markers\"\n      :key=\"marker.id\"\n      :options=\"{ position: marker.position, title: marker.title }\"\n    />\n  \u003C/ScriptGoogleMaps>\n\u003C/template>",{"id":2103,"title":2104,"titles":2105,"content":2106,"level":401,"path":2103,"to":2103,"label":2104},"/scripts/content/google-maps#错误处理","错误处理",[192,2034,1337],"始终提供错误回退和加载状态： \u003Cscript setup>\nconst mapError = ref(false)\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptGoogleMaps\n    @error=\"mapError = true\"\n    api-key=\"your-api-key\"\n  >\n    \u003Ctemplate #error>\n      \u003Cdiv class=\"p-4 bg-red-100\">\n        谷歌地图加载失败\n      \u003C/div>\n    \u003C/template>\n\n    \u003C!-- 你的组件 -->\n  \u003C/ScriptGoogleMaps>\n\u003C/template>",{"id":2108,"title":2109,"titles":2110,"content":2111,"level":314,"path":2108,"to":2108,"label":2109},"/scripts/content/google-maps#usescriptgooglemaps","useScriptGoogleMaps",[192],"useScriptGoogleMaps 组合式函数让你可以灵活控制谷歌地图 SDK。它提供了一种方式来加载谷歌地图 SDK 并以编程方式与之交互。 export function useScriptGoogleMaps\u003CT extends GoogleMapsApi>(_options?: GoogleMapsInput) {} 请参阅Registry 脚本指南了解更高级用法。",{"id":2113,"title":2114,"titles":2115,"content":2116,"level":320,"path":2113,"to":2113,"label":2114},"/scripts/content/google-maps#googlemapsapi","GoogleMapsApi",[192,2109],"export interface GoogleMapsApi {\n  // @types/google.maps\n  maps: typeof google.maps\n}",{"id":2118,"title":1266,"titles":2119,"content":2120,"level":314,"path":2118,"to":2118,"label":1266},"/scripts/content/google-maps#示例",[192],"加载谷歌地图 SDK 并以编程方式操作它。 \u003Cscript setup lang=\"ts\">\n/// \u003Creference types=\"google.maps\" />\nconst { onLoaded } = useScriptGoogleMaps({\n  apiKey: 'key'\n})\nconst map = ref()\nonMounted(() => {\n  onLoaded(async (instance) => {\n    const maps = await instance.maps as any as typeof google.maps // 上游的 google 类型问题\n    new maps.Map(map.value, {\n      center: { lat: -34.397, lng: 150.644 },\n      zoom: 8\n    })\n    // 可执行进一步操控\n  })\n})\n\u003C/script>\n\u003Ctemplate>\n    \u003Cdiv ref=\"map\" />\n\u003C/template> html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .skSwn, html code.shiki .skSwn{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s9JP1, html code.shiki .s9JP1{--shiki-light:#22863A;--shiki-light-font-style:inherit;--shiki-default:#22863A;--shiki-default-font-style:inherit;--shiki-dark:#F07178;--shiki-dark-font-style:italic}html pre.shiki code .s1R3m, html code.shiki .s1R3m{--shiki-light:#6F42C1;--shiki-light-font-style:inherit;--shiki-default:#6F42C1;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .sV6QL, html code.shiki .sV6QL{--shiki-light:#032F62;--shiki-light-font-style:inherit;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .shPU9, html code.shiki .shPU9{--shiki-light:#032F62;--shiki-light-font-style:inherit;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#C3E88D;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}",{"id":197,"title":196,"titles":2122,"content":2123,"level":308,"path":197,"to":197,"label":196},[],"服务器端渲染的 Instagram 嵌入，无需客户端 API 调用。 Instagram 是一个照片和视频分享的社交媒体平台。 Nuxt Scripts 提供了一个 ScriptInstagramEmbed 组件，它在服务器端获取 Instagram 的嵌入 HTML，并通过你的服务器代理所有资源 —— 无需客户端调用 Instagram API。",{"id":2125,"title":2126,"titles":2127,"content":2128,"level":314,"path":2125,"to":2125,"label":2126},"/scripts/content/instagram-embed#scriptinstagramembed","ScriptInstagramEmbed",[196],"ScriptInstagramEmbed 组件特点： 服务器端获取官方 Instagram 嵌入 HTML重写所有图片和资源 URL，通过你的服务器代理移除 Instagram 的 embed.js 脚本（不需要）缓存响应 10 分钟",{"id":2130,"title":1266,"titles":2131,"content":2132,"level":320,"path":2130,"to":2130,"label":1266},"/scripts/content/instagram-embed#示例",[196,2126],"\u003Ctemplate>\n  \u003CScriptInstagramEmbed\n    post-url=\"https://www.instagram.com/p/C3Sk6d2MTjI/\"\n    :captions=\"true\"\n  />\n\u003C/template>\n\u003Ctemplate>\n  \u003CScriptInstagramEmbed\n    post-url=\"https://www.instagram.com/p/C3Sk6d2MTjI/\"\n    :captions=\"true\"\n  >\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"animate-pulse bg-gray-100 rounded-lg p-4 aspect-square max-w-md\">\n        正在加载 Instagram 帖子...\n      \u003C/div>\n    \u003C/template>\n\n    \u003Ctemplate #error>\n      \u003Cdiv class=\"bg-red-50 border border-red-200 rounded-lg p-4 max-w-md\">\n        加载 Instagram 帖子失败\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptInstagramEmbed>\n\u003C/template>\n\u003Ctemplate>\n  \u003CScriptInstagramEmbed post-url=\"https://www.instagram.com/p/C3Sk6d2MTjI/\">\n    \u003Ctemplate #default=\"{ html, shortcode, postUrl }\">\n      \u003Cdiv class=\"instagram-wrapper\">\n        \u003Ca :href=\"postUrl\" target=\"_blank\" class=\"text-sm text-gray-500 mb-2 block\">\n          在 Instagram 查看 ({{ shortcode }})\n        \u003C/a>\n        \u003C!-- eslint-disable-next-line vue/no-v-html -->\n        \u003Cdiv v-html=\"html\" />\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptInstagramEmbed>\n\u003C/template>",{"id":2134,"title":1039,"titles":2135,"content":2136,"level":320,"path":2134,"to":2134,"label":1039},"/scripts/content/instagram-embed#props",[196,2126],"ScriptInstagramEmbed 组件接受以下属性： 属性类型默认值说明postUrlstring必填Instagram 帖子链接 (例如 https://www.instagram.com/p/ABC123/)captionsbooleantrue是否在嵌入中包含字幕apiEndpointstring/api/_scripts/instagram-embed用于获取嵌入 HTML 的自定义 API 端点rootAttrsHTMLAttributes{}根元素属性",{"id":2138,"title":2139,"titles":2140,"content":2141,"level":320,"path":2138,"to":2138,"label":2139},"/scripts/content/instagram-embed#插槽-props","插槽 Props",[196,2126],"默认插槽接收： interface SlotProps {\n  html: string      // 处理后的嵌入 HTML\n  shortcode: string // 帖子短码 (例如 \"C3Sk6d2MTjI\")\n  postUrl: string   // 原始帖子链接\n}",{"id":2143,"title":2144,"titles":2145,"content":2146,"level":320,"path":2143,"to":2143,"label":2144},"/scripts/content/instagram-embed#命名插槽","命名插槽",[196,2126],"插槽说明default主要内容，接收 { html, shortcode, postUrl }。默认渲染 HTML。loading获取嵌入 HTML 时显示error嵌入获取失败时显示，接收 { error }",{"id":2148,"title":2149,"titles":2150,"content":2151,"level":314,"path":2148,"to":2148,"label":2149},"/scripts/content/instagram-embed#支持的-url-格式","支持的 URL 格式",[196],"帖子: https://www.instagram.com/p/ABC123/Reels: https://www.instagram.com/reel/ABC123/TV: https://www.instagram.com/tv/ABC123/",{"id":2153,"title":609,"titles":2154,"content":2155,"level":314,"path":2153,"to":2153,"label":609},"/scripts/content/instagram-embed#工作原理",[196],"服务器端抓取：从 {postUrl}/embed/ 获取 Instagram 嵌入 HTML资源代理：将来自 scontent.cdninstagram.com 的所有图片和来自 static.cdninstagram.com 的资源重写为通过你的服务器代理脚本移除：移除 Instagram 的 embed.js （静态渲染不需要）缓存：服务器级别缓存响应 10 分钟 该方案启发自 Cloudflare Zaraz 的嵌入实现。",{"id":2157,"title":2158,"titles":2159,"content":2160,"level":314,"path":2157,"to":2157,"label":2158},"/scripts/content/instagram-embed#隐私优势","隐私优势",[196],"不加载第三方 JavaScriptInstagram/Meta 不设置任何 Cookies浏览器不会直接与 Instagram 通信不会向 Instagram 共享用户 IP 地址所有内容均由你的域名提供",{"id":2162,"title":1434,"titles":2163,"content":2164,"level":314,"path":2162,"to":2162,"label":1434},"/scripts/content/instagram-embed#限制",[196],"仅支持单图帖子（图集只显示第一张图片）视频以静态封面图展示一些交互功能不可用（点赞、评论） html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}",{"id":201,"title":200,"titles":2166,"content":2167,"level":308,"path":201,"to":201,"label":200},[],"在你的 Nuxt 应用中展示性能优化的 Vimeo 视频。 Vimeo 是一个视频托管平台，允许你上传和分享视频。 Nuxt Scripts 提供了一个 useScriptVimeoPlayer 组合式函数和一个无 UI 的 ScriptVimeoPlayer 组件，用于与 Vimeo 播放器交互。",{"id":2169,"title":1964,"titles":2170,"content":2171,"level":314,"path":2169,"to":2169,"label":1964},"/scripts/content/vimeo-player#类型",[200],"若想使用具备完整 TypeScript 支持的视频播放器，你需要安装 @types/vimeo__player 依赖。 pnpm add -D @types/vimeo__player",{"id":2173,"title":2174,"titles":2175,"content":2176,"level":314,"path":2173,"to":2173,"label":2174},"/scripts/content/vimeo-player#scriptvimeoplayer","ScriptVimeoPlayer",[200],"ScriptVimeoPlayer 组件是 useScriptVimeoPlayer 组合式函数的封装。它提供了一种简便方式在你的 Nuxt 应用中嵌入 Vimeo 视频。 通过利用 元素事件触发，仅在特定元素事件发生时加载 Vimeo 播放器，从而优化性能。 默认情况下，它会在 mousedown 事件时加载。",{"id":2178,"title":1979,"titles":2179,"content":2180,"level":320,"path":2178,"to":2178,"label":1979},"/scripts/content/vimeo-player#演示",[200,2174],"\u003Cscript setup lang=\"ts\">\nconst isLoaded = ref(false)\nconst isPlaying = ref(false)\nconst video = ref()\nasync function play() {\n  await video.value.play()\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv class=\"flex items-center justify-center p-5\">\n      \u003CScriptVimeoPlayer :id=\"331567154\" ref=\"video\" class=\"group\" @loaded=\"isLoaded = true\" @play=\"isPlaying = true\" @pause=\"isPlaying = false\">\n        \u003Ctemplate #awaitingLoad>\n          \u003Cdiv class=\"absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-blue-500 group-hover:bg-blue-700 transition rounded px-6 py-2\">\n            \u003Csvg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" class=\"w-10 h-10 text-white\" xmlns=\"http://www.w3.org/2000/svg\">\u003Cpath d=\"M19 12C19 12.3557 18.8111 12.6846 18.5039 12.8638L6.50387 19.8638C6.19458 20.0442 5.81243 20.0455 5.50194 19.8671C5.19145 19.6888 5 19.3581 5 19L5 5C5 4.64193 5.19145 4.3112 5.50194 4.13286C5.81243 3.95452 6.19458 3.9558 6.50387 4.13622L18.5039 11.1362C18.8111 11.3154 19 11.6443 19 12Z\" fill=\"currentColor\" />\u003C/svg>\n          \u003C/div>\n        \u003C/template>\n      \u003C/ScriptVimeoPlayer>\n    \u003C/div>\n    \u003Cdiv class=\"text-center\">\n      \u003CUAlert v-if=\"!isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"点击视频！\" description=\"点击视频会加载 Vimeo iframe 并开始播放视频。\" />\n      \u003CUButton v-if=\"isLoaded && !isPlaying\" @click=\"play\">\n        播放视频\n      \u003C/UButton>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>",{"id":2182,"title":2183,"titles":2184,"content":2185,"level":320,"path":2182,"to":2182,"label":2183},"/scripts/content/vimeo-player#属性props","属性（Props）",[200,2174],"ScriptVimeoPlayer 组件接收以下属性： trigger：触发加载 Vimeo 播放器的事件，默认是 mousedown。更多信息请参见 元素事件触发。aboveTheFold：优化折叠上方内容的占位图像，默认是 false。rootAttrs：覆盖自动设置的根节点属性。placeholderAttrs：占位图像的属性，默认是 { loading: 'lazy' }。id：vimeoOptions.id 的简写。url：vimeoOptions.url 的简写。vimeoOptions：支持 Player SDK 的所有选项，完整文档请参考 嵌入选项。 interface VimeoPlayerProps {\n  id: number | undefined\n  url?: string | undefined\n  autopause?: boolean | undefined\n  autoplay?: boolean | undefined\n  background?: boolean | undefined\n  byline?: boolean | undefined\n  color?: string | undefined\n  controls?: boolean | undefined\n  dnt?: boolean | undefined\n  height?: number | undefined\n  interactive_params?: string | undefined\n  keyboard?: boolean | undefined\n  loop?: boolean | undefined\n  maxheight?: number | undefined\n  maxwidth?: number | undefined\n  muted?: boolean | undefined\n  pip?: boolean | undefined\n  playsinline?: boolean | undefined\n  portrait?: boolean | undefined\n  responsive?: boolean | undefined\n  speed?: boolean | undefined\n  quality?: VimeoVideoQuality | undefined\n  texttrack?: string | undefined\n  title?: boolean | undefined\n  transparent?: boolean | undefined\n  width?: number | undefined\n}",{"id":2187,"title":2188,"titles":2189,"content":2190,"level":401,"path":2187,"to":2187,"label":2188},"/scripts/content/vimeo-player#预加载eager-loading占位图","预加载（Eager Loading）占位图",[200,2174,2183],"Vimeo 视频的占位图默认是懒加载的。如果你的视频是折叠上方内容，建议修改此行为，或者使用 #placeholder 插槽自定义占位图。 \u003CScriptVimeoPlayer above-the-fold />\n\u003CScriptVimeoPlayer>\n  \u003Ctemplate #placeholder=\"{ placeholder }\">\n    \u003Cimg :src=\"placeholder\" alt=\"视频占位图\">\n  \u003C/template>\n\u003C/ScriptVimeoPlayer>",{"id":2192,"title":1518,"titles":2193,"content":2194,"level":320,"path":2192,"to":2192,"label":1518},"/scripts/content/vimeo-player#组件-api",[200,2174],"完整的属性、事件和插槽信息请参阅 Facade 组件 API。",{"id":2196,"title":1049,"titles":2197,"content":2198,"level":320,"path":2196,"to":2196,"label":1049},"/scripts/content/vimeo-player#事件",[200,2174],"ScriptVimeoPlayer 组件会触发 Vimeo 播放器 SDK 的所有事件。完整文档请查看 播放器事件。 const emits = defineEmits\u003C{\n  play: [e: EventMap['play'], player: Player]\n  playing: [e: EventMap['playing'], player: Player]\n  pause: [e: EventMap['pause'], player: Player]\n  ended: [e: EventMap['ended'], player: Player]\n  timeupdate: [e: EventMap['timeupdate'], player: Player]\n  progress: [e: EventMap['progress'], player: Player]\n  seeking: [e: EventMap['seeking'], player: Player]\n  seeked: [e: EventMap['seeked'], player: Player]\n  texttrackchange: [e: EventMap['texttrackchange'], player: Player]\n  chapterchange: [e: EventMap['chapterchange'], player: Player]\n  cuechange: [e: EventMap['cuechange'], player: Player]\n  cuepoint: [e: EventMap['cuepoint'], player: Player]\n  volumechange: [e: EventMap['volumechange'], player: Player]\n  playbackratechange: [e: EventMap['playbackratechange'], player: Player]\n  bufferstart: [e: EventMap['bufferstart'], player: Player]\n  bufferend: [e: EventMap['bufferend'], player: Player]\n  error: [e: EventMap['error'], player: Player]\n  loaded: [e: EventMap['loaded'], player: Player]\n  durationchange: [e: EventMap['durationchange'], player: Player]\n  fullscreenchange: [e: EventMap['fullscreenchange'], player: Player]\n  qualitychange: [e: EventMap['qualitychange'], player: Player]\n  camerachange: [e: EventMap['camerachange'], player: Player]\n  resize: [e: EventMap['resize'], player: Player]\n  enterpictureinpicture: [e: EventMap['enterpictureinpicture'], player: Player]\n  leavepictureinpicture: [e: EventMap['leavepictureinpicture'], player: Player]\n}>()",{"id":2200,"title":2201,"titles":2202,"content":2203,"level":320,"path":2200,"to":2200,"label":2201},"/scripts/content/vimeo-player#插槽slots","插槽（Slots）",[200,2174],"由于该组件为无 UI 组件，你可以通过多个插槽自定义播放器的加载前展示。 default 默认插槽用来显示始终可见的内容。 \u003Ctemplate>\n  \u003CScriptVimeoPlayer :id=\"331567154\">\n    \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n      视频提供者：NuxtJS\n    \u003C/div>\n  \u003C/ScriptVimeoPlayer>\n\u003C/template> awaitingLoad 该插槽用于视频加载时显示内容。 \u003Ctemplate>\n  \u003CScriptVimeoPlayer :id=\"331567154\">\n    \u003Ctemplate #awaitingLoad>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        点击播放！\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptVimeoPlayer>\n\u003C/template> loading 该插槽用于视频加载过程中显示的内容。 \u003Ctemplate>\n  \u003CScriptVimeoPlayer :id=\"331567154\">\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        加载中...\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptVimeoPlayer>\n\u003C/template> placeholder 该插槽用于视频加载前显示的占位图。默认情况下，它会展示 Vimeo 视频的缩略图。你可以根据需求自定义显示。 \u003Ctemplate>\n  \u003CScriptVimeoPlayer :id=\"331567154\">\n    \u003Ctemplate #placeholder=\"{ placeholder }\">\n      \u003Cimg :src=\"placeholder\" alt=\"视频占位图\">\n    \u003C/template>\n  \u003C/ScriptVimeoPlayer>\n\u003C/template>",{"id":2205,"title":2206,"titles":2207,"content":2208,"level":314,"path":2205,"to":2205,"label":2206},"/scripts/content/vimeo-player#usescriptvimeoplayer","useScriptVimeoPlayer",[200],"useScriptVimeoPlayer 组合式函数让你可以更细粒度地控制 Vimeo 播放器 SDK。它提供了加载 Vimeo 播放器 SDK 并以编程方式交互的方式。 export function useScriptVimeoPlayer\u003CT extends VimeoPlayerApi>(_options?: VimeoPlayerInput) {} 请参考 Registry Scripts 指南以获取更多高级用法。",{"id":2210,"title":2211,"titles":2212,"content":2213,"level":320,"path":2210,"to":2210,"label":2211},"/scripts/content/vimeo-player#vimeoplayerapi","VimeoPlayerApi",[200,2206],"export interface VimeoPlayerApi {\n  Vimeo: {\n    Player: ScriptVimeoPlayer\n  }\n}",{"id":2215,"title":1266,"titles":2216,"content":2217,"level":314,"path":2215,"to":2215,"label":1266},"/scripts/content/vimeo-player#示例",[200],"加载 Vimeo 播放器 SDK 并以编程方式进行交互。 \u003Cscript setup lang=\"ts\">\nconst video = ref()\nconst { onLoaded } = useScriptVimeoPlayer()\n\nlet player\nonLoaded(({ Vimeo }) => {\n  player = new Vimeo.Player(video.value, {\n    id: 331567154\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv ref=\"video\" />\n    \u003Cbutton @click=\"player.play()\">\n      播放\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}",{"id":205,"title":204,"titles":2219,"content":2220,"level":308,"path":205,"to":205,"label":204},[],"服务器端渲染的 X（Twitter）嵌入，无需任何客户端 API 调用。 X（前身为 Twitter） 是一个用于分享帖子的社交媒体平台。 Nuxt Scripts 提供了一个 ScriptXEmbed 组件，它在服务器端获取推文数据，并通过插槽暴露出来，实现完全的样式控制。所有数据均通过你的服务器代理 —— 不进行任何客户端对 X 的 API 调用。",{"id":2222,"title":2223,"titles":2224,"content":2225,"level":314,"path":2222,"to":2222,"label":2223},"/scripts/content/x-embed#scriptxembed","ScriptXEmbed",[204],"ScriptXEmbed 组件是一个无头组件，功能包括： 通过 X 联合 API 在服务器端获取推文数据通过你的服务器代理所有图片以保护隐私通过作用域插槽暴露推文数据，实现自定义渲染缓存响应 10 分钟",{"id":2227,"title":1979,"titles":2228,"content":2229,"level":320,"path":2227,"to":2227,"label":1979},"/scripts/content/x-embed#演示",[204,2223],"\u003Ctemplate>\n  \u003CScriptXEmbed tweet-id=\"1754336034228171055\">\n    \u003Ctemplate #default=\"{ userName, userHandle, text, datetime, likesFormatted }\">\n      \u003Cdiv class=\"border rounded-lg p-4 max-w-md\">\n        \u003Cp class=\"font-bold\">{{ userName }} (@{{ userHandle }})\u003C/p>\n        \u003Cp>{{ text }}\u003C/p>\n        \u003Cp class=\"text-gray-500 text-sm\">{{ datetime }} - {{ likesFormatted }} 赞\u003C/p>\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptXEmbed>\n\u003C/template>\n\u003Ctemplate>\n  \u003CScriptXEmbed tweet-id=\"1754336034228171055\">\n    \u003Ctemplate #default=\"{ userName, userHandle, userAvatar, text, datetime, likesFormatted, repliesFormatted, tweetUrl, photos, isVerified }\">\n      \u003Cdiv class=\"max-w-lg bg-white dark:bg-gray-800 rounded-xl border p-4\">\n        \u003C!-- 头部 -->\n        \u003Cdiv class=\"flex items-start gap-3 mb-3\">\n          \u003Cimg :src=\"userAvatar\" :alt=\"userName\" class=\"w-12 h-12 rounded-full\">\n          \u003Cdiv>\n            \u003Cspan class=\"font-bold\">{{ userName }}\u003C/span>\n            \u003Cspan v-if=\"isVerified\" class=\"text-blue-500 ml-1\">✓\u003C/span>\n            \u003Cp class=\"text-gray-500\">@{{ userHandle }}\u003C/p>\n          \u003C/div>\n        \u003C/div>\n        \u003C!-- 内容 -->\n        \u003Cp class=\"mb-3 whitespace-pre-wrap\">{{ text }}\u003C/p>\n        \u003C!-- 图片 -->\n        \u003Cdiv v-if=\"photos?.length\" class=\"mb-3 rounded-xl overflow-hidden\">\n          \u003Cimg v-for=\"photo in photos\" :key=\"photo.url\" :src=\"photo.proxiedUrl\" class=\"w-full\">\n        \u003C/div>\n        \u003C!-- 底部 -->\n        \u003Cdiv class=\"flex items-center gap-4 text-gray-500 text-sm\">\n          \u003Cspan>{{ datetime }}\u003C/span>\n          \u003Cspan>{{ repliesFormatted }} 条回复\u003C/span>\n          \u003Cspan>{{ likesFormatted }} 赞\u003C/span>\n        \u003C/div>\n      \u003C/div>\n    \u003C/template>\n\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"animate-pulse bg-gray-100 rounded-xl p-4 max-w-lg\">\n        加载推文中...\n      \u003C/div>\n    \u003C/template>\n\n    \u003Ctemplate #error>\n      \u003Cdiv class=\"bg-red-50 border border-red-200 rounded-xl p-4 max-w-lg\">\n        加载推文失败\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptXEmbed>\n\u003C/template>",{"id":2231,"title":1039,"titles":2232,"content":2233,"level":320,"path":2231,"to":2231,"label":1039},"/scripts/content/x-embed#props",[204,2223],"ScriptXEmbed 组件接受以下属性： 属性类型默认值描述tweetIdstring必填要嵌入的推文 IDapiEndpointstring/api/_scripts/x-embed获取推文数据的自定义 API 端点imageProxyEndpointstring/api/_scripts/x-embed-image代理图片的自定义端点rootAttrsHTMLAttributes{}根元素属性",{"id":2235,"title":2139,"titles":2236,"content":2237,"level":320,"path":2235,"to":2235,"label":2139},"/scripts/content/x-embed#插槽-props",[204,2223],"默认插槽接收以下 props： interface SlotProps {\n  // 原始数据\n  tweet: XEmbedTweetData\n  // 用户信息\n  userName: string\n  userHandle: string\n  userAvatar: string // 代理 URL\n  userAvatarOriginal: string // X 原始 URL\n  isVerified: boolean\n  // 推文内容\n  text: string\n  // 格式化后数据\n  datetime: string // \"12:47 PM · Feb 5, 2024\"\n  createdAt: Date\n  likes: number\n  likesFormatted: string // \"1.2K\"\n  replies: number\n  repliesFormatted: string // \"234\"\n  // 媒体资源\n  photos?: Array\u003C{\n    url: string\n    proxiedUrl: string\n    width: number\n    height: number\n  }>\n  video?: {\n    poster: string\n    posterProxied: string\n    variants: Array\u003C{ type: string; src: string }>\n  }\n  // 链接\n  tweetUrl: string\n  userUrl: string\n  // 引用推文\n  quotedTweet?: XEmbedTweetData\n  // 回复上下文\n  isReply: boolean\n  replyToUser?: string\n  // 辅助函数\n  proxyImage: (url: string) => string\n}",{"id":2239,"title":2144,"titles":2240,"content":2241,"level":320,"path":2239,"to":2239,"label":2144},"/scripts/content/x-embed#命名插槽",[204,2223],"插槽描述default主内容，带插槽 propsloading获取推文数据时展示error推文数据获取失败时展示，接收 { error }",{"id":2243,"title":609,"titles":2244,"content":2245,"level":314,"path":2243,"to":2243,"label":609},"/scripts/content/x-embed#工作原理",[204],"服务器端获取：在 SSR 期间，从 cdn.syndication.twimg.com 获取推文数据图片代理：所有图片地址均重写为通过 /api/_scripts/x-embed-image 代理缓存：响应在服务器层缓存 10 分钟无客户端 API 调用：用户浏览器不会直接访问 X 此方案灵感来源于 Cloudflare Zaraz 的嵌入实现。",{"id":2247,"title":2158,"titles":2248,"content":2249,"level":314,"path":2247,"to":2247,"label":2158},"/scripts/content/x-embed#隐私优势",[204],"不加载第三方 JavaScriptX 不设置任何 Cookies无浏览器到 X 的直接通信用户 IP 不会泄露给 X所有内容均从你的域名提供 html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"id":209,"title":208,"titles":2251,"content":2252,"level":308,"path":209,"to":209,"label":208},[],"在您的 Nuxt 应用中展示性能优化的 YouTube 视频。 YouTube 是一个视频托管平台，允许您上传和分享视频。 Nuxt Scripts 提供了 useScriptYouTubePlayer 组合函数和无头（headless）的 ScriptYouTubePlayer 组件，用于与 YouTube 播放器进行交互。",{"id":2254,"title":1964,"titles":2255,"content":2256,"level":314,"path":2254,"to":2254,"label":1964},"/scripts/content/youtube-player#类型",[208],"要使用带有完整 TypeScript 支持的 YouTube，您需要安装 @types/youtube 依赖。 pnpm add -D @types/youtube",{"id":2258,"title":2259,"titles":2260,"content":2261,"level":314,"path":2258,"to":2258,"label":2259},"/scripts/content/youtube-player#scriptyoutubeplayer","ScriptYouTubePlayer",[208],"ScriptYouTubePlayer 组件是基于 useScriptYouTubePlayer 组合函数的封装。它提供了一种简单的方法来在您的 Nuxt 应用中嵌入 YouTube 视频。 它通过利用 元素事件触发器 进行性能优化，仅在特定元素发生事件时加载 YouTube 播放器。 默认情况下，它会在 mousedown 事件时加载。",{"id":2263,"title":1979,"titles":2264,"content":2265,"level":320,"path":2263,"to":2263,"label":1979},"/scripts/content/youtube-player#演示",[208,2259],"\u003Cscript setup lang=\"ts\">\nconst isLoaded = ref(false)\nconst isPlaying = ref(false)\nconst video = ref()\nasync function play() {\n  await video.value.player.playVideo()\n}\nfunction stateChange(event) {\n  isPlaying.value = event.data === 1\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv class=\"flex items-center justify-center p-5\">\n      \u003CScriptYouTubePlayer ref=\"video\" video-id=\"d_IFKP1Ofq0\" @ready=\"isLoaded = true\" @state-change=\"stateChange\">\n        \u003Ctemplate #awaitingLoad>\n          \u003Cdiv class=\"absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 h-[48px] w-[68px]\">\n            \u003Csvg height=\"100%\" version=\"1.1\" viewBox=\"0 0 68 48\" width=\"100%\">\u003Cpath d=\"M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z\" fill=\"#f00\" />\u003Cpath d=\"M 45,24 27,14 27,34\" fill=\"#fff\" />\u003C/svg>\n          \u003C/div>\n        \u003C/template>\n      \u003C/ScriptYouTubePlayer>\n    \u003C/div>\n    \u003Cdiv class=\"text-center\">\n      \u003CUAlert v-if=\"!isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"点击以加载\" description=\"点击视频将加载 Youtube iframe 并开始播放视频。\" />\n      \u003CUButton v-if=\"isLoaded && !isPlaying\" @click=\"play\">\n        播放视频\n      \u003C/UButton>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>",{"id":2267,"title":1039,"titles":2268,"content":2269,"level":320,"path":2267,"to":2267,"label":1039},"/scripts/content/youtube-player#props",[208,2259],"ScriptYouTubePlayer 组件接受以下 props： trigger：加载 YouTube 播放器的触发事件。默认是 mousedown。欲了解更多信息，请参阅 元素事件触发器。placeholderAttrs：占位图片的属性。默认是 { loading: 'lazy' }。aboveTheFold：优化首屏内容的占位图片。默认是 false。placeholderObjectFit：占位图片的 object-fit CSS 属性。默认是 cover。对非16:9视频（如 YouTube Shorts）很有用。 playerVars prop 支持所有来自 YouTube IFrame Player API 的脚本选项，请参考 支持的参数 以获取完整文档。 export interface YouTubeProps {\n  // YouTube 播放器\n  videoId: string\n  playerVars?: YT.PlayerVars\n  width?: number\n  height?: number\n  placeholderObjectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down'\n}",{"id":2271,"title":2272,"titles":2273,"content":2274,"level":320,"path":2271,"to":2271,"label":2272},"/scripts/content/youtube-player#隐私","隐私",[208,2259],"\u003CYoutubePlayer> 组件默认隐私友好，视频托管地址设置为 https://www.youtube-nocookie.com。 若要修改此行为，可以将 host prop 设置为 https://www.youtube.com。 \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\" :player-options=\"{ host: 'https://www.youtube.com' }\" />",{"id":2276,"title":2277,"titles":2278,"content":2279,"level":320,"path":2276,"to":2276,"label":2277},"/scripts/content/youtube-player#占位符","占位符",[208,2259],"YouTube 播放器的占位图片是 1280x720 大小的 webp，默认启用懒加载。 若想修改占位符大小，可以设置 thumbnailSize prop；如果您更喜欢使用 jpg 格式，可以将 webp prop 设为 false。 \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\" thumbnail-size=\"maxresdefault\" /> 如果您需要对占位符进行精细控制，可以设置 placeholderAttrs prop，或使用 #placeholder 插槽完全覆盖。",{"id":2281,"title":2282,"titles":2283,"content":2284,"level":401,"path":2281,"to":2281,"label":2282},"/scripts/content/youtube-player#提前加载","提前加载",[208,2259,2277],"如果您的视频处于首屏位置，请调整此行为，或考虑使用 #placeholder 插槽自定义占位图片。 \u003CScriptYouTubePlayer above-the-fold />\n\u003CScriptYouTubePlayer>\n  \u003Ctemplate #placeholder=\"{ placeholder }\">\n    \u003Cimg :src=\"placeholder\" alt=\"视频占位符\">\n  \u003C/template>\n\u003C/ScriptYouTubePlayer>",{"id":2286,"title":1518,"titles":2287,"content":2288,"level":320,"path":2286,"to":2286,"label":1518},"/scripts/content/youtube-player#组件-api",[208,2259],"请查看 Facade 组件 API 获取完整的 props、事件和插槽说明。",{"id":2290,"title":1049,"titles":2291,"content":2292,"level":320,"path":2290,"to":2290,"label":1049},"/scripts/content/youtube-player#事件",[208,2259],"ScriptYouTubePlayer 组件会发出所有来自 YouTube 播放器 SDK 的事件。完整文档请见 播放器事件。 const emits = defineEmits\u003C{\n  'ready': [e: YT.PlayerEvent]\n  'state-change': [e: YT.OnStateChangeEvent, target: YT.Player]\n  'playback-quality-change': [e: YT.OnPlaybackQualityChangeEvent, target: YT.Player]\n  'playback-rate-change': [e: YT.OnPlaybackRateChangeEvent, target: YT.Player]\n  'error': [e: YT.OnErrorEvent, target: YT.Player]\n  'api-change': [e: YT.PlayerEvent, target: YT.Player]\n}>()",{"id":2294,"title":1044,"titles":2295,"content":2296,"level":320,"path":2294,"to":2294,"label":1044},"/scripts/content/youtube-player#插槽",[208,2259],"由于该组件是无头设计，提供了一些插槽让您能在加载视频之前自定义播放器的内容。 default 默认插槽用于显示始终可见的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\">\n    \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n      Nuxt 视频\n    \u003C/div>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> awaitingLoad 该插槽用于显示视频加载期间的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\">\n    \u003Ctemplate #awaitingLoad>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        点击播放！\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> loading 该插槽用于显示视频加载时的内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\">\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        加载中...\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template> placeholder 该插槽用于在视频加载前显示占位图片。默认显示视频的 YouTube 缩略图。您可以自定义显示内容。 \u003Ctemplate>\n  \u003CScriptYouTubePlayer video-id=\"d_IFKP1Ofq0\">\n    \u003Ctemplate #placeholder=\"{ placeholder }\">\n      \u003Cimg :src=\"placeholder\" alt=\"视频占位符\">\n    \u003C/template>\n  \u003C/ScriptYouTubePlayer>\n\u003C/template>",{"id":2298,"title":2299,"titles":2300,"content":2301,"level":314,"path":2298,"to":2298,"label":2299},"/scripts/content/youtube-player#usescriptyoutubeplayer","useScriptYouTubePlayer",[208],"useScriptYouTubePlayer 组合函数让您可以更细粒度地控制 YouTube 播放器 SDK。它提供了一种加载 YouTube 播放器 SDK 并以编程方式交互的方式。 export function useScriptYouTubePlayer\u003CT extends YouTubePlayerApi>(_options?: YouTubePlayerInput) {} 请参阅 注册脚本 指南，了解更多高级用法。",{"id":2303,"title":2304,"titles":2305,"content":2306,"level":320,"path":2303,"to":2303,"label":2304},"/scripts/content/youtube-player#youtubeplayerapi","YouTubePlayerApi",[208,2299],"/// \u003Creference types=\"youtube\" />\nexport interface YouTubePlayerApi {\n  YT: typeof YT\n}",{"id":2308,"title":1266,"titles":2309,"content":2310,"level":314,"path":2308,"to":2308,"label":1266},"/scripts/content/youtube-player#示例",[208],"加载 YouTube 播放器 SDK 并以编程方式与之交互。 \u003Cscript setup lang=\"ts\">\nconst video = ref()\nconst { onLoaded } = useScriptYouTubePlayer()\n\nconst player = ref(null)\nonLoaded(async ({ YT }) => {\n  // 我们需要等待内部 YouTube API 准备好\n  const YouTube = await YT\n  await new Promise\u003Cvoid>((resolve) => {\n    if (typeof YT.Player === 'undefined')\n      YouTube.ready(resolve)\n    else\n      resolve()\n  })\n  // 加载 API\n  player.value = new YT.Player(video.value, {\n    videoId: 'd_IFKP1Ofq0'\n  })\n})\nfunction play() {\n  player.value?.playVideo()\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv ref=\"video\" />\n    \u003Cbutton @click=\"play\">\n      播放\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .skSwn, html code.shiki .skSwn{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s9JP1, html code.shiki .s9JP1{--shiki-light:#22863A;--shiki-light-font-style:inherit;--shiki-default:#22863A;--shiki-default-font-style:inherit;--shiki-dark:#F07178;--shiki-dark-font-style:italic}html pre.shiki code .s1R3m, html code.shiki .s1R3m{--shiki-light:#6F42C1;--shiki-light-font-style:inherit;--shiki-default:#6F42C1;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .sV6QL, html code.shiki .sV6QL{--shiki-light:#032F62;--shiki-light-font-style:inherit;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .shPU9, html code.shiki .shPU9{--shiki-light:#032F62;--shiki-light-font-style:inherit;--shiki-default:#032F62;--shiki-default-font-style:inherit;--shiki-dark:#C3E88D;--shiki-dark-font-style:italic}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}",{"id":218,"title":217,"titles":2312,"content":2313,"level":308,"path":218,"to":218,"label":217},[],"在你的 Nuxt 应用中使用 Clarity。 Clarity 是微软提供的一款屏幕录制和热图工具，帮助你了解用户如何与网站交互。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptClarity，让你可以轻松地在 Nuxt 应用中集成 Clarity。 在 Nuxt 应用中全局加载 Clarity 的最简单方式是通过 Nuxt 配置。或者你也可以直接使用 useScriptClarity 组合式函数。",{"id":2315,"title":1601,"titles":2316,"content":2317,"level":314,"path":2315,"to":2315,"label":1601},"/scripts/marketing/clarity#全局加载",[217],"如果你不打算发送自定义事件，可以使用 环境覆盖 来在开发环境中禁用脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      clarity: {\n        id: 'YOUR_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        clarity: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      clarity: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        clarity: {\n          // .env 文件中\n          // NUXT_PUBLIC_SCRIPTS_CLARITY_ID=\u003Cyour-id>\n          id: '',\n        },\n      },\n    },\n  },\n})",{"id":2319,"title":2320,"titles":2321,"content":2322,"level":314,"path":2319,"to":2319,"label":2320},"/scripts/marketing/clarity#usescriptclarity","useScriptClarity",[217],"useScriptClarity 组合式函数允许你精细控制 Clarity 在你的网站上何时及如何加载。 const { proxy } = useScriptClarity({\n  id: 'YOUR_ID'\n})\n// 示例\nproxy.clarity(\"identify\", \"custom-id\", \"custom-session-id\", \"custom-page-id\", \"friendly-name\") 请参阅 注册脚本 指南以了解更多高级用法。",{"id":2324,"title":2325,"titles":2326,"content":2327,"level":320,"path":2324,"to":2324,"label":2325},"/scripts/marketing/clarity#clarityapi","ClarityApi",[217,2320],"type ClarityFunctions = ((fn: 'start', options: { content: boolean, cookies: string[], dob: number, expire: number, projectId: string, upload: string }) => void)\n  & ((fn: 'identify', id: string, session?: string, page?: string, userHint?: string) => Promise\u003C{\n  id: string\n  session: string\n  page: string\n  userHint: string\n}>)\n  & ((fn: 'consent') => void)\n  & ((fn: 'set', key: any, value: any) => void)\n  & ((fn: 'event', value: any) => void)\n  & ((fn: 'upgrade', upgradeReason: any) => void)\n  & ((fn: string, ...args: any[]) => void)\n\nexport interface ClarityApi {\n  clarity: ClarityFunctions & {\n    q: any[]\n    v: string\n  }\n}",{"id":2329,"title":1707,"titles":2330,"content":2331,"level":320,"path":2329,"to":2329,"label":1707},"/scripts/marketing/clarity#配置-schema",[217,2320],"首次设置脚本时必须提供选项。 export const ClarityOptions = object({\n  /**\n   * Clarity 令牌。\n   */\n  id: pipe(string(), minLength(10)),\n})",{"id":2333,"title":1717,"titles":2334,"content":2335,"level":314,"path":2333,"to":2333,"label":1717},"/scripts/marketing/clarity#first-party-模式",[217],"该脚本支持 First-Party 模式，此模式通过你的域名路由所有流量，以提升隐私性及绕过广告拦截。 当通过 scripts.firstParty: true 全局启用时，该脚本将： 从你的域名加载，而非 www.clarity.ms通过你的服务器路由数据/事件收集（d.clarity.ms, e.clarity.ms）对 IP 地址、语言和硬件指纹（canvas、webgl、浏览器版本）进行匿名化处理保留 User-Agent、屏幕分辨率和时区，以便生成准确的热图和设备过滤 export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      clarity: { id: 'YOUR_ID' }\n    }\n  }\n}) 如果想针对特定脚本选择退出： useScriptClarity({\n  id: 'YOUR_ID',\n  scriptOptions: {\n    firstParty: false // 直接从微软加载\n  }\n})",{"id":2337,"title":1266,"titles":2338,"content":2339,"level":314,"path":2337,"to":2337,"label":1266},"/scripts/marketing/clarity#示例",[217],"仅在生产环境使用 Clarity，同时使用 clarity 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptClarity()\n\n// 在开发环境和 SSR 中无操作\n// 在生产环境和客户端正常工作\nfunction sendConversion() {\n  proxy.clarity('event', 'conversion')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":222,"title":221,"titles":2341,"content":2342,"level":308,"path":222,"to":222,"label":221},[],"在你的 Nuxt 应用中使用 Hotjar。 Hotjar 是一款屏幕录制和热力图工具，帮助你了解用户如何与网站交互。 在你的 Nuxt 应用中，全局加载 Hotjar 最简单的方式是使用 Nuxt 配置。或者你也可以直接使用 useScriptHotjar 组合式函数。",{"id":2344,"title":1601,"titles":2345,"content":2346,"level":314,"path":2344,"to":2344,"label":1601},"/scripts/marketing/hotjar#全局加载",[221],"如果你不打算发送自定义事件，可以使用 环境覆盖 来在开发环境禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      hotjar: {\n        id: 123456, // 你的 ID\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        hotjar: {\n          id: 123456, // 你的 ID\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      hotjar: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        hotjar: {\n          id: 123456, // NUXT_PUBLIC_SCRIPTS_HOTJAR_ID\n        },\n      },\n    },\n  },\n})",{"id":2348,"title":2349,"titles":2350,"content":2351,"level":314,"path":2348,"to":2348,"label":2349},"/scripts/marketing/hotjar#usescripthotjar","useScriptHotjar",[221],"useScriptHotjar 组合式函数让你可以更细粒度地控制 Hotjar 在你的网站上何时以及如何加载。 const { proxy } = useScriptHotjar({\n  id: 123546,\n})\n// 示例\nproxy.hj('identify', 123456, {\n  name: 'John Doe',\n  email: 'john@doe.com'\n}) 请参阅 注册脚本指南 了解更多高级用法。",{"id":2353,"title":2354,"titles":2355,"content":2356,"level":320,"path":2353,"to":2353,"label":2354},"/scripts/marketing/hotjar#hotjarapi","HotjarApi",[221,2349],"export interface HotjarApi {\n  hj: ((event: 'identify', userId: string, attributes?: Record\u003Cstring, any>) => void)\n  & ((event: 'stateChange', path: string) => void)\n  & ((event: 'event', eventName: string) => void)\n  & ((event: string, arg?: string) => void)\n  & ((...params: any[]) => void) & {\n    q: any[]\n  }\n}",{"id":2358,"title":1707,"titles":2359,"content":2360,"level":320,"path":2358,"to":2358,"label":1707},"/scripts/marketing/hotjar#配置-schema",[221,2349],"首次设置脚本时必须提供选项。 export const HotjarOptions = object({\n  id: number(),\n  sv: optional(number()),\n})",{"id":2362,"title":1266,"titles":2363,"content":2364,"level":314,"path":2362,"to":2362,"label":1266},"/scripts/marketing/hotjar#示例",[221],"该脚本支持第一方模式，通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截器。 当通过 scripts.firstParty: true 全局启用时，该脚本将： 从你的域名加载而非 static.hotjar.com通过你的服务器路由配置和数据请求（vars.hotjar.com、in.hotjar.com）匿名化 IP 地址、语言和硬件指纹（canvas、webgl、浏览器版本）保留 User-Agent、屏幕分辨率和时区，以确保热力图和设备过滤的准确性 Hotjar 使用 WebSocket 连接进行会话录制数据。代理负责初始设置，但 WebSocket 连接直接连接到 Hotjar 服务器。 export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      hotjar: { id: 123456 }\n    }\n  }\n}) 若要针对该脚本选择退出： useScriptHotjar({\n  id: 123456,\n  scriptOptions: {\n    firstParty: false // 直接从 Hotjar 加载\n  }\n})",{"id":2366,"title":1266,"titles":2367,"content":2368,"level":314,"path":2366,"to":2366,"label":1266},"/scripts/marketing/hotjar#示例-1",[221],"仅在生产环境使用 Hotjar，并通过 hj 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptHotjar()\n\n// 在开发环境和 SSR 中无操作\n// 在生产环境客户端生效\nfunction sendConversion() {\n  proxy.hj('event', 'conversion')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":231,"title":230,"titles":2370,"content":2371,"level":308,"path":231,"to":231,"label":230},[],"在你的 Nuxt 应用中使用 Lemon Squeezy。 Lemon Squeezy 是一个流行的支付网关，允许你在线接受付款。 Nuxt Scripts 提供了一个 useScriptLemonSqueezy 组合式函数和一个无头门面组件 ScriptLemonSqueezy 组件，以便与 Lemon Squeezy 交互。",{"id":2373,"title":2374,"titles":2375,"content":2376,"level":314,"path":2373,"to":2373,"label":2374},"/scripts/payments/lemon-squeezy#scriptlemonsqueezy","ScriptLemonSqueezy",[230],"ScriptLemonSqueezy 组件是一个无头的门面组件，封装了 useScriptLemonSqueezy 组合式函数，提供了一种简单且性能优化的方式在你的 Nuxt 应用中加载 Lemon Squeezy。 \u003Ctemplate>\n\u003CScriptLemonSqueezy>\n  \u003CNuxtLink href=\"https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1\">\n    买我 - $9.99\n  \u003C/NuxtLink>\n\u003C/ScriptLemonSqueezy>\n\u003C/template> 它通过向组件内的所有 a 标签注入 .lemonsqueezy-button 类名，然后使用 visibility 元素事件触发器 来加载 Lemon Squeezy 脚本进行工作。",{"id":2378,"title":1979,"titles":2379,"content":2380,"level":320,"path":2378,"to":2378,"label":1979},"/scripts/payments/lemon-squeezy#演示",[230,2374],"\u003Cscript lang=\"ts\" setup>\nconst ready = ref(false)\nconst events = ref([])\n\u003C/script>\n\n\u003Ctemplate>\n\u003Cdiv class=\"not-prose w-full\">\n  \u003Cdiv class=\"flex items-center justify-center p-5\">\n    \u003CScriptLemonSqueezy @lemon-squeezy-event=\"e => events.push(e)\" @ready=\"ready = true\">\n      \u003CUButton to=\"https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1\" class=\"block mb-3\">\n        买我 - $9.99\n      \u003C/UButton>\n      \u003CUButton to=\"https://harlantest.lemonsqueezy.com/buy/76bbfa74-a81a-4111-8449-4f5ad564ed76?embed=1\" class=\"block\">\n        买我 - 想付多少就付多少\n      \u003C/UButton>\n    \u003C/ScriptLemonSqueezy>\n  \u003C/div>\n  \u003Cdiv>\n    \u003CUAlert v-if=\"!ready\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"Lemon Squeezy 尚未加载\" description=\"它会在 DOM 元素进入视口时加载。\" />\n    \u003CUAlert v-else color=\"green\" variant=\"soft\" title=\"Lemon Squeezy 已加载\">\n      \u003Ctemplate #description>\n      \u003Cdiv class=\"mb-2\">\n        按钮已激活，将打开模态窗口，事件跟踪：\n      \u003C/div>\n      \u003Cdiv v-for=\"event in events\" class=\"text-xs\">\n        {{ event.event }}\n      \u003C/div>\n      \u003C/template>\n    \u003C/UAlert>\n  \u003C/div>\n\u003C/div>\n\u003C/template>",{"id":2382,"title":1518,"titles":2383,"content":2384,"level":320,"path":2382,"to":2382,"label":1518},"/scripts/payments/lemon-squeezy#组件-api",[230,2374],"完整的 props、事件和插槽请参阅 门面组件 API。",{"id":2386,"title":1049,"titles":2387,"content":2388,"level":320,"path":2386,"to":2386,"label":1049},"/scripts/payments/lemon-squeezy#事件",[230,2374],"lemon-squeezy-event 由 Lemon.js 脚本发出的事件会通过此事件转发。负载是一个带有 event 和 data 键的对象。 export type LemonSqueezyEventPayload = { event: 'Checkout.Success', data: Record\u003Cstring, any> }\n  & { event: 'Checkout.ViewCart', data: Record\u003Cstring, any> }\n  & { event: 'GA.ViewCart', data: Record\u003Cstring, any> }\n  & { event: 'PaymentMethodUpdate.Mounted' }\n  & { event: 'PaymentMethodUpdate.Closed' }\n  & { event: 'PaymentMethodUpdate.Updated' }\n  & { event: string }",{"id":2390,"title":2391,"titles":2392,"content":2393,"level":314,"path":2390,"to":2390,"label":2391},"/scripts/payments/lemon-squeezy#usescriptlemonsqueezy","useScriptLemonSqueezy",[230],"useScriptLemonSqueezy 组合式函数让你可以更细粒度地控制 Lemon Squeezy SDK。它提供了一种加载 Lemon Squeezy SDK 并以编程方式与之交互的方式。 export function useScriptLemonSqueezy\u003CT extends LemonSqueezyApi>(_options?: LemonSqueezyInput) {} 请参阅 Registry Scripts 指南以了解更多高级用法。",{"id":2395,"title":2396,"titles":2397,"content":2398,"level":320,"path":2395,"to":2395,"label":2396},"/scripts/payments/lemon-squeezy#lemonsqueezyapi","LemonSqueezyApi",[230,2391],"export interface LemonSqueezyApi {\n  /**\n   * 在页面上初始化 Lemon.js。\n   * @param options - 一个带有单个属性 eventHandler 的对象，当 Lemon.js 发出事件时会调用该函数。\n   */\n  Setup: (options: {\n    eventHandler: (event: { event: 'Checkout.Success', data: Record\u003Cstring, any> }\n      & { event: 'Checkout.ViewCart', data: Record\u003Cstring, any> }\n      & { event: 'GA.ViewCart', data: Record\u003Cstring, any> }\n      & { event: 'PaymentMethodUpdate.Mounted' }\n      & { event: 'PaymentMethodUpdate.Closed' }\n      & { event: 'PaymentMethodUpdate.Updated' }\n      & { event: string }\n    ) => void\n  }) => void\n  /**\n   * 刷新页面上所有 `lemonsqueezy-button` 监听器。\n   */\n  Refresh: () => void\n\n  Url: {\n    /**\n     * 打开指定的 Lemon Squeezy URL，通常是结账或支付详情更新的覆盖层。\n     * @param url - 要打开的 URL。\n     */\n    Open: (url: string) => void\n\n    /**\n     * 关闭当前打开的 Lemon Squeezy 结账覆盖窗口。\n     */\n    Close: () => void\n  }\n  Affiliate: {\n    /**\n     * 获取联盟追踪 ID\n     */\n    GetID: () => string\n\n    /**\n     * 向指定 URL 添加联盟追踪参数\n     * @param url - 要添加联盟追踪参数的 URL。\n     */\n    Build: (url: string) => string\n  }\n  Loader: {\n    /**\n     * 显示 Lemon.js 加载器。\n     */\n    Show: () => void\n\n    /**\n     * 隐藏 Lemon.js 加载器。\n     */\n    Hide: () => void\n  }\n}",{"id":2400,"title":1266,"titles":2401,"content":2402,"level":314,"path":2400,"to":2400,"label":1266},"/scripts/payments/lemon-squeezy#示例",[230],"使用 Lemon Squeezy SDK 和支付链接。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptLemonSqueezy()\nonMounted(() => {\n  proxy.Setup()\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Ca href=\"https://harlantest.lemonsqueezy.com/buy/52a40427-36d2-4450-a514-ae80d9e1a333?embed=1\" class=\"lemonsqueezy-button\" />\n\u003C/template> html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}",{"id":235,"title":234,"titles":2404,"content":2405,"level":308,"path":235,"to":235,"label":234},[],"在您的 Nuxt 应用中使用 PayPal。 PayPal 是一个流行的支付网关，允许您在线接受付款。 Nuxt Scripts 提供了多种 PayPal 功能： useScriptPayPal 组合函数，用于加载脚本 https://www.paypal.com/sdk/js。ScriptPayPalButtons 组件，允许您在网站中嵌入 PayPal 按钮。ScriptPayPalMarks 组件，允许您在网站中嵌入 PayPal 标志。ScriptPayPalMessages 组件，允许您在网站中嵌入 PayPal 消息。",{"id":2407,"title":1964,"titles":2408,"content":2409,"level":314,"path":2407,"to":2407,"label":1964},"/scripts/payments/paypal#类型",[234],"要使用带有完整 TypeScript 支持的 PayPal，您需要安装 @paypal/paypal-js 依赖。 pnpm add -D @paypal/paypal-js",{"id":2411,"title":1979,"titles":2412,"content":2413,"level":320,"path":2411,"to":2411,"label":1979},"/scripts/payments/paypal#演示",[234,1964],"\u003Ctemplate>\n  \u003Cdiv>\n    \u003CScriptPayPalButtons\n      class=\"border border-gray-200 dark:border-gray-800 rounded-lg\"\n      :button-options=\"buttonOptions\"\n      :disabled=\"disabled\"\n    />\n    \u003Clabel>\n      禁用\n      \u003Cinput v-model=\"disabled\" type=\"checkbox\">\n    \u003C/label>\n    \u003CScriptPayPalMarks />\n    \u003CScriptPayPalMessages :messages-options=\"{ style: { color: 'white-no-border', layout: 'flex' } }\" />\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\n  import { computed, ref } from 'vue'\n  import type { PayPalButtonsComponentOptions } from '@paypal/paypal-js'\n\n  const buttonOptions = computed(() => ({\n    style: {\n      layout: 'vertical',\n      color: 'blue',\n      shape: 'rect',\n      label: 'paypal',\n    },\n    message: { amount: '10.00' },\n  } satisfies PayPalButtonsComponentOptions))\n\n  const disabled = ref(false)\n\u003C/script>",{"id":2415,"title":1834,"titles":2416,"content":2417,"level":401,"path":2415,"to":2415,"label":1834},"/scripts/payments/paypal#使用环境变量",[234,1964,1979],"如果您更喜欢使用环境变量来配置客户端 ID。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      paypal: true,\n    }\n  },\n  // 需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        paypal: {\n          clientId: '', // NUXT_PUBLIC_SCRIPTS_PAYPAL_CLIENT_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_PAYPAL_CLIENT_ID=\u003CYOUR_CLIENT_ID> html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"id":239,"title":238,"titles":2419,"content":2420,"level":308,"path":239,"to":239,"label":238},[],"在你的 Nuxt 应用中使用 Stripe。 Stripe 是一个流行的支付网关，允许你在线接受付款。 Nuxt Scripts 提供了两个 Stripe 功能： useScriptStripe 组合函数，会加载脚本 https://js.stripe.com/v3/。ScriptStripePricingTable 组件，允许你使用 https://js.stripe.com/v3/pricing-table.js 在你的网站上嵌入一个 Stripe 价格表。",{"id":2422,"title":1964,"titles":2423,"content":2424,"level":314,"path":2422,"to":2422,"label":1964},"/scripts/payments/stripe#类型",[238],"为了在使用 Stripe 时获得完整的 TypeScript 支持，你需要安装 @stripe/stripe-js 依赖。 pnpm add -D @stripe/stripe-js",{"id":2426,"title":1601,"titles":2427,"content":2428,"level":314,"path":2426,"to":2426,"label":1601},"/scripts/payments/stripe#全局加载",[238],"Stripe 建议在你的应用中全局加载其脚本，以增强防欺诈检测。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      stripe: true,\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        stripe: true,\n      }\n    }\n  }\n})",{"id":2430,"title":2431,"titles":2432,"content":2433,"level":314,"path":2430,"to":2430,"label":2431},"/scripts/payments/stripe#scriptstripepricingtable","ScriptStripePricingTable",[238],"ScriptStripePricingTable 组件允许你以优化的方式在网站上嵌入一个 Stripe 价格表。 为了提升性能，它会在价格表元素可见时加载，利用了 元素事件触发器。 你需要先创建你自己的 价格表 才能继续使用。",{"id":2435,"title":1979,"titles":2436,"content":2437,"level":320,"path":2435,"to":2435,"label":1979},"/scripts/payments/stripe#演示",[238,2431],"\u003Ctemplate>\n  \u003CScriptStripePricingTable\n    pricing-table-id=\"prctbl_1PD0MMEclFNgdHcR8t0Jop2H\"\n    publishable-key=\"pk_live_51OhXSKEclFNgdHcRNi5xBjBClxsA0alYgt6NzBwUZ880pLG88rYSCYPQqpzM3TedzNYu5g2AynKiPI5QVLYSorLJ002iD4VZIB\"\n  />\n\u003C/template>",{"id":2439,"title":1518,"titles":2440,"content":2441,"level":320,"path":2439,"to":2439,"label":1518},"/scripts/payments/stripe#组件-api",[238,2431],"完整的属性、事件和插槽请参见 Facade 组件接口。",{"id":2443,"title":1984,"titles":2444,"content":2445,"level":320,"path":2443,"to":2443,"label":1984},"/scripts/payments/stripe#属性",[238,2431],"ScriptStripePricingTable 组件接受以下属性： trigger：触发加载 Stripe 的事件。默认为 mouseover。更多信息请参见 元素事件触发器。pricing-table-id：你在 Stripe 控制台创建的价格表 ID。publishable-key：你的 Stripe 可发布密钥。client-reference-id：客户的唯一标识符。customer-email：客户的电子邮件。customer-session-client-secret：客户会话的客户端密钥。",{"id":2447,"title":2448,"titles":2449,"content":2450,"level":314,"path":2447,"to":2447,"label":2448},"/scripts/payments/stripe#usescriptstripe","useScriptStripe",[238],"useScriptStripe 组合函数让你可以精细控制 Stripe SDK。它提供了一种加载 Stripe SDK 并以编程方式与之交互的方法。 export function useScriptStripe\u003CT extends StripeApi>(_options?: StripeInput) {} 请参考 注册表脚本 指南了解更多高级用法。",{"id":2452,"title":1673,"titles":2453,"content":2454,"level":320,"path":2452,"to":2452,"label":1673},"/scripts/payments/stripe#选项",[238,2448],"export const StripeOptions = object({\n  advancedFraudSignals: optional(boolean()),\n})",{"id":2456,"title":2457,"titles":2458,"content":2459,"level":320,"path":2456,"to":2456,"label":2457},"/scripts/payments/stripe#stripeapi","StripeApi",[238,2448],"export interface StripeApi {\n  Stripe: stripe.StripeStatic\n}",{"id":2461,"title":1266,"titles":2462,"content":2463,"level":314,"path":2461,"to":2461,"label":1266},"/scripts/payments/stripe#示例",[238],"加载 Stripe SDK 并使用它创建支付元素。 \u003Cscript setup lang=\"ts\">\nconst paymentEl = ref(null)\nconst { onLoaded } = useScriptStripe()\nonMounted(() => {\n  onLoaded(({ Stripe }) => {\n    const stripe = Stripe('YOUR_STRIPE_KEY')\n    const elements = stripe.elements()\n    const paymentElement = elements.create('payment', { /* 传入选项 */ })\n    paymentElement.mount(paymentEl.value)\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv ref=\"paymentEl\" />\n\u003C/template> html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .sJFDI, html code.shiki .sJFDI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}",{"id":248,"title":247,"titles":2465,"content":2466,"level":308,"path":248,"to":248,"label":247},[],"在你的 Nuxt 应用中展示性能优化的 Crisp。 Crisp 是一个客户消息平台，让你通过聊天、邮件等方式与客户沟通。 Nuxt Scripts 提供了一个组合式函数 useScriptCrisp 和一个无头外观组件 ScriptCrisp 来与 Crisp 交互。",{"id":2468,"title":2469,"titles":2470,"content":2471,"level":314,"path":2468,"to":2468,"label":2469},"/scripts/support/crisp#scriptcrisp","ScriptCrisp",[247],"ScriptCrisp 组件是一个无头外观组件，封装了 useScriptCrisp 组合式函数，提供了一种简单且性能优化的方式，在你的 Nuxt 应用中加载 Crisp。 它通过利用元素事件触发器实现性能优化，只在特定元素事件发生时加载 Crisp。 默认情况下，它会在 click DOM 事件时加载。",{"id":2473,"title":1979,"titles":2474,"content":2475,"level":320,"path":2473,"to":2473,"label":1979},"/scripts/support/crisp#演示",[247,2469],"\u003Cscript setup lang=\"ts\">\nconst isLoaded = ref(false)\n\u003C/script>\n\n\u003Ctemplate>\n\u003Cdiv class=\"not-prose\">\n  \u003Cdiv class=\"flex items-center justify-center p-5\">\n    \u003CScriptCrisp id=\"b1021910-7ace-425a-9ef5-07f49e5ce417\" class=\"crisp\">\n      \u003Ctemplate #awaitingLoad>\n        \u003Cdiv class=\"crisp-icon\" />\n      \u003C/template>\n      \u003Ctemplate #loading>\n        \u003CScriptLoadingIndicator color=\"black\" />\n      \u003C/template>\n    \u003C/ScriptCrisp>\n  \u003C/div>\n  \u003Cdiv class=\"text-center\">\n    \u003CUAlert v-if=\"!isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"点击加载\" description=\"点击右侧按钮将加载 crisp 脚本\" />\n    \u003CUAlert v-else color=\"green\" variant=\"soft\" title=\"Crisp 已加载\" description=\"Crisp 外观组件不再显示。\" />\n  \u003C/div>\n\u003C/div>\n\u003C/template>\n\n\u003Cstyle>\n.crisp {\n  width: 54px;\n  height: 54px;\n  border-radius: 54px;\n  cursor: pointer;\n  background-color: #1972F5;\n  position: relative; /* 改为 fixed */\n  bottom: 20px;\n  right: 24px;\n  z-index: 100000;\n  box-shadow: 0 4px 10px 0 rgba(0,0,0!important,.05) !important;\n}\n.crisp-icon {\n  position: absolute;\n  top: 16px;\n  left: 11px;\n  width: 32px;\n  height: 26px;\n  background-size: contain;\n  background-repeat: no-repeat;\n  background-position: center;\n  background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwIiB3aWR0aD0iMzUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxmaWx0ZXIgaWQ9ImEiIGhlaWdodD0iMTM4LjclIiB3aWR0aD0iMTMxLjQiIHg9Ii0xNS43JSIgeT0iLTE1LjElIj48ZmVNb3JwaG9sb2d5IGluPSJTb3VyY2VBbHBoYSIgb3BlcmF0b3I9ImRpbGF0ZSIgcmFkaXVzPSIxIiByZXN1bHQ9InNoYWRvd1NwcmVhZE91dGVyMSIvPjxmZU9mZnNldCBkeT0iMSIgaW49InNoYWRvd1NwcmVhZE91dGVyMSIgcmVzdWx0PSJzaGFkb3dPZmZzZXRPdXRlcjEiLz48ZmVHYXVzc2lhbkJsdXIgaW49InNoYWRvd09mZnNldE91dGVyMSIgcmVzdWx0PSJzaGFkb3dCbHVyT3V0ZXIxIiBzdGREZXZpYXRpb249IjEiLz48ZmVDb21wb3NpdGUgaW49InNoYWRvd0JsdXJPdXRlcjEiIGluMj0iU291cmNlQWxwaGEiIG9wZXJhdG9yPSJvdXQiIHJlc3VsdD0ic2hhZG93Qmx1ck91dGVyMSIvPjxmZUNvbG9yTWF0cml4IGluPSJzaGFkb3dCbHVyT3V0ZXIxIiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwLjA3IDAiLz48L2ZpbHRlcj48cGF0aCBpZD0iYiIgZD0iTTE0LjIzIDIwLjQ2bC05LjY1IDEuMUwzIDUuMTIgMzAuMDcgMmwxLjU4IDE2LjQ2LTkuMzcgMS4wNy0zLjUgNS43Mi00LjU1LTQuOHoiLz48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIyIiB4bGluazpocmVmPSIjYiIvPjwvZz48L3N2Zz4=)!important\n}\n@media (max-height: 600px) {\n  .crisp {\n    bottom: 14px;\n    right: 14px;\n  }\n}\n\u003C/style>",{"id":2477,"title":1518,"titles":2478,"content":2479,"level":320,"path":2477,"to":2477,"label":1518},"/scripts/support/crisp#组件-api",[247,2469],"完整的属性、事件和插槽信息，请参见外观组件 API。",{"id":2481,"title":1039,"titles":2482,"content":2483,"level":320,"path":2481,"to":2481,"label":1039},"/scripts/support/crisp#props",[247,2469],"trigger：加载 crisp 的触发事件。默认是 click。详见元素事件触发器。id：Crisp ID。runtimeConfig：额外配置选项。用于配置语言环境。等同于 CRISP_RUNTIME_CONFIG。tokenId：关联会话，相当于使用 CRISP_TOKEN_ID 变量。等同于 CRISP_TOKEN_ID。cookieDomain：限制 crisp cookie 设置的域。等同于 CRISP_COOKIE_DOMAIN。cookieExpiry：cookie 过期时间（秒）。等同于 CRISP_COOKIE_EXPIRATION。 完整细节请参见配置架构。",{"id":2485,"title":2486,"titles":2487,"content":2488,"level":401,"path":2485,"to":2485,"label":2486},"/scripts/support/crisp#使用环境变量配置","使用环境变量配置",[247,2469,1039],"如果你希望通过环境变量配置 id。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      crisp: true,\n    }\n  },\n  // 需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        crisp: {\n          id: '', // 对应 NUXT_PUBLIC_SCRIPTS_CRISP_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_CRISP_ID=\u003CYOUR_ID>",{"id":2490,"title":1049,"titles":2491,"content":2492,"level":320,"path":2490,"to":2490,"label":1049},"/scripts/support/crisp#事件",[247,2469],"ScriptCrisp 组件在 crisp 加载完成时触发一个 ready 事件。 const emits = defineEmits\u003C{\n  ready: [crisp: Crisp]\n}>() \u003Cscript setup lang=\"ts\">\nfunction onReady(crisp) {\n  console.log('Crisp 已准备好', crisp)\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptCrisp @ready=\"onReady\" />\n\u003C/template>",{"id":2494,"title":1044,"titles":2495,"content":2496,"level":320,"path":2494,"to":2494,"label":1044},"/scripts/support/crisp#插槽",[247,2469],"awaitingLoad 该插槽用于在 crisp 加载时显示内容。 \u003Ctemplate>\n  \u003CScriptCrisp>\n    \u003Ctemplate #awaitingLoad>\n    \u003Cdiv style=\"width: 54px; height: 54px; border-radius: 54px; cursor: pointer; background-color: #1972F5;\">\n      聊天!\n    \u003C/div>\n    \u003C/template>\n  \u003C/ScriptCrisp>\n\u003C/template> loading 该插槽用于在 crisp 正在加载时显示内容。 提示：出于无障碍和用户体验考虑，通常建议使用 ScriptLoadingIndicator。 \u003Ctemplate>\n  \u003CScriptCrisp>\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        正在加载...\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptCrisp>\n\u003C/template>",{"id":2498,"title":2499,"titles":2500,"content":2501,"level":314,"path":2498,"to":2498,"label":2499},"/scripts/support/crisp#usescriptcrisp","useScriptCrisp",[247],"useScriptCrisp 组合式函数让你可以细粒度控制 Crisp SDK。它提供了程序加载 Crisp SDK 并进行交互的方式。 export function useScriptCrisp\u003CT extends CrispApi>(_options?: CrispInput) {} 请参阅注册脚本指南了解更多高级用法。",{"id":2503,"title":2504,"titles":2505,"content":2506,"level":320,"path":2503,"to":2503,"label":2504},"/scripts/support/crisp#配置架构","配置架构",[247,2499],"export const CrispOptions = object({\n  /**\n   * Crisp ID。\n   */\n  id: string(),\n  /**\n   * 额外配置选项。用于配置语言环境。\n   * 同 CRISP_RUNTIME_CONFIG。\n   * @see https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/language-customization/\n   */\n  runtimeConfig: optional(object({\n    locale: optional(string()),\n  })),\n  /**\n   * 关联会话，相当于使用 CRISP_TOKEN_ID 变量。\n   * 同 CRISP_TOKEN_ID。\n   * @see https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/session-continuity/\n   */\n  tokenId: optional(string()),\n  /**\n   * 限制 crisp cookie 设置的域。\n   * 同 CRISP_COOKIE_DOMAIN。\n   * @see https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/cookie-policies/\n   */\n  cookieDomain: optional(string()),\n  /**\n   * cookie 过期时间（秒）。\n   * 同 CRISP_COOKIE_EXPIRATION。\n   * @see https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/cookie-policies/#change-cookie-expiration-date\n   */\n  cookieExpiry: optional(number()),\n})",{"id":2508,"title":2509,"titles":2510,"content":2511,"level":320,"path":2508,"to":2508,"label":2509},"/scripts/support/crisp#crispapi","CrispApi",[247,2499],"export interface CrispApi {\n  push: (...args: any[]) => void\n  is: (name: 'chat:opened' | 'chat:closed' | 'chat:visible' | 'chat:hidden' | 'chat:small' | 'chat:large' | 'session:ongoing' | 'website:available' | 'overlay:opened' | 'overlay:closed' | string) => boolean\n  set: (name: 'message:text' | 'session:data' | 'session:segments' | 'session:event' | 'user:email' | 'user:phone' | 'user:nickname' | 'user:avatar' | 'user:company' | string, value: any) => void\n  get: (name: 'chat:unread:count' | 'message:text' | 'session:identifier' | 'session:data' | 'user:email' | 'user:phone' | 'user:nickname' | 'user:avatar' | 'user:company' | string) => any\n  do: (name: 'chat:open' | 'chat:close' | 'chat:toggle' | 'chat:show' | 'chat:hide' | 'helpdesk:search' | 'helpdesk:article:open' | 'helpdesk:query' | 'overlay:open' | 'overlay:close' | 'message:send' | 'message:show' | 'message:read' | 'message:thread:start' | 'message:thread:end' | 'session:reset' | 'trigger:run' | string, arg2?: any) => any\n  on: (name: 'session:loaded' | 'chat:initiated' | 'chat:opened' | 'chat:closed' | 'message:sent' | 'message:received' | 'message:compose:sent' | 'message:compose:received' | 'user:email:changed' | 'user:phone:changed' | 'user:nickname:changed' | 'user:avatar:changed' | 'website:availability:changed' | 'helpdesk:queried' | string, callback: (...args: any[]) => any) => void\n  off: (name: 'session:loaded' | 'chat:initiated' | 'chat:opened' | 'chat:closed' | 'message:sent' | 'message:received' | 'message:compose:sent' | 'message:compose:received' | 'user:email:changed' | 'user:phone:changed' | 'user:nickname:changed' | 'user:avatar:changed' | 'website:availability:changed' | 'helpdesk:queried' | string, callback: (...args: any[]) => any) => void\n  config: (options: any) => void\n  help: () => void\n  [key: string]: any\n} 更多信息，请参阅 Crisp API 文档。",{"id":2513,"title":1266,"titles":2514,"content":2515,"level":314,"path":2513,"to":2513,"label":1266},"/scripts/support/crisp#示例",[247],"加载 Crisp SDK 并通过编程方式进行交互。 \u003Cscript setup lang=\"ts\">\nconst crisp = useScriptCrisp({\n  id: 'YOUR_ID'\n})\ncrisp.set('user:nickname', 'Harlan')\ncrisp.do('chat:open')\n\u003C/script> html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}html pre.shiki code .sy1TL, html code.shiki .sy1TL{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sQZzC, html code.shiki .sQZzC{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#B2CCD6}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sJXcV, html code.shiki .sJXcV{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F78C6C}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sJtTG, html code.shiki .sJtTG{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#82AAFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s5pLV, html code.shiki .s5pLV{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#C792EA;--shiki-dark-font-style:italic}html pre.shiki code .saVZY, html code.shiki .saVZY{--shiki-light:#24292E;--shiki-light-font-style:inherit;--shiki-default:#24292E;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}",{"id":252,"title":251,"titles":2517,"content":2518,"level":308,"path":252,"to":252,"label":251},[],"在你的 Nuxt 应用中使用 Intercom。 Intercom 是一款客户消息平台，帮助你建立更好的客户关系。 Nuxt Scripts 提供了一个 useScriptIntercom 组合式函数和一个无头门面组件 ScriptIntercom 用于与 Intercom 交互。",{"id":2520,"title":2521,"titles":2522,"content":2523,"level":314,"path":2520,"to":2520,"label":2521},"/scripts/support/intercom#scriptintercom","ScriptIntercom",[251],"ScriptIntercom 组件是一个无头门面组件，封装了 useScriptIntercom 组合式函数，提供了一种简单、高性能的方式在你的 Nuxt 应用中加载 Intercom。 它通过利用 元素事件触发器 实现性能优化，仅在特定元素事件发生时才加载 Intercom。 默认情况下，它会在 click DOM 事件时加载。",{"id":2525,"title":1979,"titles":2526,"content":2527,"level":320,"path":2525,"to":2525,"label":1979},"/scripts/support/intercom#演示",[251,2521],"\u003Cscript setup lang=\"ts\">\nconst isLoaded = ref(false)\n\u003C/script>\n\n\u003Ctemplate>\n\u003Cdiv>\n  \u003CScriptIntercom @ready=\"isLoaded = true\" app-id=\"akg5rmxb\" api-base=\"https://api-iam.intercom.io\" alignment=\"left\" :horizontal-padding=\"50\" class=\"intercom\">\n    \u003Cdiv style=\"display: flex; align-items: center; justify-content: center; width: 48px; height: 48px;\">\n      \u003Csvg width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"white\" viewBox=\"0 0 28 32\">\u003Cpath d=\"M28 32s-4.714-1.855-8.527-3.34H3.437C1.54 28.66 0 27.026 0 25.013V3.644C0 1.633 1.54 0 3.437 0h21.125c1.898 0 3.437 1.632 3.437 3.645v18.404H28V32zm-4.139-11.982a.88.88 0 00-1.292-.105c-.03.026-3.015 2.681-8.57 2.681-5.486 0-8.517-2.636-8.571-2.684a.88.88 0 00-1.29.107 1.01 1.01 0 00-.219.708.992.992 0 00.318.664c.142.128 3.537 3.15 9.762 3.15 6.226 0 9.621-3.022 9.763-3.15a.992.992 0 00.317-.664 1.01 1.01 0 00-.218-.707z\" />\u003C/svg>\n    \u003C/div>\n  \u003C/ScriptIntercom>\n  \u003Cdiv class=\"text-center\">\n    \u003CUAlert v-if=\"!isLoaded\" class=\"mb-5\" size=\"sm\" color=\"blue\" variant=\"soft\" title=\"点击加载\" description=\"点击右侧按钮将加载 Intercom 脚本\" />\n    \u003CUAlert v-else color=\"green\" variant=\"soft\" title=\"Intercom 已加载\" description=\"Intercom 门面组件已不再显示。\" />\n  \u003C/div>\n\u003C/div>\n\u003C/template>\n\n\u003Cstyle>\n.intercom {\n  display: block;\n  position: relative; /* 可更改为 fixed */\n  z-index: 100000;\n  width: 48px;\n  align-items: center;\n  justify-content: center;\n  height: 48px;\n  border-radius: 50%;\n  cursor: pointer;\n  background-color: #0071b2;\n  filter: drop-shadow(rgba(0, 0, 0, 0.06) 0px 1px 6px) drop-shadow(rgba(0, 0, 0, 0.16) 0px 2px 32px);\n}\n\u003C/style>",{"id":2529,"title":1518,"titles":2530,"content":2531,"level":320,"path":2529,"to":2529,"label":1518},"/scripts/support/intercom#组件-api",[251,2521],"完整的属性、事件和插槽请参见 门面组件 API。",{"id":2533,"title":1039,"titles":2534,"content":2535,"level":320,"path":2533,"to":2533,"label":1039},"/scripts/support/intercom#props",[251,2521],"trigger：触发事件以加载 Intercom。默认是 click。详情参见 元素事件触发器。app-id：Intercom 应用 ID。api-base：Intercom API 基础 URL。name：用户姓名。email：用户邮箱。user-id：用户 ID。alignment：消息组件对齐位置，可选 left 或 right，默认 right。horizontal-padding：消息组件的水平内边距，默认 20。vertical-padding：消息组件的垂直内边距，默认 20。 完整细节请参见 配置 Schema。",{"id":2537,"title":2486,"titles":2538,"content":2539,"level":401,"path":2537,"to":2537,"label":2486},"/scripts/support/intercom#使用环境变量配置",[251,2521,1039],"如果你更倾向用环境变量配置 app ID。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      intercom: true,\n    }\n  },\n  // 你需要提供一个运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        intercom: {\n          app_id: '', // NUXT_PUBLIC_SCRIPTS_INTERCOM_APP_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_INTERCOM_APP_ID=\u003CYOUR_APP_ID>",{"id":2541,"title":1049,"titles":2542,"content":2543,"level":320,"path":2541,"to":2541,"label":1049},"/scripts/support/intercom#事件",[251,2521],"ScriptIntercom 组件在 Intercom 加载完成时会触发一个 ready 事件。 const emits = defineEmits\u003C{\n  ready: [intercom: Intercom]\n}>() \u003Cscript setup lang=\"ts\">\nfunction onReady(intercom) {\n  console.log('Intercom 已准备好', intercom)\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptIntercom @ready=\"onReady\" />\n\u003C/template>",{"id":2545,"title":2546,"titles":2547,"content":2548,"level":320,"path":2545,"to":2545,"label":2546},"/scripts/support/intercom#intercom-api","Intercom API",[251,2521],"该组件暴露了 intercom 实例，可用来访问底层 Intercom API。 \u003Cscript setup lang=\"ts\">\nconst intercomEl = ref()\nonMounted(() => {\n  intercomEl.value.intercom.do('chat:open')\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003CScriptIntercom ref=\"intercomEl\" />\n\u003C/template>",{"id":2550,"title":1044,"titles":2551,"content":2552,"level":320,"path":2550,"to":2550,"label":1044},"/scripts/support/intercom#插槽",[251,2521],"组件默认提供了最小化的 UI，仅保证功能性和可访问性。你可以通过多个插槽自由定制界面。 default 默认插槽，用于显示始终可见的内容。 awaitingLoad 当 Intercom 未加载时显示的内容。 \u003Ctemplate>\n  \u003CScriptIntercom>\n    \u003Ctemplate #awaitingLoad>\n    \u003Cdiv style=\"width: 54px; height: 54px; border-radius: 54px; cursor: pointer; background-color: #1972F5;\">\n      聊天！\n    \u003C/div>\n    \u003C/template>\n  \u003C/ScriptIntercom>\n\u003C/template> loading Intercom 加载过程中显示的内容。 提示：一般建议默认用 ScriptLoadingIndicator 以提升可访问性和用户体验。 \u003Ctemplate>\n  \u003CScriptIntercom>\n    \u003Ctemplate #loading>\n      \u003Cdiv class=\"bg-blue-500 text-white p-5\">\n        加载中...\n      \u003C/div>\n    \u003C/template>\n  \u003C/ScriptIntercom>\n\u003C/template>",{"id":2554,"title":2555,"titles":2556,"content":2557,"level":314,"path":2554,"to":2554,"label":2555},"/scripts/support/intercom#usescriptintercom","useScriptIntercom",[251],"useScriptIntercom 组合式函数允许你细粒度控制 Intercom 在你网站上的加载时机和方式。 const { proxy } = useScriptIntercom({\n  app_id: 'YOUR_APP_ID'\n})\n\n// 示例\nproxy.Intercom('show')\nproxy.Intercom('update', { name: 'John Doe' }) 请参考 脚本注册指南 了解更多高级用法。",{"id":2559,"title":2560,"titles":2561,"content":2562,"level":320,"path":2559,"to":2559,"label":2560},"/scripts/support/intercom#intercomapi","IntercomApi",[251,2555],"export interface IntercomApi {\n  Intercom: ((event: 'boot', data?: Input\u003Ctypeof IntercomOptions>) => void)\n  & ((event: 'shutdown') => void)\n  & ((event: 'update', options?: Input\u003Ctypeof IntercomOptions>) => void)\n  & ((event: 'hide') => void)\n  & ((event: 'show') => void)\n  & ((event: 'showSpace', spaceName: 'home' | 'messages' | 'help' | 'news' | 'tasks' | 'tickets' | string) => void)\n  & ((event: 'showMessages') => void)\n  & ((event: 'showNewMessage', content?: string) => void)\n  & ((event: 'onHide', fn: () => void) => void)\n  & ((event: 'onShow', fn: () => void) => void)\n  & ((event: 'onUnreadCountChange', fn: () => void) => void)\n  & ((event: 'trackEvent', eventName: string, metadata?: Record\u003Cstring, any>) => void)\n  & ((event: 'getVisitorId') => Promise\u003Cstring>)\n  & ((event: 'startTour', tourId: string | number) => void)\n  & ((event: 'showArticle', articleId: string | number) => void)\n  & ((event: 'showNews', newsItemId: string | number) => void)\n  & ((event: 'startSurvey', surveyId: string | number) => void)\n  & ((event: 'startChecklist', checklistId: string | number) => void)\n  & ((event: 'showTicket', ticketId: string | number) => void)\n  & ((event: 'showConversation', conversationId: string | number) => void)\n  & ((event: 'onUserEmailSupplied', fn: () => void) => void)\n  & ((event: string, ...params: any[]) => void)\n}",{"id":2564,"title":1707,"titles":2565,"content":2566,"level":320,"path":2564,"to":2564,"label":1707},"/scripts/support/intercom#配置-schema",[251,2555],"export const IntercomOptions = object({\n  app_id: string(),\n  api_base: optional(union([literal('https://api-iam.intercom.io'), literal('https://api-iam.eu.intercom.io'), literal('https://api-iam.au.intercom.io')])),\n  name: optional(string()),\n  email: optional(string()),\n  user_id: optional(string()),\n  // 定制消息组件\n  alignment: optional(union([literal('left'), literal('right')])),\n  horizontal_padding: optional(number()),\n  vertical_padding: optional(number()),\n})",{"id":2568,"title":1266,"titles":2569,"content":2570,"level":314,"path":2568,"to":2568,"label":1266},"/scripts/support/intercom#示例",[251],"仅在生产环境中使用 Intercom。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptIntercom()\n\n// 开发环境和 SSR 中为 noop\n// 生产环境客户端中正常工作\nfunction showIntercom() {\n  proxy.Intercom('show')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"showIntercom\">\n      与我们聊天\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sy1TL, html code.shiki .sy1TL{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sQZzC, html code.shiki .sQZzC{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#B2CCD6}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sJXcV, html code.shiki .sJXcV{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F78C6C}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .sJtTG, html code.shiki .sJtTG{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}",{"id":261,"title":260,"titles":2572,"content":2573,"level":308,"path":261,"to":261,"label":260},[],"在你的 Nuxt 应用中使用 Google Tag Manager。 Google Tag Manager 是一个标签管理系统，允许你快速且轻松地更新网站或移动应用中的标签和代码片段，例如用于流量分析和营销优化的代码。 使用 Nuxt Scripts 你可能不需要 Google Tag Manager。GTM 体积为 82kb，会降低你网站的加载速度。\nNuxt Scripts 提供许多功能，你可以轻松在 Nuxt 应用中实现它们。如果你使用 GTM 来做 Google Analytics，可以改用 useScriptGoogleAnalytics 组合函数。",{"id":2575,"title":1601,"titles":2576,"content":2577,"level":314,"path":2575,"to":2575,"label":1601},"/scripts/tracking/google-tag-manager#全局加载",[260],"如果你想避免在开发环境中加载分析脚本，可以在 Nuxt 配置中使用环境覆盖。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: {\n        id: '\u003CYOUR_ID>'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        googleTagManager: {\n          id: '\u003CYOUR_ID>',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: {\n        id: '\u003CYOUR_ID>',\n        defaultConsent: {\n          // 根据 GTM 文档，这里可以是任意字符串或数字\n          // 这里默认将所有同意类型设置为 'denied'（拒绝）\n          'ad_user_data': 'denied',\n          'ad_personalization': 'denied',\n          'ad_storage': 'denied',\n          'analytics_storage': 'denied',\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        googleTagManager: {\n          // .env 文件中\n          // NUXT_PUBLIC_SCRIPTS_GOOGLE_TAG_MANAGER_ID=\u003Cyour-id>\n          id: '',\n        },\n      },\n    },\n  },\n})",{"id":2579,"title":2580,"titles":2581,"content":2582,"level":314,"path":2579,"to":2579,"label":2580},"/scripts/tracking/google-tag-manager#usescriptgoogletagmanager","useScriptGoogleTagManager",[260],"useScriptGoogleTagManager 组合函数让你可以精细控制 Google Tag Manager 在网站上的加载时机和方式。 const { proxy } = useScriptGoogleTagManager({\n  id: 'YOUR_ID' // 仅当你未在全局配置中设置时需要传入 id\n})\n// 例如\nproxy.dataLayer.push({ event: 'conversion', value: 1 }) 请参考注册脚本指南了解更多关于 proxy 的用法。",{"id":2584,"title":2585,"titles":2586,"content":2587,"level":320,"path":2584,"to":2584,"label":2585},"/scripts/tracking/google-tag-manager#指南发送页面事件","指南：发送页面事件",[260,2580],"如果你想手动向 Google Tag Manager 发送页面事件，可以结合使用 proxy 和 useScriptEventPage 组合函数。\n该组合会在路由变更且页面标题更新后触发你提供的函数。 const { proxy } = useScriptGoogleTagManager({\n  id: 'YOUR_ID' // 仅当你未在全局配置中设置时需要传入 id\n})\n\nuseScriptEventPage(({ title, path }) => {\n  // 路由变更且标题更新后触发\n  proxy.dataLayer.push({\n    event: 'pageview',\n    title,\n    path\n  })\n})",{"id":2589,"title":2590,"titles":2591,"content":2592,"level":320,"path":2589,"to":2589,"label":2590},"/scripts/tracking/google-tag-manager#googletagmanagerapi","GoogleTagManagerApi",[260,2580],"interface GoogleTagManagerApi {\n  dataLayer: Record\u003Cstring, any>[]\n  google_tag_manager: GoogleTagManager\n}",{"id":2594,"title":2595,"titles":2596,"content":2597,"level":320,"path":2594,"to":2594,"label":2595},"/scripts/tracking/google-tag-manager#配置模式-config-schema","配置模式 (Config Schema)",[260,2580],"首次设置该脚本时必须提供配置选项。 /**\n * GTM 配置选项，附带详细文档说明\n */\nexport const GoogleTagManagerOptions = object({\n    /** GTM 容器 ID（格式：GTM-XXXXXX） */\n    id: string(),\n\n    /** 可选的数据层变量名 */\n    l: optional(string()),\n\n    /** 针对特定环境容器版本的认证令牌 */\n    auth: optional(string()),\n\n    /** 预览环境名称 */\n    preview: optional(string()),\n\n    /** 值为 true 时强制 GTM cookie 优先 */\n    cookiesWin: optional(union([boolean(), literal('x')])),\n\n    /** 值为 true 时开启调试模式 */\n    debug: optional(union([boolean(), literal('x')])),\n\n    /** 是否禁用个性化广告功能，值为 true 时禁用 */\n    npa: optional(union([boolean(), literal('1')])),\n\n    /** 自定义 dataLayer 名称（替代属性 \"l\"） */\n    dataLayer: optional(string()),\n\n    /** 环境专用容器的环境名称 */\n    envName: optional(string()),\n\n    /** 分析请求的引用策略 */\n    authReferrerPolicy: optional(string()),\n    \n    /** GTM 默认同意设置 */\n    defaultConsent: optional(record(string(), union([string(), number()]))),\n  })",{"id":2599,"title":2600,"titles":2601,"content":2602,"level":320,"path":2599,"to":2599,"label":2600},"/scripts/tracking/google-tag-manager#选项类型","选项类型",[260,2580],"type GoogleTagManagerInput = typeof GoogleTagManagerOptions & { onBeforeGtmStart?: (gtag: Gtag) => void }",{"id":2604,"title":1266,"titles":2605,"content":330,"level":314,"path":2604,"to":2604,"label":1266},"/scripts/tracking/google-tag-manager#示例",[260],{"id":2607,"title":2608,"titles":2609,"content":2610,"level":320,"path":2607,"to":2607,"label":2608},"/scripts/tracking/google-tag-manager#服务器端-gtm-设置","服务器端 GTM 设置",[260,1266],"服务器端 GTM 将标签执行转移到服务器端，提升隐私、性能（约快 500ms）并绕过广告拦截器。 前提条件： 服务器端 GTM 容器、主机服务（Cloud Run / Docker）和自定义域名。",{"id":2612,"title":2613,"titles":2614,"content":2615,"level":401,"path":2612,"to":2612,"label":2613},"/scripts/tracking/google-tag-manager#配置","配置",[260,1266,2608],"用你的自定义域覆盖脚本源地址： // nuxt.config.ts\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleTagManager: {\n        id: 'GTM-XXXXXX',\n        scriptInput: {\n          src: 'https://gtm.example.com/gtm.js'\n        }\n      }\n    }\n  }\n}) 环境令牌（auth、preview）可在 GTM 路径：管理员 > 环境 > 获取代码段找到。",{"id":2617,"title":697,"titles":2618,"content":2619,"level":401,"path":2617,"to":2617,"label":697},"/scripts/tracking/google-tag-manager#故障排查",[260,1266,2608],"问题原因解决方案脚本被广告拦截器阻止自定义域名被识别为跟踪器使用不明显的子域名（避免使用 gtm、analytics、tracking）Safari 中 cookie 7 天后过期ITP 将子域名视作第三方使用同源设置或实现 cookie 保持机制预览模式不可用缺少或错误的 auth/preview 令牌从 GTM 管理员 > 环境中复制令牌发生 CORS 错误服务器容器配置不正确确保服务器容器允许来自你域名的请求gtm.js 返回 404路径映射错误检查 CDN/代理是否将 /gtm.js 正确路由至容器 基础设施设置请参考 Cloud Run 或 Docker 指南。",{"id":2621,"title":2622,"titles":2623,"content":2624,"level":320,"path":2621,"to":2621,"label":2622},"/scripts/tracking/google-tag-manager#基础用法","基础用法",[260,1266],"仅在生产环境使用 Google Tag Manager，并通过 dataLayer 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptGoogleTagManager()\n\n// 在开发或 SSR 中不执行任何操作\n// 仅在生产客户端正常工作\nproxy.dataLayer.push({ event: 'conversion-step', value: 1 })\nfunction sendConversion() {\n  proxy.dataLayer.push({ event: 'conversion', value: 1 })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template>",{"id":2626,"title":54,"titles":2627,"content":2628,"level":314,"path":2626,"to":2626,"label":54},"/scripts/tracking/google-tag-manager#第一方模式",[260],"该脚本支持第一方模式，通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截器。 当你在全局通过 scripts.firstParty: true 启用时，该脚本将： 从你的域名加载而非 www.googletagmanager.com通过你的服务器路由所有 GTM 请求无隐私匿名处理（仅容器脚本加载 — 这些请求中不包含用户数据） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      googleTagManager: { id: 'GTM-XXXXXX' }\n    }\n  }\n}) 若想对该脚本特定取消第一方模式： useScriptGoogleTagManager({\n  id: 'GTM-XXXXXX',\n  scriptOptions: {\n    firstParty: false // 直接从 Google 加载\n  }\n})",{"id":2630,"title":2631,"titles":2632,"content":2633,"level":314,"path":2630,"to":2630,"label":2631},"/scripts/tracking/google-tag-manager#gtm-启动前的配置","GTM 启动前的配置",[260],"useScriptGoogleTagManager 会自动初始化 Google Tag Manager，即自动触发 js、config 和 gtm.start 事件。 如果你需要在 GTM 启动前做配置，比如设置同意模式，你有两个选项：",{"id":2635,"title":2636,"titles":2637,"content":2638,"level":320,"path":2635,"to":2635,"label":2636},"/scripts/tracking/google-tag-manager#选项-1在-nuxtconfig-中使用-defaultconsent推荐","选项 1：在 nuxt.config 中使用 defaultConsent（推荐）",[260,2631],"如果你在 nuxt.config 中配置 GTM，使用 defaultConsent 选项。请参考上文的默认同意模式示例。",{"id":2640,"title":2641,"titles":2642,"content":2643,"level":320,"path":2640,"to":2640,"label":2641},"/scripts/tracking/google-tag-manager#选项-2使用-onbeforegtmstart-回调函数","选项 2：使用 onBeforeGtmStart 回调函数",[260,2631],"如果你直接在组件中调用 useScriptGoogleTagManager （带 ID，非全局配置），使用 onBeforeGtmStart 钩子，该钩子会在推送 gtm.start 事件之前执行。 onBeforeGtmStart 仅在你直接传入 GTM ID 调用 useScriptGoogleTagManager 时生效，全局配置（nuxt.config）时无效。全局配置请使用 defaultConsent 选项。 试试 StackBlitz 上的Cookie 同意示例或细粒度同意示例。",{"id":2645,"title":2646,"titles":2647,"content":2648,"level":401,"path":2645,"to":2645,"label":2646},"/scripts/tracking/google-tag-manager#同意模式-v2-信号","同意模式 v2 信号",[260,2631,2641],"信号用途ad_storage广告用 Cookiead_user_data发送用户数据给 Google 广告ad_personalization个性化广告（再营销）analytics_storage分析用 Cookie",{"id":2650,"title":2651,"titles":2652,"content":2653,"level":401,"path":2650,"to":2650,"label":2651},"/scripts/tracking/google-tag-manager#同意状态更新","同意状态更新",[260,2631,2641],"用户同意时调用 gtag('consent', 'update', ...)： function acceptCookies() {\n  window.gtag?.('consent', 'update', {\n    ad_storage: 'granted',\n    ad_user_data: 'granted',\n    ad_personalization: 'granted',\n    analytics_storage: 'granted',\n  })\n} 如需在用户同意之前完全阻止 GTM 加载，可配合 useScriptTriggerConsent 使用。 \u003Cscript setup lang=\"ts\">\nconst consent = useState('consent', () => 'denied')\n\nconst { proxy } = useScriptGoogleTagManager({\n  onBeforeGtmStart: (gtag) => {\n    // 设置默认同意状态为拒绝\n    gtag('consent', 'default', {\n      'ad_user_data': 'denied',\n      'ad_personalization': 'denied',\n      'ad_storage': 'denied',\n      'analytics_storage': 'denied',\n      'wait_for_update': 500,\n    })\n\n    // 如果用户已同意，更新 gtag 状态\n    if (consent.value === 'granted') {\n      gtag('consent', 'update', {\n        ad_user_data: consent.value,\n        ad_personalization: consent.value,\n        ad_storage: consent.value,\n        analytics_storage: consent.value\n      })\n    }\n  }\n})\n\n// 推送页面浏览事件到 dataLayer\nuseScriptEventPage(({ title, path }) => {\n  proxy.dataLayer.push({\n    event: 'pageview',\n    title,\n    path\n  })\n})\n\u003C/script> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sm_uT, html code.shiki .sm_uT{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#F07178}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":265,"title":264,"titles":2655,"content":2656,"level":308,"path":265,"to":265,"label":264},[],"在你的 Nuxt 应用中使用 Meta Pixel。 Meta Pixel 让你能够衡量、优化并为你的 Facebook 广告活动构建受众。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptMetaPixel，方便你在 Nuxt 应用中集成 Meta Pixel。",{"id":2658,"title":1829,"titles":2659,"content":2660,"level":320,"path":2658,"to":2658,"label":1829},"/scripts/tracking/meta-pixel#nuxt-配置设置",[264],"在你的 Nuxt 应用中全局加载 Meta Pixel 最简单的方式是通过 Nuxt 配置。或者你也可以直接使用 useScriptMetaPixel 组合式函数。 如果你不打算发送自定义事件，可以利用环境重写来在开发环境禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      metaPixel: {\n        id: 'YOUR_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        metaPixel: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})",{"id":2662,"title":1834,"titles":2663,"content":2664,"level":401,"path":2662,"to":2662,"label":1834},"/scripts/tracking/meta-pixel#使用环境变量",[264,1829],"如果你更喜欢通过环境变量配置你的 id。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      metaPixel: true,\n    }\n  },\n  // 你需要提供一个运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        metaPixel: {\n          id: '', // NUXT_PUBLIC_SCRIPTS_META_PIXEL_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_META_PIXEL_ID=\u003CYOUR_ID>",{"id":2666,"title":2667,"titles":2668,"content":2669,"level":314,"path":2666,"to":2666,"label":2667},"/scripts/tracking/meta-pixel#usescriptmetapixel","useScriptMetaPixel",[264],"useScriptMetaPixel 组合式函数让你精细控制 Meta Pixel 在你网站上的加载时机和方式。 const { proxy } = useScriptMetaPixel({\n  id: 'YOUR_ID'\n})\n// 示例\nproxy.fbq('track', 'ViewContent', {\n  content_name: 'Nuxt Pixel',\n  content_category: 'Nuxt',\n}) 请参考注册脚本指南了解更多高级用法。",{"id":2671,"title":2672,"titles":2673,"content":2674,"level":320,"path":2671,"to":2671,"label":2672},"/scripts/tracking/meta-pixel#metapixelapi","MetaPixelApi",[264,2667],"export interface MetaPixelApi {\n  fbq: FbqFns & {\n    push: FbqFns\n    loaded: boolean\n    version: string\n    queue: any[]\n  }\n  _fbq: MetaPixelApi['fbq']\n}\ntype FbqArgs =\n  | ['track', StandardEvents, EventObjectProperties?]\n  | ['trackCustom', string, EventObjectProperties?]\n  | ['trackSingle', string, StandardEvents, EventObjectProperties?]\n  | ['trackSingleCustom', string, string, EventObjectProperties?]\n  | ['init', string]\n  | ['init', number, Record\u003Cstring, any>?]\n  | ['consent', ConsentAction]\n  | [string, ...any[]]\ntype FbqFns = (...args: FbqArgs) => void\ntype StandardEvents = 'AddPaymentInfo' | 'AddToCart' | 'AddToWishlist' | 'CompleteRegistration' | 'Contact' | 'CustomizeProduct' | 'Donate' | 'FindLocation' | 'InitiateCheckout' | 'Lead' | 'Purchase' | 'Schedule' | 'Search' | 'StartTrial' | 'SubmitApplication' | 'Subscribe' | 'ViewContent'\ninterface EventObjectProperties {\n  content_category?: string\n  content_ids?: string[]\n  content_name?: string\n  content_type?: string\n  contents?: { id: string, quantity: number }[]\n  currency?: string\n  delivery_category?: 'in_store' | 'curbside' | 'home_delivery'\n  num_items?: number\n  predicted_ltv?: number\n  search_string?: string\n  status?: 'completed' | 'updated' | 'viewed' | 'added_to_cart' | 'removed_from_cart' | string\n  value?: number\n  [key: string]: any\n}\ntype ConsentAction = 'grant' | 'revoke'",{"id":2676,"title":2677,"titles":2678,"content":2679,"level":320,"path":2676,"to":2676,"label":2677},"/scripts/tracking/meta-pixel#配置结构","配置结构",[264,2667],"你必须在首次设置脚本时提供选项。 export const MetaPixelOptions = object({\n  id: number(),\n  sv: optional(number()),\n})",{"id":2681,"title":1717,"titles":2682,"content":2683,"level":314,"path":2681,"to":2681,"label":1717},"/scripts/tracking/meta-pixel#first-party-模式",[264],"此脚本支持第一方模式，通过你的域名路由所有流量，以提升隐私保护和绕过广告拦截。 通过在全局配置中启用 scripts.firstParty: true，该脚本将会： 从你的域名加载，而非 connect.facebook.net通过你的服务器路由追踪请求（/tr）全方位隐私匿名化 — IP、用户代理、语言、屏幕、时区和硬件指纹数据均被匿名化（不信任的广告网络） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      metaPixel: { id: '123456789' }\n    }\n  }\n}) 如果你想为该脚本单独禁用第一方模式： useScriptMetaPixel({\n  id: '123456789',\n  scriptOptions: {\n    firstParty: false // 直接从 Meta 加载\n  }\n})",{"id":2685,"title":1266,"titles":2686,"content":2687,"level":314,"path":2685,"to":2685,"label":1266},"/scripts/tracking/meta-pixel#示例",[264],"在生产环境中使用 Meta Pixel，并通过 fbq 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptMetaPixel()\n\n// 在开发和服务端渲染阶段无操作\n// 在生产客户端正常工作\nfunction sendConversion() {\n  proxy.fbq('trackCustom', 'conversion', {\n    value: 1,\n    currency: 'USD'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}",{"id":269,"title":268,"titles":2689,"content":2690,"level":308,"path":269,"to":269,"label":268},[],"在你的 Nuxt 应用中使用 Reddit 像素。 Reddit 像素 帮助你跟踪转化并为你的 Reddit 广告活动构建受众。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptRedditPixel，可让你轻松地在 Nuxt 应用中集成 Reddit 像素。",{"id":2692,"title":1829,"titles":2693,"content":2694,"level":320,"path":2692,"to":2692,"label":1829},"/scripts/tracking/reddit-pixel#nuxt-配置设置",[268],"在你的 Nuxt 应用中全局加载 Reddit 像素的最简单方式是使用 Nuxt 配置。或者，你也可以直接使用 useScriptRedditPixel 组合式函数。 如果你不打算发送自定义事件，可以使用 环境变量覆盖 来在开发环境中禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      redditPixel: {\n        id: 'YOUR_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        redditPixel: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})",{"id":2696,"title":1834,"titles":2697,"content":2698,"level":401,"path":2696,"to":2696,"label":1834},"/scripts/tracking/reddit-pixel#使用环境变量",[268,1829],"如果你更喜欢通过环境变量来配置你的 id。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      redditPixel: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        redditPixel: {\n          id: '', // NUXT_PUBLIC_SCRIPTS_REDDIT_PIXEL_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_REDDIT_PIXEL_ID=\u003CYOUR_ID>",{"id":2700,"title":2701,"titles":2702,"content":2703,"level":314,"path":2700,"to":2700,"label":2701},"/scripts/tracking/reddit-pixel#usescriptredditpixel","useScriptRedditPixel",[268],"useScriptRedditPixel 组合式函数让你可以精细控制 Reddit 像素在你的站点上何时以及如何加载。 const { proxy } = useScriptRedditPixel({\n  id: 'YOUR_ID'\n})\n// 示例\nproxy.rdt('track', 'Lead') 请参阅 注册脚本 指南以了解更多高级用法。",{"id":2705,"title":2706,"titles":2707,"content":2708,"level":320,"path":2705,"to":2705,"label":2706},"/scripts/tracking/reddit-pixel#redditpixelapi","RedditPixelApi",[268,2701],"export interface RedditPixelApi {\n  rdt: RdtFns & {\n    sendEvent: (rdt: RedditPixelApi['rdt'], args: unknown[]) => void\n    callQueue: unknown[]\n  }\n}\ntype RdtFns\n  = & ((event: 'init', id: string) => void)\n    & ((event: 'track', eventName: string) => void)",{"id":2710,"title":1647,"titles":2711,"content":2712,"level":320,"path":2710,"to":2710,"label":1647},"/scripts/tracking/reddit-pixel#配置模式",[268,2701],"首次设置脚本时，你必须提供选项。 export const RedditPixelOptions = object({\n  id: string(),\n})",{"id":2714,"title":54,"titles":2715,"content":2716,"level":314,"path":2714,"to":2714,"label":54},"/scripts/tracking/reddit-pixel#第一方模式",[268],"此脚本支持 第一方模式，该模式通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截器。 当全局启用 scripts.firstParty: true 时，此脚本将： 从你的域名加载，而非 alb.reddit.com通过你的服务器转发跟踪请求完全隐私匿名化 — IP、用户代理、语言、屏幕、时区和硬件指纹全部匿名化（不信任广告网络） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      redditPixel: { id: 'YOUR_ID' }\n    }\n  }\n}) 若想为此特定脚本选择退出： useScriptRedditPixel({\n  id: 'YOUR_ID',\n  scriptOptions: {\n    firstParty: false // 直接从 Reddit 加载\n  }\n})",{"id":2718,"title":1266,"titles":2719,"content":2720,"level":314,"path":2718,"to":2718,"label":1266},"/scripts/tracking/reddit-pixel#示例",[268],"仅在生产环境使用 Reddit 像素，同时使用 rdt 发送跟踪事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptRedditPixel()\n\n// 在开发环境和 SSR 中无操作\n// 仅在生产环境客户端有效\nfunction trackConversion() {\n  proxy.rdt('track', 'Lead')\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"trackConversion\">\n      跟踪转化\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":273,"title":272,"titles":2722,"content":2723,"level":308,"path":273,"to":273,"label":272},[],"在你的 Nuxt 应用中使用 Segment。 Segment 让你能够收集、清理和控制客户数据。Segment 帮助你了解客户并个性化他们的体验。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptSegment，可以轻松地在你的 Nuxt 应用中集成 Segment。",{"id":2725,"title":1829,"titles":2726,"content":2727,"level":320,"path":2725,"to":2725,"label":1829},"/scripts/tracking/segment#nuxt-配置设置",[272],"在 Nuxt 应用中全局加载 Segment 最简便的方法是使用 Nuxt 配置。或者你也可以直接使用 useScriptSegment 组合式函数。 如果你不打算发送自定义事件，可以使用环境变量覆盖来在开发环境中禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      segment: {\n        writeKey: 'YOUR_WRITE_KEY'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        segment: {\n          writeKey: 'YOUR_WRITE_KEY'\n        }\n      }\n    }\n  }\n})",{"id":2729,"title":1834,"titles":2730,"content":2731,"level":401,"path":2729,"to":2729,"label":1834},"/scripts/tracking/segment#使用环境变量",[272,1829],"如果你更倾向于使用环境变量配置你的 ID。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      segment: true,\n    }\n  },\n  // 你需要提供运行时配置来访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        segment: {\n          writeKey: '' // NUXT_PUBLIC_SCRIPTS_SEGMENT_WRITE_KEY\n        }\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_SEGMENT_WRITE_KEY=\u003CYOUR_WRITE_KEY>",{"id":2733,"title":2734,"titles":2735,"content":2736,"level":314,"path":2733,"to":2733,"label":2734},"/scripts/tracking/segment#usescriptsegment","useScriptSegment",[272],"useScriptSegment 组合式函数让你可以精细控制 Segment 在你的网站上何时以及如何加载。 const { proxy } = useScriptSegment({\n  id: 'YOUR_ID'\n})\n// 示例\nproxy.track('event', {\n  foo: 'bar'\n}) 请参阅 注册脚本 指南，了解更多高级用法。",{"id":2738,"title":2739,"titles":2740,"content":2741,"level":320,"path":2738,"to":2738,"label":2739},"/scripts/tracking/segment#segmentapi","SegmentApi",[272,2734],"interface SegmentApi {\n  track: (event: string, properties?: Record\u003Cstring, any>) => void\n  page: (name?: string, properties?: Record\u003Cstring, any>) => void\n  identify: (userId: string, traits?: Record\u003Cstring, any>, options?: Record\u003Cstring, any>) => void\n  group: (groupId: string, traits?: Record\u003Cstring, any>, options?: Record\u003Cstring, any>) => void\n  alias: (userId: string, previousId: string, options?: Record\u003Cstring, any>) => void\n  reset: () => void\n}",{"id":2743,"title":1647,"titles":2744,"content":2745,"level":320,"path":2743,"to":2743,"label":1647},"/scripts/tracking/segment#配置模式",[272,2734],"在首次设置脚本时，必须提供选项。 export const SegmentOptions = object({\n  writeKey: string(),\n  analyticsKey: optional(string()),\n})",{"id":2747,"title":54,"titles":2748,"content":2749,"level":314,"path":2747,"to":2747,"label":54},"/scripts/tracking/segment#第一方模式",[272],"此脚本支持第一方模式，该模式通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截。 当在全局开启 scripts.firstParty: true 后，此脚本将会： 从你的域名加载资源，而非 cdn.segment.com通过你的服务器代理 API 请求（api.segment.io）将用户 IP 地址匿名化到子网级别标准化 User-Agent 并将设备指纹信息通用化到常见类别 export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      segment: { writeKey: 'YOUR_WRITE_KEY' }\n    }\n  }\n}) 如需在此脚本中选择退出： useScriptSegment({\n  writeKey: 'YOUR_WRITE_KEY',\n  scriptOptions: {\n    firstParty: false // 直接从 Segment 加载\n  }\n})",{"id":2751,"title":1266,"titles":2752,"content":2753,"level":314,"path":2751,"to":2751,"label":1266},"/scripts/tracking/segment#示例",[272],"仅在生产环境中使用 Segment，同时使用 analytics 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptSegment()\n\n// 在开发环境和 SSR 时无操作\n// 仅在生产环境客户端生效\nfunction sendConversion() {\n  proxy.track('conversion', {\n    value: 1,\n    currency: 'USD'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}",{"id":277,"title":276,"titles":2755,"content":2756,"level":308,"path":277,"to":277,"label":276},[],"在你的 Nuxt 应用中使用 Snapchat 像素。 Snapchat 像素 让你能够衡量 Snapchat 广告活动的跨设备影响。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptSnapchatPixel，方便你在 Nuxt 应用中集成 Snapchat 像素。",{"id":2758,"title":1829,"titles":2759,"content":2760,"level":320,"path":2758,"to":2758,"label":1829},"/scripts/tracking/snapchat-pixel#nuxt-配置设置",[276],"在 Nuxt 应用中全局加载 Snapchat 像素的最简单方式是使用 Nuxt 配置。或者，你也可以直接使用useScriptSnapchatPixel组合式函数。 如果你不打算发送自定义事件，可以使用环境覆盖来在开发环境禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      snapchatPixel: {\n        id: 'YOUR_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        snapchatPixel: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})",{"id":2762,"title":2486,"titles":2763,"content":2764,"level":401,"path":2762,"to":2762,"label":2486},"/scripts/tracking/snapchat-pixel#使用环境变量配置",[276,1829],"如果你更喜欢通过环境变量来配置你的 ID。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      snapchatPixel: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        snapchatPixel: {\n          id: '', // NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_SNAPCHAT_PIXEL_ID=\u003CYOUR_ID>",{"id":2766,"title":2767,"titles":2768,"content":2769,"level":314,"path":2766,"to":2766,"label":2767},"/scripts/tracking/snapchat-pixel#usescriptsnapchatpixel","useScriptSnapchatPixel",[276],"useScriptSnapchatPixel 组合式函数允许你精细控制 Snapchat 像素在你的网站上何时以及如何加载。 const { proxy } = useScriptSnapchatPixel({\n  id: 'YOUR_ID',\n  user_email: 'USER_EMAIL'\n})\n// 示例\nproxy.snaptr('track', 'PURCHASE', {\n  currency: 'USD',\n  price: 120.10,\n  transaction_id: '11111'\n}) 请参阅注册脚本指南，了解更多高级用法。",{"id":2771,"title":2772,"titles":2773,"content":2774,"level":320,"path":2771,"to":2771,"label":2772},"/scripts/tracking/snapchat-pixel#snapchatpixelapi","SnapchatPixelApi",[276,2767],"export interface SnapPixelApi {\n  snaptr: SnapTrFns & {\n    push: SnapTrFns\n    loaded: boolean\n    version: string\n    queue: any[]\n  }\n  _snaptr: SnapPixelApi['snaptr']\n  handleRequest?: SnapTrFns\n}\ntype StandardEvents = 'PAGE_VIEW' | 'VIEW_CONTENT' | 'ADD_CART' | 'SIGN_UP' | 'SAVE' | 'START_CHECKOUT' | 'APP_OPEN' | 'ADD_BILLING' | 'SEARCH' | 'SUBSCRIBE' | 'AD_CLICK' | 'AD_VIEW' | 'COMPLETE_TUTORIAL' | 'LEVEL_COMPLETE' | 'INVITE' | 'LOGIN' | 'SHARE' | 'RESERVE' | 'ACHIEVEMENT_UNLOCKED' | 'ADD_TO_WISHLIST' | 'SPENT_CREDITS' | 'RATE' | 'START_TRIAL' | 'LIST_VIEW'\ntype SnapTrFns =\n  ((event: 'track', eventName: StandardEvents | '', data?: EventObjectProperties) => void) &\n  ((event: 'init', id: string, data?: Record\u003Cstring, any>) => void) &\n  ((event: 'init', id: string, data?: InitObjectProperties) => void) &\n  ((event: string, ...params: any[]) => void)\ninterface EventObjectProperties {\n  price?: number\n  client_dedup_id?: string\n  currency?: string\n  transaction_id?: string\n  item_ids?: string[]\n  item_category?: string\n  description?: string\n  search_string?: string\n  number_items?: number\n  payment_info_available?: 0 | 1\n  sign_up_method?: string\n  success?: 0 | 1\n  brands?: string[]\n  delivery_method?: 'in_store' | 'curbside' | 'delivery'\n  customer_status?: 'new' | 'returning' | 'reactivated'\n  event_tag?: string\n  [key: string]: any\n}\ninterface InitObjectProperties {\n  user_email?: string\n  ip_address?: string\n  user_phone_number?: string\n  user_hashed_email?: string\n  user_hashed_phone_number?: string\n  firstname?: string\n  lastname?: string\n  geo_city?: string\n  geo_region?: string\n  geo_postal_code?: string\n  geo_country?: string\n  age?: string\n}",{"id":2776,"title":1707,"titles":2777,"content":2778,"level":320,"path":2776,"to":2776,"label":1707},"/scripts/tracking/snapchat-pixel#配置-schema",[276,2767],"首次设置脚本时必须提供选项。 export const SnapTrPixelOptions = object({\n  id: string(),\n  trackPageView: optional(boolean()),\n  user_email: optional(string()),\n  ip_address: optional(string()),\n  user_phone_number: optional(string()),\n  user_hashed_email: optional(string()),\n  user_hashed_phone_number: optional(string()),\n  firstname: optional(string()),\n  lastname: optional(string()),\n  geo_city: optional(string()),\n  geo_region: optional(string()),\n  geo_postal_code: optional(string()),\n  geo_country: optional(string()),\n  age: optional(string()),\n})",{"id":2780,"title":2781,"titles":2782,"content":2783,"level":314,"path":2780,"to":2780,"label":2781},"/scripts/tracking/snapchat-pixel#一方模式","一方模式",[276],"此脚本支持一方模式，通过你的域名路由所有流量，以增强隐私性并绕过广告拦截器。 当通过 scripts.firstParty: true 全局启用时，此脚本将： 从你的域名加载，而非 tr.snapchat.com通过你的服务器路由跟踪请求完全隐私匿名化 — IP、用户代理、语言、屏幕、时区和硬件指纹均匿名化（不信任的广告网络） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      snapchatPixel: { id: 'YOUR_ID' }\n    }\n  }\n}) 若要对该脚本禁用一方模式： useScriptSnapchatPixel({\n  id: 'YOUR_ID',\n  scriptOptions: {\n    firstParty: false // 直接从 Snapchat 加载\n  }\n})",{"id":2785,"title":1266,"titles":2786,"content":2787,"level":314,"path":2785,"to":2785,"label":1266},"/scripts/tracking/snapchat-pixel#示例",[276],"仅在生产环境中使用 Snapchat 像素，并通过 snaptr 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptSnapchatPixel()\n\n// 在开发环境和 SSR 中为 noop\n// 在生产客户端环境中正常工作\nfunction sendConversion() {\n  proxy.snaptr('track', 'PURCHASE', {\n    currency: 'USD',\n    price: 120.10,\n    transaction_id: '11111'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化事件\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":281,"title":280,"titles":2789,"content":2790,"level":308,"path":281,"to":281,"label":280},[],"在你的 Nuxt 应用中使用 TikTok Pixel。 TikTok Pixel 让你能够衡量、优化并构建 TikTok 广告活动的受众。 Nuxt Scripts 提供了注册脚本组合函数 useScriptTikTokPixel，轻松地在你的 Nuxt 应用中集成 TikTok Pixel。",{"id":2792,"title":1829,"titles":2793,"content":2794,"level":320,"path":2792,"to":2792,"label":1829},"/scripts/tracking/tiktok-pixel#nuxt-配置设置",[280],"在 Nuxt 应用中全局加载 TikTok Pixel 最简单的方式是使用 Nuxt 配置。你也可以直接使用 useScriptTikTokPixel 组合函数。 如果你不打算发送自定义事件，可以使用 环境配置覆盖 在开发环境中禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      tiktokPixel: {\n        id: 'YOUR_PIXEL_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        tiktokPixel: {\n          id: 'YOUR_PIXEL_ID'\n        }\n      }\n    }\n  }\n})",{"id":2796,"title":1834,"titles":2797,"content":2798,"level":401,"path":2796,"to":2796,"label":1834},"/scripts/tracking/tiktok-pixel#使用环境变量",[280,1829],"如果你更倾向于使用环境变量配置你的 id。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      tiktokPixel: true,\n    }\n  },\n  // 需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        tiktokPixel: {\n          id: '', // 对应 NUXT_PUBLIC_SCRIPTS_TIKTOK_PIXEL_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_TIKTOK_PIXEL_ID=\u003CYOUR_ID>",{"id":2800,"title":2801,"titles":2802,"content":2803,"level":314,"path":2800,"to":2800,"label":2801},"/scripts/tracking/tiktok-pixel#usescripttiktokpixel","useScriptTikTokPixel",[280],"useScriptTikTokPixel 组合函数让你能够细粒度地控制 TikTok Pixel 在你网站上的加载时机和方式。 const { proxy } = useScriptTikTokPixel({\n  id: 'YOUR_PIXEL_ID'\n})\n\n// 跟踪事件\nproxy.ttq('track', 'ViewContent', {\n  content_id: '123',\n  content_name: '产品名称',\n  value: 99.99,\n  currency: 'USD'\n}) 请参考 注册脚本 指南了解更多高级用法。",{"id":2805,"title":2806,"titles":2807,"content":2808,"level":320,"path":2805,"to":2805,"label":2806},"/scripts/tracking/tiktok-pixel#tiktokpixelapi","TikTokPixelApi",[280,2801],"export interface TikTokPixelApi {\n  ttq: TtqFns & {\n    push: TtqFns\n    loaded: boolean\n    queue: any[]\n  }\n}\n\ntype TtqFns =\n  & ((cmd: 'track', event: StandardEvents | string, properties?: EventProperties) => void)\n  & ((cmd: 'page') => void)\n  & ((cmd: 'identify', properties: IdentifyProperties) => void)\n  & ((cmd: string, ...args: any[]) => void)\n\ntype StandardEvents =\n  | 'ViewContent' | 'ClickButton' | 'Search' | 'AddToWishlist'\n  | 'AddToCart' | 'InitiateCheckout' | 'AddPaymentInfo' | 'CompletePayment'\n  | 'PlaceAnOrder' | 'Contact' | 'Download' | 'SubmitForm'\n  | 'CompleteRegistration' | 'Subscribe'",{"id":2810,"title":1707,"titles":2811,"content":2812,"level":320,"path":2810,"to":2810,"label":1707},"/scripts/tracking/tiktok-pixel#配置-schema",[280,2801],"首次设置脚本时必须提供选项。 export const TikTokPixelOptions = object({\n  id: string(),\n  trackPageView: optional(boolean()), // 默认: true\n})",{"id":2814,"title":1717,"titles":2815,"content":2816,"level":314,"path":2814,"to":2814,"label":1717},"/scripts/tracking/tiktok-pixel#first-party-模式",[280],"此脚本支持 First-Party Mode，该模式通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截器。 当在全局通过 scripts.firstParty: true 启用时，该脚本将： 从你的域名加载，而非 analytics.tiktok.com通过你的服务器路由跟踪请求完全隐私匿名化 — IP 地址、用户代理、语言、屏幕、时区和硬件指纹均被匿名化（不被信任的广告网络） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      tiktokPixel: { id: 'YOUR_PIXEL_ID' }\n    }\n  }\n}) 如果你想为此脚本单独禁用该功能： useScriptTikTokPixel({\n  id: 'YOUR_PIXEL_ID',\n  scriptOptions: {\n    firstParty: false // 直接从 TikTok 加载\n  }\n})",{"id":2818,"title":1266,"titles":2819,"content":2820,"level":314,"path":2818,"to":2818,"label":1266},"/scripts/tracking/tiktok-pixel#示例",[280],"使用 TikTok Pixel 跟踪购买事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptTikTokPixel()\n\nfunction trackPurchase() {\n  proxy.ttq('track', 'CompletePayment', {\n    content_id: 'product-123',\n    content_name: '超棒的产品',\n    value: 49.99,\n    currency: 'USD'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"trackPurchase\">\n    完成购买\n  \u003C/button>\n\u003C/template>",{"id":2822,"title":2823,"titles":2824,"content":2825,"level":314,"path":2822,"to":2822,"label":2823},"/scripts/tracking/tiktok-pixel#用户识别","用户识别",[280],"你可以识别用户进行高级匹配： const { proxy } = useScriptTikTokPixel()\n\nproxy.ttq('identify', {\n  email: 'user@example.com',\n  phone_number: '+1234567890'\n})",{"id":2827,"title":2828,"titles":2829,"content":2830,"level":314,"path":2827,"to":2827,"label":2828},"/scripts/tracking/tiktok-pixel#禁用自动页面浏览跟踪","禁用自动页面浏览跟踪",[280],"默认情况下，TikTok Pixel 会自动追踪页面浏览。若要禁用： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      tiktokPixel: {\n        id: 'YOUR_PIXEL_ID',\n        trackPageView: false\n      }\n    }\n  }\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":285,"title":284,"titles":2832,"content":2833,"level":308,"path":285,"to":285,"label":284},[],"在你的 Nuxt 应用中使用 X Pixel。 X Pixel 让你能够收集、清理并控制你的客户数据。X 帮助你了解客户并个性化他们的体验。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptXPixel，以便在你的 Nuxt 应用中轻松集成 X Pixel。",{"id":2835,"title":1829,"titles":2836,"content":2837,"level":320,"path":2835,"to":2835,"label":1829},"/scripts/tracking/x-pixel#nuxt-配置设置",[284],"在你的 Nuxt 应用中全局加载 Meta Pixel 的最简单方式是使用 Nuxt 配置。或者，你也可以直接使用 useScriptXPixel 组合式函数。 如果你不打算发送自定义事件，可以使用 环境覆盖 在开发环境中禁用该脚本。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      xPixel: {\n        id: 'YOUR_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        xPixel: {\n          id: 'YOUR_ID',\n        }\n      }\n    }\n  }\n})",{"id":2839,"title":1834,"titles":2840,"content":2841,"level":401,"path":2839,"to":2839,"label":1834},"/scripts/tracking/x-pixel#使用环境变量",[284,1829],"如果你更倾向于使用环境变量来配置你的 id。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      xPixel: true,\n    }\n  },\n  // 你需要提供运行时配置以访问环境变量\n  runtimeConfig: {\n    public: {\n      scripts: {\n        xPixel: {\n          id: '', // NUXT_PUBLIC_SCRIPTS_X_PIXEL_ID\n        },\n      },\n    },\n  },\n}) NUXT_PUBLIC_SCRIPTS_X_PIXEL_ID=\u003CYOUR_ID>",{"id":2843,"title":2844,"titles":2845,"content":2846,"level":314,"path":2843,"to":2843,"label":2844},"/scripts/tracking/x-pixel#usescriptxpixel","useScriptXPixel",[284],"useScriptXPixel 组合式函数让你可以精细控制 X Pixel 在你的网站上的加载时机和方式。 const { proxy } = useScriptXPixel({\n  id: 'YOUR_ID'\n})\n// 示例\nproxy.twq('event', '\u003CEventId>', {\n  value: 1,\n}) 请参阅注册脚本指南以了解更多高级用法。",{"id":2848,"title":2849,"titles":2850,"content":2851,"level":320,"path":2848,"to":2848,"label":2849},"/scripts/tracking/x-pixel#xpixelapi","XPixelApi",[284,2844],"export interface XPixelApi {\n  twq: TwqFns & {\n    loaded: boolean\n    version: string\n    queue: any[]\n  }\n}\ntype TwqFns =\n  ((event: 'event', eventId: string, data?: EventObjectProperties) => void)\n  & ((event: 'config', id: string) => void)\n  & ((event: string, ...params: any[]) => void)\ninterface ContentProperties {\n  content_type?: string | null\n  content_id?: string | number | null\n  content_name?: string | null\n  content_price?: string | number | null\n  num_items?: string | number | null\n  content_group_id?: string | number | null\n}\ninterface EventObjectProperties {\n  value?: string | number | null\n  currency?: string | null\n  conversion_id?: string | number | null\n  email_address?: string | null\n  phone_number?: string | null\n  contents: ContentProperties[]\n}",{"id":2853,"title":1647,"titles":2854,"content":2855,"level":320,"path":2853,"to":2853,"label":1647},"/scripts/tracking/x-pixel#配置模式",[284,2844],"首次设置该脚本时必须提供选项。 export const XPixelOptions = object({\n  id: string(),\n  version: optional(string()),\n})",{"id":2857,"title":1717,"titles":2858,"content":2859,"level":314,"path":2857,"to":2857,"label":1717},"/scripts/tracking/x-pixel#first-party-模式",[284],"该脚本支持第一方模式，可通过你的域名路由所有流量，以提升隐私保护并绕过广告拦截器。 当通过 scripts.firstParty: true 全局启用时，该脚本将会： 从你的域名加载，而非 analytics.twitter.com通过你的服务器路由跟踪请求（t.co）完全的隐私匿名化 — IP、用户代理、语言、屏幕、时区和硬件指纹均被匿名处理（针对不可信的广告网络） export default defineNuxtConfig({\n  scripts: {\n    firstParty: true,\n    registry: {\n      xPixel: { id: 'YOUR_ID' }\n    }\n  }\n}) 若你想为此特定脚本选择退出此模式： useScriptXPixel({\n  id: 'YOUR_ID',\n  scriptOptions: {\n    firstParty: false // 直接从 X/Twitter 加载\n  }\n})",{"id":2861,"title":1266,"titles":2862,"content":2863,"level":314,"path":2861,"to":2861,"label":1266},"/scripts/tracking/x-pixel#示例",[284],"仅在生产环境中使用 X Pixel，同时使用 twq 发送转化事件。 \u003Cscript setup lang=\"ts\">\nconst { proxy } = useScriptXPixel()\n\n// 在开发环境和 SSR 中无操作\n// 仅在生产环境客户端生效\nfunction sendConversion() {\n  proxy.twq('event', 'Purchase', {\n    value: 1,\n    currency: 'USD'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cbutton @click=\"sendConversion\">\n      发送转化\n    \u003C/button>\n  \u003C/div>\n\u003C/template> html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}",{"id":294,"title":293,"titles":2865,"content":2866,"level":308,"path":294,"to":294,"label":293},[],"在你的 Nuxt 应用中使用 Google reCAPTCHA v3。 Google reCAPTCHA 利用先进的风险分析技术保护你的网站免受垃圾信息和滥用。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptGoogleRecaptcha，让你能轻松在 Nuxt 应用中集成 reCAPTCHA v3。 此集成仅支持 reCAPTCHA v3（基于得分的隐形验证）。若需使用 v2 复选框，请使用标准的 reCAPTCHA 集成方式。",{"id":2868,"title":1601,"titles":2869,"content":2870,"level":320,"path":2868,"to":2868,"label":1601},"/scripts/utility/google-recaptcha#全局加载",[293],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleRecaptcha: {\n        siteKey: 'YOUR_SITE_KEY'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        googleRecaptcha: {\n          siteKey: 'YOUR_SITE_KEY'\n        }\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleRecaptcha: true,\n    }\n  },\n  runtimeConfig: {\n    public: {\n      scripts: {\n        googleRecaptcha: {\n          // .env 文件中\n          // NUXT_PUBLIC_SCRIPTS_GOOGLE_RECAPTCHA_SITE_KEY=\u003Cyour-key>\n          siteKey: '',\n        },\n      },\n    },\n  },\n})",{"id":2872,"title":2873,"titles":2874,"content":2875,"level":314,"path":2872,"to":2872,"label":2873},"/scripts/utility/google-recaptcha#usescriptgooglerecaptcha","useScriptGoogleRecaptcha",[293],"useScriptGoogleRecaptcha 组合式函数让你可以精细控制 reCAPTCHA 在你网站上的加载时机和方式。 const { proxy } = useScriptGoogleRecaptcha({\n  siteKey: 'YOUR_SITE_KEY'\n})\n\n// 执行 reCAPTCHA 并获取令牌\nproxy.grecaptcha.ready(async () => {\n  const token = await proxy.grecaptcha.execute('YOUR_SITE_KEY', { action: 'submit' })\n  // 将令牌发送到你的服务器进行验证\n}) 请参照注册脚本指南了解更多高级用法。",{"id":2877,"title":2878,"titles":2879,"content":2880,"level":320,"path":2877,"to":2877,"label":2878},"/scripts/utility/google-recaptcha#googlerecaptchaapi","GoogleRecaptchaApi",[293,2873],"export interface GoogleRecaptchaApi {\n  grecaptcha: {\n    ready: (callback: () => void) => void\n    execute: (siteKey: string, options: { action: string }) => Promise\u003Cstring>\n    enterprise?: {\n      ready: (callback: () => void) => void\n      execute: (siteKey: string, options: { action: string }) => Promise\u003Cstring>\n    }\n  }\n}",{"id":2882,"title":1647,"titles":2883,"content":2884,"level":320,"path":2882,"to":2882,"label":1647},"/scripts/utility/google-recaptcha#配置模式",[293,2873],"首次设置脚本时必须提供以下选项。 export const GoogleRecaptchaOptions = object({\n  /**\n   * 你的 reCAPTCHA 网站密钥，来自 Google reCAPTCHA 管理控制台。\n   */\n  siteKey: string(),\n  /**\n   * 使用 reCAPTCHA Enterprise 而非标准的 reCAPTCHA。\n   */\n  enterprise: optional(boolean()),\n  /**\n   * 通过 recaptcha.net 而非 google.com 加载（适用于中国）。\n   */\n  recaptchaNet: optional(boolean()),\n  /**\n   * reCAPTCHA 小部件的语言代码。\n   */\n  hl: optional(string()),\n})",{"id":2886,"title":1266,"titles":2887,"content":2888,"level":314,"path":2886,"to":2886,"label":1266},"/scripts/utility/google-recaptcha#示例",[293],"使用 reCAPTCHA v3 保护表单提交，并做服务器端验证。 \u003Cscript setup lang=\"ts\">\nconst { onLoaded } = useScriptGoogleRecaptcha()\n\nconst name = ref('')\nconst email = ref('')\nconst message = ref('')\nconst status = ref\u003C'idle' | 'loading' | 'success' | 'error'>('idle')\n\nasync function onSubmit() {\n  status.value = 'loading'\n\n  onLoaded(async ({ grecaptcha }) => {\n    // 获取 reCAPTCHA 令牌\n    const token = await grecaptcha.execute('YOUR_SITE_KEY', { action: 'contact' })\n\n    // 将表单数据和令牌发送到 API 进行验证\n    const result = await $fetch('/api/contact', {\n      method: 'POST',\n      body: {\n        token,\n        name: name.value,\n        email: email.value,\n        message: message.value\n      }\n    }).catch(() => null)\n\n    status.value = result ? 'success' : 'error'\n  })\n}\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"onSubmit\">\n    \u003Cinput v-model=\"name\" placeholder=\"姓名\" required />\n    \u003Cinput v-model=\"email\" type=\"email\" placeholder=\"邮箱\" required />\n    \u003Ctextarea v-model=\"message\" placeholder=\"消息\" required />\n    \u003Cbutton type=\"submit\" :disabled=\"status === 'loading'\">\n      {{ status === 'loading' ? '发送中...' : '提交' }}\n    \u003C/button>\n    \u003Cp v-if=\"status === 'success'\">消息已发送！\u003C/p>\n    \u003Cp v-if=\"status === 'error'\">发送失败。请重试。\u003C/p>\n  \u003C/form>\n\u003C/template>\nexport default defineEventHandler(async (event) => {\n  const { token, name, email, message } = await readBody(event)\n\n  // 验证 reCAPTCHA 令牌\n  const secretKey = process.env.RECAPTCHA_SECRET_KEY\n  const verification = await $fetch('https://www.google.com/recaptcha/api/siteverify', {\n    method: 'POST',\n    body: new URLSearchParams({\n      secret: secretKey,\n      response: token,\n    }),\n  })\n\n  if (!verification.success || verification.score \u003C 0.5) {\n    throw createError({\n      statusCode: 400,\n      message: 'reCAPTCHA 验证失败',\n    })\n  }\n\n  // 处理联系表单（发送邮件、存入数据库等）\n  console.log('联系表单提交信息:', { name, email, message, score: verification.score })\n\n  return { success: true }\n})",{"id":2890,"title":2891,"titles":2892,"content":2893,"level":314,"path":2890,"to":2890,"label":2891},"/scripts/utility/google-recaptcha#企业版","企业版",[293],"使用 reCAPTCHA Enterprise 时，将 enterprise 选项设置为 true： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleRecaptcha: {\n        siteKey: 'YOUR_SITE_KEY',\n        enterprise: true\n      }\n    }\n  }\n})",{"id":2895,"title":2896,"titles":2897,"content":2898,"level":314,"path":2895,"to":2895,"label":2896},"/scripts/utility/google-recaptcha#中国支持","中国支持",[293],"需要支持中国大陆的网站，使用 recaptchaNet: true，从 recaptcha.net 而非 google.com 加载： export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleRecaptcha: {\n        siteKey: 'YOUR_SITE_KEY',\n        recaptchaNet: true\n      }\n    }\n  }\n})",{"id":2900,"title":2901,"titles":2902,"content":2903,"level":314,"path":2900,"to":2900,"label":2901},"/scripts/utility/google-recaptcha#服务器端验证","服务器端验证",[293],"reCAPTCHA 令牌必须在服务器端进行验证。请创建一个 API 接口来校验令牌： export default defineEventHandler(async (event) => {\n  const { token } = await readBody(event)\n  const secretKey = process.env.RECAPTCHA_SECRET_KEY\n\n  const response = await $fetch('https://www.google.com/recaptcha/api/siteverify', {\n    method: 'POST',\n    body: new URLSearchParams({\n      secret: secretKey,\n      response: token,\n    }),\n  })\n\n  if (!response.success || response.score \u003C 0.5) {\n    throw createError({\n      statusCode: 400,\n      message: 'reCAPTCHA 验证失败',\n    })\n  }\n\n  return { success: true, score: response.score }\n})\nexport default defineEventHandler(async (event) => {\n  const { token } = await readBody(event)\n  const projectId = process.env.RECAPTCHA_PROJECT_ID\n  const apiKey = process.env.RECAPTCHA_API_KEY\n  const siteKey = process.env.NUXT_PUBLIC_SCRIPTS_GOOGLE_RECAPTCHA_SITE_KEY\n\n  const response = await $fetch(\n    `https://recaptchaenterprise.googleapis.com/v1/projects/${projectId}/assessments?key=${apiKey}`,\n    {\n      method: 'POST',\n      body: {\n        event: { token, siteKey, expectedAction: 'submit' },\n      },\n    }\n  )\n\n  if (!response.tokenProperties?.valid || response.riskAnalysis?.score \u003C 0.5) {\n    throw createError({\n      statusCode: 400,\n      message: 'reCAPTCHA 验证失败',\n    })\n  }\n\n  return { success: true, score: response.riskAnalysis.score }\n}) 切勿在客户端暴露你的密钥。请务必在服务器端验证令牌。",{"id":2905,"title":2906,"titles":2907,"content":2908,"level":314,"path":2905,"to":2905,"label":2906},"/scripts/utility/google-recaptcha#隐藏徽章","隐藏徽章",[293],"reCAPTCHA v3 会在网站角落显示徽章。你可以通过 CSS 将其隐藏，但必须在你的表单中包含归属声明： .grecaptcha-badge { visibility: hidden; } \u003Cp>本网站受 reCAPTCHA 保护，且受 Google 的\n  \u003Ca href=\"https://policies.google.com/privacy\">隐私政策\u003C/a> 和\n  \u003Ca href=\"https://policies.google.com/terms\">服务条款\u003C/a> 约束。\n\u003C/p>",{"id":2910,"title":2911,"titles":2912,"content":2913,"level":314,"path":2910,"to":2910,"label":2911},"/scripts/utility/google-recaptcha#测试密钥","测试密钥",[293],"Google 提供了始终通过验证的测试密钥，适用于开发环境本地测试： 密钥类型值网站密钥6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI密钥秘钥6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe 测试密钥总是返回 success: true 且得分为 0.9。详情参见 Google 常见问题。 export default defineNuxtConfig({\n  $development: {\n    scripts: {\n      registry: {\n        googleRecaptcha: {\n          siteKey: '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI'\n        }\n      }\n    }\n  }\n}) html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .sy1TL, html code.shiki .sy1TL{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#89DDFF}html pre.shiki code .sQZzC, html code.shiki .sQZzC{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#B2CCD6}",{"id":298,"title":297,"titles":2915,"content":2916,"level":308,"path":298,"to":298,"label":297},[],"在您的 Nuxt 应用中添加支持 One Tap 和个性化按钮的 Google 登录。 Google 登录 提供了一种安全且便捷的方式，让用户使用他们的 Google 账号通过 One Tap、个性化按钮及自动登录进入您的应用。 Nuxt Scripts 提供了一个注册脚本组合式函数 useScriptGoogleSignIn，可让您轻松地在 Nuxt 应用中集成 Google 登录，并实现最佳性能。",{"id":2918,"title":2919,"titles":2920,"content":330,"level":314,"path":2918,"to":2918,"label":2919},"/scripts/utility/google-sign-in#实时演示","实时演示",[297],{"id":2922,"title":2923,"titles":2924,"content":2925,"level":314,"path":2922,"to":2922,"label":2923},"/scripts/utility/google-sign-in#性能优化","性能优化",[297],"该脚本以 async 和 defer 属性加载，避免阻塞渲染，确保核心网页指标（Core Web Vitals）达到最佳。初始化会延迟到您显式调用 initialize() 时执行，赋予您完全控制 One Tap 出现时机的能力。",{"id":2927,"title":1829,"titles":2928,"content":2929,"level":314,"path":2927,"to":2927,"label":1829},"/scripts/utility/google-sign-in#nuxt-配置设置",[297],"在 Nuxt 应用中全局加载 Google 登录的最简单方法是使用 Nuxt 配置。或者您也可以直接使用 useScriptGoogleSignIn 组合式函数。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleSignIn: {\n        clientId: 'YOUR_GOOGLE_CLIENT_ID'\n      }\n    }\n  }\n})\nexport default defineNuxtConfig({\n  $production: {\n    scripts: {\n      registry: {\n        googleSignIn: {\n          clientId: 'YOUR_GOOGLE_CLIENT_ID'\n        }\n      }\n    }\n  }\n})",{"id":2931,"title":2486,"titles":2932,"content":2933,"level":320,"path":2931,"to":2931,"label":2486},"/scripts/utility/google-sign-in#使用环境变量配置",[297,1829],"export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleSignIn: true,\n    }\n  },\n  runtimeConfig: {\n    public: {\n      scripts: {\n        googleSignIn: {\n          clientId: '', // NUXT_PUBLIC_SCRIPTS_GOOGLE_SIGN_IN_CLIENT_ID\n        },\n      },\n    },\n  },\n})",{"id":2935,"title":2936,"titles":2937,"content":2938,"level":314,"path":2935,"to":2935,"label":2936},"/scripts/utility/google-sign-in#usescriptgooglesignin","useScriptGoogleSignIn",[297],"useScriptGoogleSignIn 组合函数让您可以细粒度控制何时以及如何加载 Google 登录。 const { onLoaded } = useScriptGoogleSignIn({\n  clientId: 'YOUR_GOOGLE_CLIENT_ID'\n})\n\n// 准备好后初始化\nonLoaded(({ accounts }) => {\n  accounts.id.initialize({\n    client_id: 'YOUR_GOOGLE_CLIENT_ID',\n    callback: handleCredentialResponse\n  })\n}) 请参阅注册脚本指南，了解更多高级用法。",{"id":2940,"title":2941,"titles":2942,"content":2943,"level":320,"path":2940,"to":2940,"label":2941},"/scripts/utility/google-sign-in#googlesigninapi","GoogleSignInApi",[297,2936],"export interface GoogleSignInApi {\n  accounts: {\n    id: {\n      initialize: (config: IdConfiguration) => void\n      prompt: (momentListener?: (notification: MomentNotification) => void) => void\n      renderButton: (parent: HTMLElement, options: GsiButtonConfiguration) => void\n      disableAutoSelect: () => void\n      cancel: () => void\n      revoke: (hint: string, callback: (response: RevocationResponse) => void) => void\n    }\n  }\n}",{"id":2945,"title":2946,"titles":2947,"content":2948,"level":320,"path":2945,"to":2945,"label":2946},"/scripts/utility/google-sign-in#配置参数结构","配置参数结构",[297,2936],"您可以通过以下选项配置 Google 登录脚本： export const GoogleSignInOptions = object({\n  clientId: string(),\n  autoSelect: optional(boolean()),\n  context: optional(union([literal('signin'), literal('signup'), literal('use')])),\n  useFedcmForPrompt: optional(boolean()),\n  cancelOnTapOutside: optional(boolean()),\n  uxMode: optional(union([literal('popup'), literal('redirect')])),\n  loginUri: optional(string()),\n  itpSupport: optional(boolean()),\n  allowedParentOrigin: optional(union([string(), array(string())])),\n  hd: optional(string()), // 限制登录至 Google Workspace 域\n})",{"id":2950,"title":1266,"titles":2951,"content":330,"level":314,"path":2950,"to":2950,"label":1266},"/scripts/utility/google-sign-in#示例",[297],{"id":2953,"title":2954,"titles":2955,"content":2956,"level":320,"path":2953,"to":2953,"label":2954},"/scripts/utility/google-sign-in#one-tap-登录","One Tap 登录",[297,1266],"One Tap 提示提供了简洁的登录体验： \u003Cscript setup lang=\"ts\">\nconst { onLoaded } = useScriptGoogleSignIn()\n\nfunction handleCredentialResponse(response: CredentialResponse) {\n  // 将凭证发送到后端进行验证\n  await $fetch('/api/auth/google', {\n    method: 'POST',\n    body: { credential: response.credential }\n  })\n}\n\nonMounted(() => {\n  onLoaded(({ accounts }) => {\n    accounts.id.initialize({\n      client_id: 'YOUR_CLIENT_ID',\n      callback: handleCredentialResponse,\n      context: 'signin',\n      ux_mode: 'popup',\n      use_fedcm_for_prompt: true // 使用隐私沙箱 FedCM API\n    })\n    \n    // 显示 One Tap\n    accounts.id.prompt()\n  })\n})\n\u003C/script>",{"id":2958,"title":2959,"titles":2960,"content":2961,"level":320,"path":2958,"to":2958,"label":2959},"/scripts/utility/google-sign-in#个性化按钮","个性化按钮",[297,1266],"渲染 Google 的个性化 “使用 Google 登录” 按钮： \u003Cscript setup lang=\"ts\">\nconst { onLoaded } = useScriptGoogleSignIn()\n\nfunction handleCredentialResponse(response: CredentialResponse) {\n  console.log('登录成功！', response.credential)\n}\n\nonMounted(() => {\n  onLoaded(({ accounts }) => {\n    accounts.id.initialize({\n      client_id: 'YOUR_CLIENT_ID',\n      callback: handleCredentialResponse\n    })\n    \n    const buttonDiv = document.getElementById('g-signin-button')\n    if (buttonDiv) {\n      accounts.id.renderButton(buttonDiv, {\n        type: 'standard',\n        theme: 'outline',\n        size: 'large',\n        text: 'signin_with',\n        shape: 'rectangular',\n        logo_alignment: 'left'\n      })\n    }\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv id=\"g-signin-button\" />\n\u003C/template>",{"id":2963,"title":2964,"titles":2965,"content":2966,"level":314,"path":2963,"to":2963,"label":2964},"/scripts/utility/google-sign-in#状态通知","状态通知",[297],"跟踪 One Tap 的显示状态： const { onLoaded } = useScriptGoogleSignIn()\n\nonLoaded(({ accounts }) => {\n  accounts.id.prompt((notification) => {\n    if (notification.isDisplayMoment()) {\n      if (notification.isDisplayed()) {\n        console.log('One Tap 已显示')\n      } else {\n        console.log('未显示:', notification.getNotDisplayedReason())\n      }\n    }\n    \n    if (notification.isSkippedMoment()) {\n      console.log('已跳过:', notification.getSkippedReason())\n    }\n    \n    if (notification.isDismissedMoment()) {\n      console.log('已关闭:', notification.getDismissedReason())\n    }\n  })\n})",{"id":2968,"title":2901,"titles":2969,"content":2970,"level":314,"path":2968,"to":2968,"label":2901},"/scripts/utility/google-sign-in#服务器端验证",[297],"始终在服务器端验证凭证令牌： export default defineEventHandler(async (event) => {\n  const { credential } = await readBody(event)\n  \n  // 向 Google 验证令牌\n  const response = await $fetch(`https://oauth2.googleapis.com/tokeninfo`, {\n    params: { id_token: credential }\n  })\n  \n  // 验证客户端 ID 是否匹配\n  if (response.aud !== 'YOUR_CLIENT_ID') {\n    throw createError({ statusCode: 401, message: '无效的令牌' })\n  }\n  \n  // 使用用户信息创建会话\n  const user = {\n    email: response.email,\n    name: response.name,\n    picture: response.picture,\n    sub: response.sub\n  }\n  \n  return { user }\n})",{"id":2972,"title":2973,"titles":2974,"content":2975,"level":314,"path":2972,"to":2972,"label":2973},"/scripts/utility/google-sign-in#fedcm-api-支持","FedCM API 支持",[297],"启用隐私沙箱 FedCM API 支持以增强隐私保护。2025 年 8 月起将强制采用 FedCM。 export default defineNuxtConfig({\n  scripts: {\n    registry: {\n      googleSignIn: {\n        clientId: 'YOUR_CLIENT_ID',\n        useFedcmForPrompt: true\n      }\n    }\n  }\n})",{"id":2977,"title":2978,"titles":2979,"content":2980,"level":320,"path":2977,"to":2977,"label":2978},"/scripts/utility/google-sign-in#跨域-iframe","跨域 iframe",[297,2973],"在使用 FedCM 的 One Tap 或登录按钮于跨域 iframe 中时，应为所有父 iframe 添加 allow 属性： \u003Ciframe src=\"https://your-app.com/login\" allow=\"identity-credentials-get\">\u003C/iframe> 启用 FedCM 后，无法通过 prompt_parent_id 定制 One Tap 提示的位置。",{"id":2982,"title":2983,"titles":2984,"content":2985,"level":314,"path":2982,"to":2982,"label":2983},"/scripts/utility/google-sign-in#撤销访问权限","撤销访问权限",[297],"允许用户撤销对其 Google 账户的访问权限： const { onLoaded } = useScriptGoogleSignIn()\n\nfunction revokeAccess(userId: string) {\n  onLoaded(({ accounts }) => {\n    accounts.id.revoke(userId, (response) => {\n      if (response.successful) {\n        console.log('访问权限已撤销')\n      } else {\n        console.error('撤销失败:', response.error)\n      }\n    })\n  })\n}",{"id":2987,"title":1337,"titles":2988,"content":330,"level":314,"path":2987,"to":2987,"label":1337},"/scripts/utility/google-sign-in#最佳实践",[297],{"id":2990,"title":2991,"titles":2992,"content":2993,"level":320,"path":2990,"to":2990,"label":2991},"/scripts/utility/google-sign-in#登出处理","登出处理",[297,1337],"用户登出时务必调用 disableAutoSelect()，防止自动重新认证： function signOut() {\n  // 清除应用会话\n  user.value = null\n\n  // 阻止 One Tap 自动选择此账户\n  onLoaded(({ accounts }) => {\n    accounts.id.disableAutoSelect()\n  })\n}",{"id":2995,"title":2996,"titles":2997,"content":2998,"level":320,"path":2995,"to":2995,"label":2996},"/scripts/utility/google-sign-in#限制托管域","限制托管域",[297,1337],"限制登录仅允许来自特定 Google Workspace 域的用户： accounts.id.initialize({\n  client_id: 'YOUR_CLIENT_ID',\n  callback: handleCredentialResponse,\n  hd: 'your-company.com' // 仅允许该域用户登录\n})",{"id":3000,"title":3001,"titles":3002,"content":3003,"level":314,"path":3000,"to":3000,"label":3001},"/scripts/utility/google-sign-in#本地开发配置","本地开发配置",[297],"要在本地测试 Google 登录： 打开 Google Cloud 控制台 → 凭据创建或选择一个 OAuth 2.0 客户端 ID（Web 应用类型）在 授权的 JavaScript 来源 中添加：\nhttp://localhosthttp://localhost:3000（或您的开发服务器端口）保存并复制客户端 ID Google 要求本地开发使用 http://localhost（而非 127.0.0.1）。使用弹出模式时无需重定向 URI。 然后配置环境变量： NUXT_PUBLIC_SCRIPTS_GOOGLE_SIGN_IN_CLIENT_ID=your-client-id.apps.googleusercontent.com",{"id":3005,"title":1993,"titles":3006,"content":3007,"level":314,"path":3005,"to":3005,"label":1993},"/scripts/utility/google-sign-in#指南",[297],"有关如何获取 Google 客户端 ID 及配置 OAuth 同意屏幕的详细信息，请参阅官方 Google 身份服务文档。 html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sGFTI, html code.shiki .sGFTI{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FF9CAC}html pre.shiki code .sTBSN, html code.shiki .sTBSN{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .sWpk2, html code.shiki .sWpk2{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#F07178}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sV-QU, html code.shiki .sV-QU{--shiki-light:#22863A;--shiki-default:#22863A;--shiki-dark:#F07178}html pre.shiki code .sg-iE, html code.shiki .sg-iE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#C792EA}html pre.shiki code .sSrKx, html code.shiki .sSrKx{--shiki-light:#B31D28;--shiki-light-font-style:italic;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}html pre.shiki code .sjz_z, html code.shiki .sjz_z{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#F78C6C}html pre.shiki code .swiL2, html code.shiki .swiL2{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#89DDFF}",{"id":302,"title":301,"titles":3009,"content":3010,"level":308,"path":302,"to":302,"label":301},[],"在你的 Nuxt 应用中从 NPM 加载 IIFE 脚本。",{"id":3012,"title":311,"titles":3013,"content":3014,"level":314,"path":3012,"to":3012,"label":311},"/scripts/utility/npm#背景",[301],"使用 NPM 文件时，通常会将它们作为 package.json 文件中的 node_module 依赖包含进来。然而，\n优化这些脚本的加载较为困难，需要从单独的代码块动态导入模块，\n并且仅在需要时加载。它还会拖慢构建速度，因为模块需要被转译。 useScriptNpm 注册脚本抽象了这一过程，使你可以通过一行代码加载那些已经导出为立即调用函数（IIFE）的脚本。 在许多情况下，将脚本作为 package.json 文件中的依赖可能更合理，但对于不常用或对应用不关键的脚本，\n这可以是一个很好的替代方案。 一开始，我们可以将使用此脚本视为 useHead 组合式函数的替代方案。以下代码示例展示了该抽象层次。 useScriptNpm({\n  packageName: 'js-confetti',\n  file: 'dist/js-confetti.browser.js',\n  version: '0.12.0',\n})\nuseScript('https://cdn.jsdelivr.net/npm/js-confetti@0.12.0/dist/js-confetti.browser.js')\nuseHead({\n  script: [\n    { src: 'https://cdn.jsdelivr.net/npm/js-confetti@latest/dist/js-confetti.browser.js' }\n  ]\n})",{"id":3016,"title":3017,"titles":3018,"content":3019,"level":314,"path":3016,"to":3016,"label":3017},"/scripts/utility/npm#usescriptnpm","useScriptNpm",[301],"useScriptNpm 组合式函数让你可以精细地控制你的网站上 NPM 脚本何时以及如何加载。 function useScriptNpm\u003CT extends Record\u003Cstring | symbol, any>>(_options: NpmInput) {} 请参考 注册脚本指南 了解更多进阶用法。",{"id":3021,"title":3022,"titles":3023,"content":3024,"level":320,"path":3021,"to":3021,"label":3022},"/scripts/utility/npm#npmoptions","NpmOptions",[301,3017],"export const NpmOptions = object({\n  packageName: string(),\n  file: optional(string()),\n  version: optional(string()),\n  type: optional(string()),\n})",{"id":3026,"title":1241,"titles":3027,"content":3028,"level":320,"path":3026,"to":3026,"label":1241},"/scripts/utility/npm#返回值",[301,3017],"要获取所加载脚本的类型，你需要扩展 useScriptNpm 函数的类型定义。 interface SomeApi {\n  doSomething: () => void\n}\nuseScriptNpm\u003CSomeApi>({\n  packageName: 'some-api'\n})",{"id":3030,"title":1266,"titles":3031,"content":3032,"level":314,"path":3030,"to":3030,"label":1266},"/scripts/utility/npm#示例",[301],"更多示例请参见 教程：加载 js-confetti。 html pre.shiki code .s0YkB, html code.shiki .s0YkB{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#82AAFF}html pre.shiki code .sqjlB, html code.shiki .sqjlB{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#BABED8}html pre.shiki code .sx-uw, html code.shiki .sx-uw{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#89DDFF}html pre.shiki code .sqVJQ, html code.shiki .sqVJQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#F07178}html pre.shiki code .sbw7o, html code.shiki .sbw7o{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#89DDFF}html pre.shiki code .sJnJ8, html code.shiki .sJnJ8{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swqme, html code.shiki .swqme{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#C792EA}html pre.shiki code .sryBE, html code.shiki .sryBE{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#FFCB6B}html pre.shiki code .s9nlO, html code.shiki .s9nlO{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#FFCB6B}html pre.shiki code .sc1V3, html code.shiki .sc1V3{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#89DDFF}html pre.shiki code .sgUNn, html code.shiki .sgUNn{--shiki-light:#E36209;--shiki-light-font-style:inherit;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .smL2f, html code.shiki .smL2f{--shiki-light:#D73A49;--shiki-light-font-style:inherit;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .smpaK, html code.shiki .smpaK{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#BABED8}html pre.shiki code .sBBN6, html code.shiki .sBBN6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#F07178}",{"id":3034,"title":10,"body":3035,"description":3177,"extension":3178,"head":3179,"meta":3180,"navigation":3181,"ogImage":3179,"path":11,"robots":3179,"schemaOrg":3179,"seo":3182,"sitemap":3183,"stem":12,"__hash__":3184},"docs/docs/1.getting-started/1.index.md",{"type":3036,"value":3037,"toc":3166},"minimark",[3038,3042,3045,3053,3056,3078,3080,3083,3106,3109,3112,3127,3130,3144,3146],[3039,3040,3041],"p",{},"Nuxt Scripts 在将第三方脚本整合到 Nuxt 应用中时，提升了性能、隐私和开发者体验（DX）。",[3043,3044,311],"h2",{"id":311},[3039,3046,3047,3048,3052],{},"使用 ",[3049,3050,3051],"code",{},"useHead"," 组合式函数加载第三方 IIFE 脚本很简单，但在服务器端渲染（SSR）、懒加载和类型安全方面会遇到复杂问题。Nuxt Scripts 通过优化第三方脚本的集成，解决了这些挑战，从而提高性能、隐私和整体开发体验。",[3054,3055,317],"h3",{"id":317},[3057,3058,3059,3063,3066,3069,3072,3075],"ul",{},[3060,3061,3062],"li",{},"在客户端和服务器端环境中的兼容性。",[3060,3064,3065],{},"采用最佳实践的默认设置。",[3060,3067,3068],{},"细粒度的优化控制。",[3060,3070,3071],{},"避免阻碍渲染、隐私问题和性能瓶颈。",[3060,3073,3074],{},"确保类型安全和脚本验证。",[3060,3076,3077],{},"与第三方服务器相关的安全考虑。",[3054,3079,323],{"id":323},[3039,3081,3082],{},"第三方资源如分析工具、视频嵌入、地图和社交媒体集成功能增强了网站功能，但并非由网站所有者直接管理。单个资源的性能影响或许很小，但多个资源会显著降低用户体验。脚本尤其可能延迟交互响应并阻碍页面渲染。",[3039,3084,3085,3086,3093,3094,3099,3100,3105],{},"根据 Chrome 用户体验报告，拥有众多第三方资源的 Nuxt 站点通常获得较低的 ",[3087,3088,3092],"a",{"href":3089,"rel":3090},"https://web.dev/articles/inp",[3091],"nofollow","Interaction to Next Paint (INP)"," 和 ",[3087,3095,3098],{"href":3096,"rel":3097},"https://web.dev/articles/lcp",[3091],"Largest Contentful Paint (LCP)"," 分数。尽管这种相关性不代表因果关系，实验室测试和 ",[3087,3101,3104],{"href":3102,"rel":3103},"https://almanac.httparchive.org/en/2022/third-parties",[3091],"Web 年鉴"," 均证实第三方资源对性能有显著影响。",[3043,3107,328],{"id":3108},"nuxt-script-功能",[3054,3110,333],{"id":3111},"️-性能",[3057,3113,3114,3117,3120],{},[3060,3115,3116],{},"脚本加载默认仅在 Nuxt 准备好后触发。",[3060,3118,3119],{},"更高级的脚本加载触发方式，与具体实现无关。",[3060,3121,3122,3123,3126],{},"通过",[3087,3124,3125],{"href":59},"远程脚本打包","提升脚本加载速度。",[3054,3128,338],{"id":3129},"开发者体验",[3057,3131,3132,3135,3138,3141],{},[3060,3133,3134],{},"为常见第三方应用提供精选脚本注册表。",[3060,3136,3137],{},"简化分析事件管理，例如页面浏览跟踪。",[3060,3139,3140],{},"脚本选项输入校验。",[3060,3142,3143],{},"类型安全与 SSR 兼容的 API。",[3054,3145,343],{"id":2272},[3057,3147,3148,3153,3156],{},[3060,3149,3122,3150,3152],{},[3087,3151,3125],{"href":59},"最小化用户数据暴露。",[3060,3154,3155],{},"集成的用户同意管理。",[3060,3157,3158,3159,3093,3162,3165],{},"增强的脚本隐私设置，例如 ",[3049,3160,3161],{},"crossorigin=\"anonymous\"",[3049,3163,3164],{},"referrerpolicy=\"no-referrer\"","。",{"title":330,"searchDepth":314,"depth":314,"links":3167},[3168,3172],{"id":311,"depth":314,"text":311,"children":3169},[3170,3171],{"id":317,"depth":320,"text":317},{"id":323,"depth":320,"text":323},{"id":3108,"depth":314,"text":328,"children":3173},[3174,3175,3176],{"id":3111,"depth":320,"text":333},{"id":3129,"depth":320,"text":338},{"id":2272,"depth":320,"text":343},"Nuxt Scripts 是用于第三方脚本的 Nuxt 开发者体验（DX）。","md",null,{},true,{"title":10,"description":3177},{"loc":11},"imUrydkwPkDSl-_h6cdTJCPueySoz_FVqhOnIztX1DM",1772373774117]