Skip to content

fix: avoid mutating runtimeConfig when merging registry script options#708

Merged
harlan-zw merged 1 commit into0.xfrom
fix/registry-script-runtime-config-mutation
Apr 14, 2026
Merged

fix: avoid mutating runtimeConfig when merging registry script options#708
harlan-zw merged 1 commit into0.xfrom
fix/registry-script-runtime-config-mutation

Conversation

@harlan-zw
Copy link
Copy Markdown
Collaborator

Summary

Fixes #702Cannot stringify a function during prerender when a script is configured in scripts.registry in nuxt.config.

Root cause

useRegistryScript in src/runtime/utils.ts used Object.assign to merge the registry-defined scriptOptions (which include the composable's use() function) into userOptions.scriptOptions. When the user configured the script via nuxt.config, userOptions.scriptOptions was a live reference to runtimeConfig.public.scripts.<key>.scriptOptions. The merge therefore wrote a function reference directly into runtimeConfig. The wrapped beforeInit function was then assigned to the same reference.

At prerender time, Nuxt's renderPayloadJsonScript calls uneval(ssrContext.config) which walks the public runtime config; devalue throws when it encounters the use / beforeInit functions that leaked in.

Fix

Switch the two merges to defu / spread so they produce fresh objects and leave runtimeConfig untouched. This matches the v1 behavior (already fixed there).

Test plan

  • Added a regression test in test/unit/utils.test.ts that asserts the runtime config object passed via useRuntimeConfig().public.scripts.<key> is not mutated by useRegistryScript. The test fails on current 0.x and passes with this fix.
  • All existing unit tests still pass (pnpm test:unit).
  • Manually verified cloudflareWebAnalytics with scriptOptions: { trigger: 'client' } in scripts.registry now prerenders cleanly.

`useRegistryScript` used `Object.assign` to merge the registry-defined
`scriptOptions` (which include `use` / `beforeInit` functions) into
`userOptions.scriptOptions`. When the user configured the script in
`nuxt.config`, `userOptions.scriptOptions` was a reference to
`runtimeConfig.public.scripts.<key>.scriptOptions`, so the merge
wrote function references directly into `runtimeConfig`. During
prerender, `uneval(ssrContext.config)` then failed with
"Cannot stringify a function".

Switch the two merges to `defu` / spread so a fresh object is
produced and `runtimeConfig` stays serializable.

Fixes #702
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
scripts-playground Building Building Preview, Comment Apr 14, 2026 3:42am

@harlan-zw harlan-zw merged commit 16924a9 into 0.x Apr 14, 2026
4 of 5 checks passed
@harlan-zw harlan-zw deleted the fix/registry-script-runtime-config-mutation branch April 14, 2026 03:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant