v2.0.0-beta.14: trigger, consent, validation, and docs bugs
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 25/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- typescript
- Lĩnh vực
- backend, developer-experience
Hướng nghiên cứu
The issue reports 12 independent problems across packages/script/src/module.ts, packages/script/src/runtime/utils.ts, packages/script/src/runtime/composables/useScript.ts, packages/script/src/runtime/types.ts, packages/cli/src/cli.ts, and documentation. Start by choosing one item and reproducing it with the issue’s stated Nuxt Scripts version and command or minimal app; compare the result with the linked docs and cited code. Done means a focused fix or documentation correction with a regression test for that item.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
🤖 An agent (Claude Code) filed this issue while writing the @nuxt/scripts package Skill with skilld's generate-package-skill. It reproduced each item against @nuxt/scripts 2.0.0-beta.14.
Environment: @nuxt/scripts 2.0.0-beta.14, Nuxt 4.6.0, unhead and @unhead/vue 3.4.2, Node.js 24.18.0, pnpm 12.4.2, headless Chromium. Each repro is a fresh Nuxt 4 app with modules: ['@nuxt/scripts']. Production results come from nuxt build and node .output/server/index.mjs.
Items are ordered by impact: silent wrong results, then type failures, then doc mismatches, then cleanups.
Silent wrong results
1. trigger: false on a registry entry blocks every composable call
Expected (per docs): the v0 to v1 guide says to set trigger: false when you load the script from a composable. It keeps the infrastructure and lets the composable load the script (1.v0-to-v1.md#L46). The build warning also offers trigger: false.
Observed: a composable call with no trigger never loads. Its status stays awaitingLoad, and the browser makes no request. The module copies trigger: false into runtime config (module.ts#L487), and useRegistryScript merges it into the call (utils.ts#L94).
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/scripts'],
scripts: { registry: { metaPixel: { id: '123456', trigger: false } } },
})
<!-- app/pages/index.vue -->
<script setup lang="ts">
const { status } = useScriptMetaPixel()
</script>
<template>
<p>{{ status }}</p>
</template>
Output after 6 seconds, in dev and production: awaitingLoad. { id: '123456' } with no trigger key loads.
Suggestion: drop an inherited trigger: false in composable calls, or document that trigger: false blocks them.
2. A later call without a trigger loads a consent-gated script
Expected (per docs): "Later composable calls return that script instance and do not need the options again" (1.registry-scripts.md#L158).
Observed: the later call returns the shared instance, but it also adds its own default onNuxtReady trigger. The script loads before consent.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/scripts'],
scripts: { registry: { metaPixel: { id: '123456' } } },
})
// app/utils/consent.ts
export const scriptsConsent = useScriptTriggerConsent()
<!-- app/pages/index.vue: first call, gated -->
<script setup lang="ts">
const { status } = useScriptMetaPixel({ scriptOptions: { trigger: scriptsConsent } })
</script>
<template>
<PixelEvent />
<p>{{ scriptsConsent.consented }} {{ status }}</p>
</template>
<!-- app/components/PixelEvent.vue: second call, no options -->
<script setup lang="ts">
const { proxy } = useScriptMetaPixel()
proxy.fbq('track', 'ViewContent')
</script>
<template>
<span />
</template>
Output after 3 seconds, with no accept: consented is false and status is loaded.
Suggestion: make a later call reuse the first call's trigger, or say in the consent guide that every call needs the consent trigger.
3. Dev option validation never runs for bundled scripts
Expected (per docs): useScriptCloudflareWebAnalytics({ token: '123' }) is "skipped in development because the token is too short" (1.registry-scripts.md#L46).
Observed: in nuxt dev the script loads and sends beacons. The bundle transform rewrites the call to useScriptCloudflareWebAnalytics({ scriptInput: { src: '/_scripts/assets/78f1a00939270893.js' }, token: "123" }). Validation is skipped when scriptInput.src is set (utils.ts#L211).
<!-- app/pages/index.vue -->
<script setup lang="ts">
const { status } = useScriptCloudflareWebAnalytics({ token: '123' })
</script>
<template>
<p>{{ status }}</p>
</template>
Output in nuxt dev: loaded. With scriptOptions: { bundle: false }, the browser console logs "Skipping script cloudflareWebAnalytics due to invalid options: Invalid length: Expected >=32 but received 3", and the status stays awaitingLoad.
Suggestion: validate before the bundle transform adds scriptInput.src, or skip validation only for a user-supplied src.
4. warmupStrategy: false still preloads with the client trigger
Expected (per docs): "false disables warmup entirely" (5.nuxt-config.md#L179).
Observed: Nuxt Scripts passes false through (useScript.ts#L321-L325), but SSR still writes a preload for a client trigger. onNuxtReady with false writes none.
<!-- app/pages/index.vue -->
<script setup lang="ts">
useScript('https://example.com/warm-client.js', { trigger: 'client', warmupStrategy: false })
useScript('https://example.com/warm-ready.js', { trigger: 'onNuxtReady', warmupStrategy: false })
</script>
<template>
<p>warmup</p>
</template>
Output in the SSR HTML: <link href="https://example.com/warm-client.js" rel="preload" ... fetchpriority="low" as="script">, and no link for warm-ready.js.
Suggestion: honour false on the client path, or document the exception.
Type failures
5. The consent guide's consent.update() fails strict typecheck
Expected (per docs): the consent guide calls consent.update({ ... }) on the composable result (3.consent.md#L105).
Observed: consent is optional in UseScriptContext (types.ts#L134). At runtime it exists only on the client.
<!-- app/app.vue -->
<script setup lang="ts">
const { consent } = useScriptGoogleAnalytics({ defaultConsent: { analytics_storage: 'denied' } })
function accept() {
consent.update({ analytics_storage: 'granted' })
}
</script>
<template>
<button @click="accept">
Accept
</button>
</template>
Command: nuxt typecheck. Output: app/app.vue(4,3): error TS18048: 'consent' is possibly 'undefined'.
Suggestion: use consent?.update(...) in the guide, or type consent as present and make it a no-op on the server.
6. trigger: 'manual' in a globals tuple works but fails typecheck
Expected (per docs): the second tuple item takes useScript options (4.global.md). 'manual' is a useScript trigger, and the registry 'mock' entry uses it internally.
Observed: at runtime the global stays awaitingLoad, as expected. Typecheck rejects it, because NuxtUseScriptOptionsSerializable has no 'manual' (types.ts#L220).
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/scripts'],
scripts: { globals: { manualGlobal: [{ src: '/manual-global.js' }, { trigger: 'manual' }] } },
})
Command: nuxt typecheck. Output: Type '"manual"' is not assignable to type '"server" | "client" | "onNuxtReady" | { idleTimeout: number; } | { interaction: string[]; } | { serviceWorker: true; } | undefined'.
Suggestion: add 'manual' to the serializable trigger type.
Doc mismatches
7. The @nuxt/scripts-devtools install line cannot install
Expected (per docs): pnpm add -D @nuxt/[email protected] (2.installation.md#L34). The v1 to v2 guide names the same package (2.v1-to-v2.md#L42).
Observed: npm view @nuxt/scripts-devtools versions returns npm error code E404. No version is published.
Suggestion: publish the package at the core version, or remove the install line until it exists.
8. The missing-trigger warning is silent for env-backed fields
Expected (per docs): "A build warning fires when you supply config values without a trigger" (1.v0-to-v1.md#L35).
Observed: the warning skips fields that have an environment variable (module.ts#L676-L680). The guide's own example gets no warning.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/scripts'],
scripts: { registry: { googleAnalytics: { id: 'G-XXXXXX' } } },
})
Command: nuxt prepare. Output: no warning. { id: 'G-XXXXXX', l: 'dl' } prints "registry.googleAnalytics: config provided without a trigger. The script will not auto-load."
Suggestion: warn for any user-supplied field, or reword the guide.
9. The install and migration commands fetch other versions
Expected (per docs): the v2 installation page and the v1 to v2 guide install and migrate to v2 (2.installation.md#L19, 2.v1-to-v2.md#L30-L31).
Observed: npm latest for @nuxt/scripts is 1.3.12, and npm latest for @nuxt/scripts-cli is 2.0.0-beta.1.
pnpm dlx [email protected] module add scripts
# ● Installing @nuxt/[email protected] as a dependency
npm view @nuxt/scripts-cli dist-tags --json
# { "latest": "2.0.0-beta.1", "beta": "2.0.0-beta.14" }
pnpm dlx [email protected] module add @nuxt/[email protected] installs beta.14 and the unhead and @unhead/vue peers.
Suggestion: pin @beta or the exact version in the v2 docs while v2 is in beta, and move the CLI latest tag to the current beta.
Cleanups
10. The migration CLI misses renamed APIs on a renamed proxy
Expected (per docs): the CLI handles "mechanical API renames" (2.v1-to-v2.md#L34).
Observed: the rename regex matches only the literal name proxy (cli.ts#L273).
<!-- app/components/Track.vue -->
<script setup lang="ts">
const { proxy: rybbit } = useScriptRybbitAnalytics()
rybbit.rybbit.pageview()
</script>
Command: pnpm dlx @nuxt/[email protected] migrate v2. Output: the file is unchanged, and no manual follow-up is listed. proxy.ttq('track', ...) in the same project was rewritten.
Suggestion: list unmatched .rybbit.pageview and ttq( calls as manual follow-ups.
11. The migration CLI drops the final newline
Observed: after pnpm dlx @nuxt/[email protected] migrate v2, the rewritten nuxt.config.ts ends without a newline (\ No newline at end of file in diff). The CLI writes generateCode(module).code as is (cli.ts#L250).
Suggestion: keep the original final newline.
12. v2 ignores a leftover scripts.security block silently
Expected (per docs): the v1 to v2 guide does not mention security, but v2 removed URL signing and the option.
Observed: scripts: { security: { autoGenerateSecret: false } } gives no warning in nuxt prepare. The migration CLI keeps the block and lists no follow-up for it.
Suggestion: warn once when scripts.security is set, and list it in the guide and as a CLI follow-up.
- Ngôn ngữ chính
- TypeScript
- Star
- 585
- Fork
- 95
- Merge trung bình
- 1 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 42
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của nuxt/scripts
-
harlan-agent-wait-to-implement
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 58/100
nuxt/scripts#887 · 7 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Loading 3rd party scripts for unused widgetCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mởharlan-agent-wait-to-implement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 55/100
nuxt/scripts#882 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
harlan-agent-wait-to-implement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
nuxt/scripts#881 · 1 bình luận · 1 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Dependency DashboardĐang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 10/100
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
area:editor bug issue-form:bug P0 platform:windows review: low
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
1lck/Lithe-IDEA#1388 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
fix(api): isToolAuditEnabled swallows database read errors on auditToolOperations without loggingĐang mởarea: backend bug priority: low
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
snapotter-hq/SnapOtter#3238 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
rig up --plan times out after 5 s and reports an UNKNOWN outcome while the daemon completes the planĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
filesystem: search_files does not expand non-wildcard excludePatterns like directory_tree doesĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
modelcontextprotocol/servers#5216 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày