Skip to content

Conversation

@caiotarifa
Copy link

@caiotarifa caiotarifa commented Dec 11, 2025

🔗 Linked issue

Resolves #3761

📚 Description

This PR adds support for custom URL prefixes per locale. Instead of using the locale code as the URL prefix, users can now define a custom prefix property in the locale configuration.

Problem

Users want to use URL prefixes instead of locale codes. For example, /brazil/about instead of /pt-BR/about.

Solution

Added a new optional prefix property to the LocaleObject type. When defined, the module uses this custom prefix in the URL instead of the locale code.

Example configuration:

locales: [
  { code: 'en', language: 'en-US' },
  { code: 'pt-BR', language: 'pt-BR', prefix: 'brazil' }
]

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Added custom URL prefix support per locale. Routes can use custom path prefixes (e.g., /brazil/ for pt-BR) while route names and i18n internals continue to use locale codes.

* **Documentation**
  * Added docs and examples explaining how to configure per-locale URL prefixes and expected routing behavior.

* **Tests**
  * Added comprehensive tests covering prefix behavior, fallbacks, strategies, nested routes, aliases, trailing slashes, and edge cases.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 11, 2025

Walkthrough

Adds support for custom locale URL prefixes by introducing a prefix?: string field on locale objects, wiring a localePrefixes map into route generation, and exposing getLocalePrefix(locale) on the route context. Route creation and alias generation now use the locale prefix (falling back to the locale code when absent). Documentation pages were updated to describe the prefix option and examples, and a comprehensive test suite for locale prefix behavior was added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review public API changes: LocaleObject.prefix?: string in src/types.ts.
  • Inspect getLocalePrefix() implementation and its wiring in src/kit/gen.ts, and confirm fallback behavior.
  • Verify buildLocalePrefixes() and the passing of localePrefixes in src/routing.ts.
  • Read test/locale-prefix.test.ts to confirm coverage for strategies (prefix_except_default, prefix_and_default), nested routes, aliases, trailing slashes, and edge cases.
  • Skim updated docs (docs/...index.md, new-features.md, 04.api/00.options.md) for accuracy and examples.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main feature: allowing custom URL prefixes per locale, which is the primary change across the entire changeset.
Linked Issues check ✅ Passed The pull request fully implements the linked issue #3761 requirements: adds an optional prefix property to LocaleObject, uses custom prefixes in URLs while preserving locale codes, and provides straightforward configuration without requiring manual per-route mappings.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the custom locale prefix feature: documentation updates, type definitions, routing logic, and comprehensive tests align with the linked issue objectives.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7292609 and 7cb8d3a.

📒 Files selected for processing (1)
  • src/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/types.ts

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
Contributor

@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: 0

🧹 Nitpick comments (6)
docs/content/docs/02.guide/91.new-features.md (1)

8-26: New feature blurb is clear; only a tiny wording nit

The description and example accurately reflect the new prefix option and correctly point to the options docs. If you care about style, you might vary the repeated “want to use …” phrasing in lines 9 and 11, but that’s purely cosmetic.

src/types.ts (1)

518-526: Clarify prefix typing and adjust code JSDoc for consistency

Two small consistency points around this new field:

  • The options docs describe prefix as null | string, while the type here is prefix?: string. In TS configs this means prefix: null will be rejected even though the docs say it’s allowed. Either change the docs to just string or widen the type here to string | null if you want that to be officially supported.
  • The code JSDoc above still says “Used for route prefixing…”, but with this option routing may use prefix instead of code when defined. Consider rephrasing to something like “Unique identifier of the locale. Used for route naming and as an argument in i18n utilities; used as the default URL prefix when no custom prefix is configured.”
docs/content/docs/04.api/00.options.md (1)

152-169: prefix option docs are accurate; consider clarifying allowed format

The behavior and example are aligned with the implementation: custom segment for the URL path while route names still use the locale code.

Two possible clarifications to make this harder to misuse:

  • Explicitly say the value should be a single path segment without leading/trailing / (e.g. brazil, not /brazil/), since the module prefixes it with / internally.
  • Optionally note that prefixes should be unique per locale when using path-based strategies; duplicate prefixes will lead to routes sharing the same URL path even though their names differ.
src/routing.ts (1)

67-79: Locale prefix map wiring looks correct; consider guarding against duplicate prefixes

The buildLocalePrefixes helper and its use in localizeRoutes cleanly introduce per-locale prefixes while preserving existing behavior when prefix is unset/empty.

You might optionally mirror the domain-duplication guard from shouldLocalizeRoutes and log a warning or error if multiple locales share the same non-empty prefix, since that will generate routes with identical paths but different names, which can be surprising in Vue Router. Not critical, but would make misconfigurations easier to catch.

Also applies to: 91-94

test/locale-prefix.test.ts (1)

1-241: Good coverage for locale prefixes; only a minor naming nit

The test suite does a solid job exercising custom prefixes across strategies, children, aliases, trailing slashes, empty prefixes, and mixed configurations. This gives good confidence in the new behavior.

Tiny nit: the “should handle prefix with special characters” case currently uses 'br', which is not really special. Either rename the test description or switch the sample to something like 'br-south' or similar to better reflect the intent.

src/kit/gen.ts (1)

70-78: RouteContext getLocalePrefix integration looks correct; consider constraining prefix format

The introduction of getLocalePrefix and its use in both path and alias localization is consistent:

  • Locales with a configured prefix use that value; others fall back to the locale code.
  • no_prefix and unprefixed trees still work because shouldPrefix controls whether prefixed vs unprefixed is used.
  • Empty prefixes behave as intended via the buildLocalePrefixes logic.

One behavior worth calling out (and possibly guarding against): if a user supplies a prefix containing / (e.g. '/brazil'), join('/', prefix, unprefixed) will yield paths with multiple slashes like '///about'. You may want to normalize or reject such prefixes in one place (e.g. when building the localePrefixes map) and/or document that prefix must be a bare segment without slashes.

Also applies to: 105-123, 145-160, 191-203

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9b4529 and 7292609.

📒 Files selected for processing (7)
  • docs/content/docs/02.guide/01.index.md (1 hunks)
  • docs/content/docs/02.guide/91.new-features.md (1 hunks)
  • docs/content/docs/04.api/00.options.md (1 hunks)
  • src/kit/gen.ts (4 hunks)
  • src/routing.ts (2 hunks)
  • src/types.ts (1 hunks)
  • test/locale-prefix.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/routing.ts (1)
src/types.ts (1)
  • LocaleObject (457-539)
test/locale-prefix.test.ts (3)
src/kit/gen.ts (1)
  • LocalizableRoute (17-25)
src/types.ts (1)
  • LocaleObject (457-539)
src/routing.ts (1)
  • localizeRoutes (84-138)
🪛 LanguageTool
docs/content/docs/02.guide/91.new-features.md

[style] ~11-~11: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...n the locale code. For example, if you want to use /brazil/ instead of /pt-BR/ for...

(REP_WANT_TO_VB)

🔇 Additional comments (1)
docs/content/docs/02.guide/01.index.md (1)

100-125: Guide “Custom Locale Prefix” section matches implementation

The explanation, example config, and resulting routes align with the new prefix behavior (custom URL segment while keeping the locale code internal). No issues from a behavior or consistency standpoint.

Removed redundant comment about SEO-friendly prefixes.
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.

Allow custom prefix per locale

1 participant