Skip to content

feat: auto-populate runtimeConfig for .env registry script overrides#634

Merged
harlan-zw merged 2 commits intomainfrom
fix/239-auto-env-runtime-config
Mar 6, 2026
Merged

feat: auto-populate runtimeConfig for .env registry script overrides#634
harlan-zw merged 2 commits intomainfrom
fix/239-auto-env-runtime-config

Conversation

@harlan-zw
Copy link
Collaborator

@harlan-zw harlan-zw commented Mar 6, 2026

🔗 Linked issue

Resolves #239

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

Users had to manually define verbose runtimeConfig.public.scripts entries for .env overrides to work with registry scripts. The module now auto-populates runtimeConfig defaults (empty string keys) when a registry script is enabled, so NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID works without any runtimeConfig boilerplate.

…v overrides

When a registry script is enabled (e.g., `googleAnalytics: true`), automatically
populate `runtimeConfig.public.scripts.<key>` with empty-string defaults for the
script's primary config keys. This allows env vars like
`NUXT_PUBLIC_SCRIPTS_GOOGLE_ANALYTICS_ID` to work without manually declaring the
runtimeConfig boilerplate.

Closes #239
@vercel
Copy link
Contributor

vercel bot commented Mar 6, 2026

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

Project Deployment Actions Updated (UTC)
scripts-playground Ready Ready Preview, Comment Mar 6, 2026 4:42am

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@nuxt/scripts@634

commit: 5fdc7c5

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

Adds a REGISTRY_ENV_DEFAULTS mapping and new logic that builds a registryWithDefaults by iterating config.registry and applying per-script defaults. The code handles boolean, 'mock', object, and array registry values to produce normalized script entries, then merges registryWithDefaults into nuxt.options.runtimeConfig.public.scripts (replacing direct use of config.registry). Comments about ensuring runtimeConfig.public were removed and replaced by this defaulting flow so NUXT_PUBLIC_SCRIPTS_<SCRIPT>_ env vars can merge with generated defaults.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: auto-populating runtimeConfig for registry scripts to enable .env overrides without boilerplate.
Description check ✅ Passed The PR description includes the linked issue, type of change, and a clear explanation of what the enhancement does and why it's needed.
Linked Issues check ✅ Passed The code changes directly address issue #239 by auto-populating runtimeConfig defaults for registry scripts, eliminating the need for manual empty-key declarations.
Out of Scope Changes check ✅ Passed All changes in src/module.ts are directly focused on implementing auto-population of runtimeConfig for registry scripts, with no extraneous modifications.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/239-auto-env-runtime-config

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/module.ts (1)

162-190: Avoid a second source of truth for env-populated keys.

This table duplicates per-script input knowledge that already lives in the registry/types, so new scripts can silently miss env auto-provisioning unless both places are updated. Consider co-locating the env-key metadata with each registry entry or schema and generating this map from that metadata.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/module.ts` around lines 162 - 190, REGISTRY_ENV_DEFAULTS duplicates
env-key metadata and should be generated from the registry/type definitions
instead of being a separate source; update each registry entry (the registry
export or type objects used to register scripts) to include a small envDefaults
(or envKeys) metadata field, then replace the hard-coded REGISTRY_ENV_DEFAULTS
with a computed map derived from those registry entries (use the existing
registry export/registry types to iterate and build the same shape); ensure the
symbol REGISTRY_ENV_DEFAULTS is removed or replaced and any consumers read the
generated map so new scripts only need to declare env metadata once.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/module.ts`:
- Around line 390-417: The registry defaults are being mirrored from the
pre-normalized config so later syntheses (e.g., config.partytown adding entries)
and consumers (like googleStaticMapsProxy.apiKey reading
public.scripts.googleMaps) miss injected env defaults; instead, compute and use
the final normalized registry first and then derive registryWithDefaults and
nuxt.options.runtimeConfig.public.scripts from that normalized shape.
Concretely: run the registry normalization step that produces the final registry
(the same normalization used later for config.partytown) before the loop that
builds registryWithDefaults (referencing config.registry, REGISTRY_ENV_DEFAULTS
and registryWithDefaults), then apply the env-default-merging logic against that
normalized registry and finally set nuxt.options.runtimeConfig.public.scripts so
later reads (e.g., googleStaticMapsProxy.apiKey and code that inspects
config.partytown) see the fully synthesized defaults.
- Around line 402-403: The current assignment writes the full tuple into runtime
config (registryWithDefaults[key] = [defu(...), value[1]]), which nests the real
script fields under index 0 and breaks runtimeConfig.public.scripts reads in
useRegistryScript(); instead, mirror only the flattened script object into the
runtime config and keep the tuple's options in the registry config. Change the
assignment so registryWithDefaults[key] is set to defu(value[0] || {},
envDefaults) (only the script object) and ensure the tuple's second element
(value[1]) remains stored in config.registry (or the existing registry
structure) rather than being placed into runtimeConfig.public.scripts.

---

Nitpick comments:
In `@src/module.ts`:
- Around line 162-190: REGISTRY_ENV_DEFAULTS duplicates env-key metadata and
should be generated from the registry/type definitions instead of being a
separate source; update each registry entry (the registry export or type objects
used to register scripts) to include a small envDefaults (or envKeys) metadata
field, then replace the hard-coded REGISTRY_ENV_DEFAULTS with a computed map
derived from those registry entries (use the existing registry export/registry
types to iterate and build the same shape); ensure the symbol
REGISTRY_ENV_DEFAULTS is removed or replaced and any consumers read the
generated map so new scripts only need to declare env metadata once.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4066e0c3-943f-4ca2-bb26-b50f0730a916

📥 Commits

Reviewing files that changed from the base of the PR and between 9431643 and b0891e3.

📒 Files selected for processing (1)
  • src/module.ts

Comment on lines +390 to 417
// Auto-populate env var defaults for enabled registry scripts so that
// NUXT_PUBLIC_SCRIPTS_<SCRIPT>_<KEY> works without manual runtimeConfig
const registryWithDefaults: Record<string, any> = {}
for (const [key, value] of Object.entries(config.registry)) {
if (value && REGISTRY_ENV_DEFAULTS[key]) {
const envDefaults = REGISTRY_ENV_DEFAULTS[key]
if (value === true || value === 'mock') {
registryWithDefaults[key] = { ...envDefaults }
}
else if (typeof value === 'object' && !Array.isArray(value)) {
registryWithDefaults[key] = defu(value, envDefaults)
}
else if (Array.isArray(value)) {
registryWithDefaults[key] = [defu(value[0] || {}, envDefaults), value[1]]
}
else {
registryWithDefaults[key] = value
}
}
else {
registryWithDefaults[key] = value
}
}

nuxt.options.runtimeConfig.public.scripts = defu(
nuxt.options.runtimeConfig.public.scripts || {},
config.registry,
registryWithDefaults,
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Normalize the registry before mirroring it into runtime config.

This block runs before config.partytown can synthesize extra registry entries (Lines 443-476), and googleStaticMapsProxy.apiKey has already been read from public.scripts.googleMaps above (Lines 371-372). As a result, partytown: ['googleAnalytics'] still misses the new env defaults, and googleMaps: true still leaves the static-maps proxy without an API key unless the old runtimeConfig boilerplate is present. Please derive both runtime-config objects from the final normalized registry shape.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/module.ts` around lines 390 - 417, The registry defaults are being
mirrored from the pre-normalized config so later syntheses (e.g.,
config.partytown adding entries) and consumers (like
googleStaticMapsProxy.apiKey reading public.scripts.googleMaps) miss injected
env defaults; instead, compute and use the final normalized registry first and
then derive registryWithDefaults and nuxt.options.runtimeConfig.public.scripts
from that normalized shape. Concretely: run the registry normalization step that
produces the final registry (the same normalization used later for
config.partytown) before the loop that builds registryWithDefaults (referencing
config.registry, REGISTRY_ENV_DEFAULTS and registryWithDefaults), then apply the
env-default-merging logic against that normalized registry and finally set
nuxt.options.runtimeConfig.public.scripts so later reads (e.g.,
googleStaticMapsProxy.apiKey and code that inspects config.partytown) see the
fully synthesized defaults.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/module.ts (1)

390-417: ⚠️ Potential issue | 🟠 Major

Ordering issue: defaults are computed before partytown synthesis and after googleStaticMapsProxy.apiKey is read.

This block still runs:

  1. After Line 372 reads googleStaticMapsProxy.apiKey from runtimeConfig.public.scripts?.googleMaps?.apiKey — so if a user has only googleMaps: true in registry (relying on .env for the API key), the proxy config won't receive the key.
  2. Before Lines 443-476 where config.partytown can inject additional registry entries — those entries won't receive env defaults.
Proposed fix: move the defaults logic after partytown processing and re-read proxy config

Move the registryWithDefaults computation to after the partytown block (after Line 487), then either:

  • Re-assign googleStaticMapsProxy.apiKey after the merge, or
  • Defer reading googleStaticMapsProxy.apiKey until after defaults are merged
 // After Line 487 (end of partytown block):
+    // Auto-populate env var defaults for enabled registry scripts
+    if (config.registry) {
+      nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {}
+      const registryWithDefaults: Record<string, any> = {}
+      for (const [key, value] of Object.entries(config.registry)) {
+        // ... same logic ...
+      }
+      nuxt.options.runtimeConfig.public.scripts = defu(
+        nuxt.options.runtimeConfig.public.scripts || {},
+        registryWithDefaults,
+      )
+      // Re-assign googleStaticMapsProxy.apiKey after env defaults are merged
+      if (config.googleStaticMapsProxy?.enabled) {
+        (nuxt.options.runtimeConfig['nuxt-scripts'] as any).googleStaticMapsProxy = {
+          apiKey: (nuxt.options.runtimeConfig.public.scripts as any)?.googleMaps?.apiKey,
+        }
+      }
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/module.ts` around lines 390 - 417, The defaults merge for registry env
vars (registryWithDefaults using REGISTRY_ENV_DEFAULTS and
nuxt.options.runtimeConfig.public.scripts = defu(...)) runs in the wrong place —
move the entire registryWithDefaults computation to after the partytown
processing that mutates config.partytown (the block that injects registry
entries), then recompute/re-read any proxy config values that were read earlier
(e.g., googleStaticMapsProxy.apiKey from
runtimeConfig.public.scripts?.googleMaps?.apiKey) so the proxy picks up
env-defaulted values; alternatively defer reading googleStaticMapsProxy.apiKey
until after you call defu into nuxt.options.runtimeConfig.public.scripts.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/module.ts`:
- Around line 390-417: The defaults merge for registry env vars
(registryWithDefaults using REGISTRY_ENV_DEFAULTS and
nuxt.options.runtimeConfig.public.scripts = defu(...)) runs in the wrong place —
move the entire registryWithDefaults computation to after the partytown
processing that mutates config.partytown (the block that injects registry
entries), then recompute/re-read any proxy config values that were read earlier
(e.g., googleStaticMapsProxy.apiKey from
runtimeConfig.public.scripts?.googleMaps?.apiKey) so the proxy picks up
env-defaulted values; alternatively defer reading googleStaticMapsProxy.apiKey
until after you call defu into nuxt.options.runtimeConfig.public.scripts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5ee1a31d-6894-4252-8e5a-2fd602c21833

📥 Commits

Reviewing files that changed from the base of the PR and between b0891e3 and 5efc2d2.

📒 Files selected for processing (1)
  • src/module.ts

@harlan-zw harlan-zw merged commit 1db6fc1 into main Mar 6, 2026
9 checks passed
@harlan-zw harlan-zw deleted the fix/239-auto-env-runtime-config branch March 6, 2026 04:49
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.

Drop need to specify the runtime config when using .env

1 participant