From 2db17698a76894d5ca81216b5e48b58735b67797 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Wed, 7 Oct 2026 12:59:23 +1100 Subject: [PATCH 1/4] docs(skills): add @nuxt/scripts Skill Agents misuse the registry trigger rules, consent ordering, build-time bundling, and the build-time signing secret. The Skill records the behaviour of @nuxt/scripts 1.3.12, tested in a consumer fixture. Ship the skills folder in the package and point the README and installation tips at the skilld.dev page. --- README.md | 12 +- .../docs/1.getting-started/2.installation.md | 5 +- packages/script/package.json | 3 +- packages/script/skills/nuxt-scripts/SKILL.md | 161 ++++++++++++++++++ 4 files changed, 172 insertions(+), 9 deletions(-) create mode 100644 packages/script/skills/nuxt-scripts/SKILL.md diff --git a/README.md b/README.md index b18f307c7..638df4e6a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,13 @@ [![License][license-src]][license-href] [![Nuxt][nuxt-src]][nuxt-href] [![Volta][volta-src]][volta-href] + + + + + Skill repository on skilld.dev + + # Nuxt Scripts @@ -38,10 +45,7 @@ npx nuxi@latest module add scripts ``` > [!TIP] -> Generate an Agent Skill for this package using [skilld](https://github.com/harlan-zw/skilld): -> ```bash -> npx skilld add @nuxt/scripts -> ``` +> Using an AI agent? Get the @nuxt/scripts Skill on [skilld.dev/gh/nuxt/scripts/nuxt-scripts](https://skilld.dev/gh/nuxt/scripts/nuxt-scripts). That's it. The Nuxt Scripts module should be downloaded and added to your Nuxt Config `modules`. diff --git a/docs/content/docs/1.getting-started/2.installation.md b/docs/content/docs/1.getting-started/2.installation.md index dbd67223d..405627d6b 100644 --- a/docs/content/docs/1.getting-started/2.installation.md +++ b/docs/content/docs/1.getting-started/2.installation.md @@ -20,10 +20,7 @@ npx nuxi@latest module add scripts ``` > [!TIP] -> Generate an Agent Skill for this package using [skilld](https://github.com/skilld-dev/skilld): -> ```bash -> npx skilld add @nuxt/scripts -> ``` +> Using an AI agent? Get the @nuxt/scripts Skill on [skilld.dev/gh/nuxt/scripts/nuxt-scripts](https://skilld.dev/gh/nuxt/scripts/nuxt-scripts). The [Nuxt module command](https://nuxt.com/docs/api/commands/module) installs Nuxt Scripts and adds it to the `modules` array in your Nuxt config. diff --git a/packages/script/package.json b/packages/script/package.json index 5cc097b71..ee80f3ebb 100644 --- a/packages/script/package.json +++ b/packages/script/package.json @@ -47,7 +47,8 @@ }, "files": [ "THIRD_PARTY_LICENSES.md", - "dist" + "dist", + "skills" ], "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0" diff --git a/packages/script/skills/nuxt-scripts/SKILL.md b/packages/script/skills/nuxt-scripts/SKILL.md new file mode 100644 index 000000000..723b9f6a4 --- /dev/null +++ b/packages/script/skills/nuxt-scripts/SKILL.md @@ -0,0 +1,161 @@ +--- +name: nuxt-scripts +description: Load and control third-party scripts in Nuxt with @nuxt/scripts. Covers the `scripts.registry` config key, registry composables such as useScriptGoogleAnalytics and useScriptMetaPixel, useScript, scripts.globals, useScriptTriggerConsent for cookie banners, build-time bundling, the /_scripts/p first-party proxy, and NUXT_SCRIPTS_PROXY_SECRET. Use when a task adds analytics, pixels, chat, video, or map scripts to a Nuxt app, mentions @nuxt/scripts or NUXT_PUBLIC_SCRIPTS_* variables, or reports a script that never loads, a build that fails downloading a script, or 403 errors on /_scripts routes. +--- + +# @nuxt/scripts + +Tested against `@nuxt/scripts` 1.3.12 (npm `latest`) with Nuxt 4.6.0. The module needs Nuxt 3.16 or newer. +Composables and components are auto-imported. The examples import from `#imports` only to stay complete modules. + +## Setup + +Install with `npx nuxi module add scripts`. A registry entry's `trigger` decides whether it loads globally: + +| `scripts.registry` entry | Global script | Composable called with no options | +|---|---|---| +| `{ id, trigger: 'onNuxtReady' }` | loads on every page | returns the global instance | +| `{ id }` or `{}` | none | loads with the default `onNuxtReady` trigger | +| `{ id, trigger: false }` | none | never loads: it inherits `trigger: false` | +| `'mock'` | none | stays `awaitingLoad`; proxy calls do nothing | + +```ts +import { defineNuxtConfig } from 'nuxt/config' + +export default defineNuxtConfig({ + modules: ['@nuxt/scripts'], + scripts: { + registry: { + // Cookieless, so it loads on every page. + plausibleAnalytics: { domain: 'example.com', trigger: 'onNuxtReady' }, + // No trigger: app.vue loads it after consent. The ID comes from + // NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID. + googleAnalytics: {}, + }, + }, +}) +``` + +Each registry key reads `NUXT_PUBLIC_SCRIPTS__` (camelCase key in SCREAMING_SNAKE_CASE) without a `runtimeConfig` declaration. +The key must be in `scripts.registry`; otherwise the module warns and ignores the variable. These values are public. + +## Automatic behaviour + +- SSR HTML contains no script tags. Scripts load on the client after hydration (`onNuxtReady`). +- SSR adds `` for `onNuxtReady` and `client` triggers. Set `warmupStrategy: false` to stop it. +- Cross-origin tags get `crossorigin="anonymous"` and `referrerpolicy="no-referrer"`. +- Registry scripts that support bundling are downloaded at build and served from `/_scripts/assets/.js`. Set `bundle: false` on an entry to load from the vendor. For most scripts this also stops the proxy, because the proxy rewrites the bundle. +- Collection requests of supported scripts go through `/_scripts/p//...`. Each script has a privacy tier, and every tier anonymises the IP. Set `proxy: false` on an entry to send them direct. +- `nuxt dev` appends `NUXT_SCRIPTS_PROXY_SECRET` to `.env` when a signed endpoint is registered: `googleMaps`, `gravatar`, `xEmbed`, `instagramEmbed`, `blueskyEmbed`. Set `security.autoGenerateSecret: false` to stop it. +- Calls are deduplicated by `key`, else `src`. A second call returns the first instance and ignores its options. + +## Common tasks + +Load consent-gated scripts. A module-level trigger in `utils/` is shared by every component: + +```ts +// utils/consent.ts +import { useScriptTriggerConsent } from '#imports' + +export const scriptsConsent = useScriptTriggerConsent() +``` + +```vue + + + + +``` + +`scriptsConsent.revoke()` sets `consented` to `false` but does not unload a loaded script. Call the vendor API through `consent` instead. + +Call a vendor API. Proxy calls queue until load and return `undefined`; use `onLoaded` for a return value: + +```vue + + + +``` + +Give each instance a unique `key` to load one script twice with different options. + +## Integrations + +- `partytown: true` needs `@nuxtjs/partytown`. It writes ` + + +``` + Give each instance a unique `key` to load one script twice with different options. ## Integrations -- `partytown: true` needs `@nuxtjs/partytown`. It writes `