Skip to content

Conversation

@oskery
Copy link

@oskery oskery commented Nov 26, 2025

PR: [sitecore-jss-nextjs] Fix Link component locale handling for different languageEmbedding configurations

Description / Motivation

The Link component currently hardcodes locale={false} when rendering Next.js's <Link> component. This prevents Next.js from automatically adding locale prefixes to URLs.

While this works correctly when Sitecore is configured with languageEmbedding="always" (where URLs from Sitecore already include the locale prefix), it breaks navigation for sites using languageEmbedding="asNeeded" where Sitecore URLs may not include the locale prefix.

The Issue

When a user is on a non-default locale page (e.g., /sv/about) and clicks an internal link that Sitecore returns without a locale prefix (e.g., /contact), they are incorrectly navigated to the default locale version (/contact) instead of staying in their current locale (/sv/contact).

Historical Context

PR #493 (Nov 2020) introduced the locale={false} pattern as a workaround to prevent double locale prefixes when Sitecore URLs already contain the locale. The PR description noted:

"Cannot force sub-path/prefix usage for default locale [...] In the meantime, workaround would be to add the prefix yourself in all client routing."

It seems this approach was designed with languageEmbedding="always" configurations in mind, and the behavior for languageEmbedding="asNeeded" appears to be an edge case that wasn't fully addressed at the time.

Solution

Instead of hardcoding locale={false}, we can intelligently detect whether the href already contains a locale prefix by checking against the configured locales from Next.js's router:

const router = useRouter();

// Check if href already starts with a known locale
const hrefHasLocale = router.locales?.some(locale => 
  href?.startsWith(`/${locale}/`) || href === `/${locale}`
);

<NextLink
  href={...}
  locale={hrefHasLocale ? false : undefined}
  ...
>

Behavior:

  • If href contains a locale prefix (e.g., /sv/about) → locale={false} (don't double-add)
  • If href doesn't contain a locale prefix (e.g., /about) → locale={undefined} (let Next.js handle it based on current locale)

Benefits

  • ✅ Works with languageEmbedding="always" - no double locale prefixes
  • ✅ Works with languageEmbedding="asNeeded" - locale is preserved
  • ✅ Backwards compatible - existing behavior unchanged for URLs that already have locale
  • ✅ No configuration needed - automatic detection based on Next.js config

Testing Details

  • Unit tests added for locale detection logic
  • Tested with languageEmbedding="always" configuration - no double prefixes
  • Tested with languageEmbedding="asNeeded" configuration - locale preserved correctly

Test Cases

  1. href with locale prefix (/sv/about) + current locale sv → navigates to /sv/about
  2. href without locale prefix (/about) + current locale sv → navigates to /sv/about
  3. href with different locale prefix (/en/about) + current locale sv → navigates to /en/about
  4. External URLs → unchanged behavior ✅

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • This PR follows the Contribution Guide
  • Changelog updated
  • Upgrade guide entry added (not needed - backwards compatible)

…t languageEmbedding configurations

- Auto-detect if href already contains a locale prefix using router.locales
- Set locale={false} only when href has locale (prevents double-prefixing)
- Set locale={undefined} when href has no locale (lets Next.js handle it)

This supports both languageEmbedding='always' and languageEmbedding='asNeeded' Sitecore configurations without requiring manual configuration.
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