Skip to content

fix(domain): resolve domain config the same way at build time and runtime - #4090

Merged
BobbieGoede merged 3 commits into
mainfrom
audit/domain-divergences
Jul 27, 2026
Merged

fix(domain): resolve domain config the same way at build time and runtime#4090
BobbieGoede merged 3 commits into
mainfrom
audit/domain-divergences

Conversation

@BobbieGoede

@BobbieGoede BobbieGoede commented Jul 27, 2026

Copy link
Copy Markdown
Member

Four places where a domain fact was derived twice, once at build time and once at runtime, and the two derivations disagreed.

shouldLocalizeRoutes read only the singular domain, so no_prefix accepted two locales sharing a domain when they were configured through domains and refused the same setup written as domain. getDomainDefaultLocales read the raw domainDefault while the runtime resolves domain defaults from defaultForDomains alone, so a locale carrying domainDefault without any domain was given unprefixed ___default routes the runtime could never select it for. Both now resolve through normalizeDomainLocale, which is where that mapping already lives.

withRuntimeDomain replaced a locale's domain and left domains as it was built, so a locale moved with NUXT_PUBLIC_I18N_DOMAIN_LOCALES_{code}_DOMAIN matched its new host and the one it was configured with, which host membership now decides navigation and relocation from. It replaces both, and carries defaultForDomains over so an overridden locale stays the default for the domain it moved to.

__I18N_COMPACT_ROUTES__ was set from experimental.compactRoutes alone while route generation also requires no domain routing and a prefixing strategy, so an incompatible config left the runtime taking compact branches against a route table that had none, including dropping a locale route param. The flag now mirrors the generation gate that prepare/options.ts already warns about.

The updated snapshot loses only routes, the ___default variants that were generated for a locale with no domain to be the default for.

Summary by CodeRabbit

  • Bug Fixes

    • Improved domain-based locale routing and validation.
    • Prevented unsupported unprefixed routing when multiple locales share a domain.
    • Improved handling of locales configured across multiple domains.
    • Ensured runtime domain overrides keep locale defaults and domain mappings consistent.
    • Corrected route generation for domain-default locales without assigned domains.
  • Tests

    • Added coverage for runtime domain overrides, shared domains, multi-domain locales, and default route generation.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

The changes gate compact route compilation for domain-based and no-prefix routing, normalize domain data during no-prefix validation, and detect duplicate hosts across locale domain configurations. Runtime domain overrides now update related domain metadata. Tests cover host matching, default-locale resolution, duplicate-domain validation, multi-domain locales, and unprefixed route generation.

Estimated code review effort: 3 (Moderate) | ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning domain configuration handling between build time and runtime.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch audit/domain-divergences

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/runtime/shared/domain.ts`:
- Around line 100-102: Update the domain normalization flow around the existing
domain comparison so a matching primary domain does not return early when
properties.domains contains other hosts. For a runtime override, always collapse
domains and defaultForDomains to the single override domain, while preserving
the current no-domain behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 22b7ccd1-d351-4ae4-bb53-22f8c3974df9

📥 Commits

Reviewing files that changed from the base of the PR and between 0406e3f and 6b24064.

⛔ Files ignored due to path filters (1)
  • test/pages/__snapshots__/localize_routes.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • src/bundler.ts
  • src/routing.ts
  • src/runtime/shared/domain.ts
  • test/domain.test.ts
  • test/pages/localize_routes.test.ts

Comment on lines +100 to +102
if (!domain || domain === properties.domain) {
return locale
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not skip normalization when the primary domain already matches.

If domain === properties.domain but properties.domains still contains other hosts, this return leaves the locale matching those old hosts. A runtime override must still collapse domains (and defaultForDomains) to the single override domain.

Proposed fix
-  if (!domain || domain === properties.domain) {
+  if (!domain) {
     return locale
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!domain || domain === properties.domain) {
return locale
}
if (!domain) {
return locale
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/shared/domain.ts` around lines 100 - 102, Update the domain
normalization flow around the existing domain comparison so a matching primary
domain does not return early when properties.domains contains other hosts. For a
runtime override, always collapse domains and defaultForDomains to the single
override domain, while preserving the current no-domain behavior.

@BobbieGoede
BobbieGoede merged commit b38b7df into main Jul 27, 2026
11 checks passed
@BobbieGoede
BobbieGoede deleted the audit/domain-divergences branch July 27, 2026 13:23
BobbieGoede added a commit that referenced this pull request Jul 27, 2026
…time

`normalizeDomainLocale` now always sets `domains` and `defaultForDomains`, so domain
logic can read them without a fallback, and the result is typed as
`NormalizedLocaleObject`. `domainDefault` is fully resolved into `defaultForDomains`,
so the type takes it away - reading it past normalization is how the build and the
runtime came to disagree in #4090.

The test helpers resolve their locales through the normalizer the same way
`resolveContext` does, rather than passing a shape the build never produces.
BobbieGoede added a commit that referenced this pull request Jul 27, 2026
…time

`normalizeDomainLocale` now always sets `domains` and `defaultForDomains`, so domain
logic can read them without a fallback, and the result is typed as
`NormalizedLocaleObject`. `domainDefault` is fully resolved into `defaultForDomains`,
so the type takes it away - reading it past normalization is how the build and the
runtime came to disagree in #4090.

The test helpers resolve their locales through the normalizer the same way
`resolveContext` does, rather than passing a shape the build never produces.
BobbieGoede added a commit that referenced this pull request Jul 27, 2026
…time

`normalizeDomainLocale` now always sets `domains` and `defaultForDomains`, so domain
logic can read them without a fallback, and the result is typed as
`NormalizedLocaleObject`. `domainDefault` is fully resolved into `defaultForDomains`,
so the type takes it away - reading it past normalization is how the build and the
runtime came to disagree in #4090.

The test helpers resolve their locales through the normalizer the same way
`resolveContext` does, rather than passing a shape the build never produces.
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