Skip to content

fix(i18n): prevent duplicate locale directories and incorrect redirects for existing translations #13650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

asieradzk
Copy link

fix(i18n): prevent duplicate locale directories and incorrect redirects for existing translations

Description

This PR fixes an issue with i18n fallback routes where:

  1. Duplicate locale directories were being created (e.g., /es/es/ instead of just /es/)
  2. Unnecessary redirect files were generated for pages that already have translations

The bug occurs when using i18n with:

  1. fallback: { "es": "en" } configuration
  2. prefixDefaultLocale: false in routing options

When these settings are used, the build process incorrectly generates paths with duplicate locale prefixes for fallback routes, creating directories like /es/es/test/item1/ with redirect files even when those pages have actual translations at /es/test/item1/.

Fix

The fix modifies the generatePath function to:

  1. Detect paths with duplicate locale prefixes in fallback routes
  2. Normalize these paths by removing the duplicate prefix
  3. Use the normalized paths throughout the rendering and file output process
  4. Check both original and normalized paths when determining if a translation exists
// Key part of the fix - normalize pathname to remove duplicate locale prefixes
let normalizedPathname = pathname;
if (route.type === 'fallback' && config.i18n) {
  const pathParts = pathname.split('/').filter(Boolean);
  if (pathParts.length >= 2 && pathParts[0] === pathParts[1]) {
    normalizedPathname = '/' + pathParts.slice(1).join('/');
    logger.debug('build', `Fixed duplicate locale path: ${pathname}${normalizedPathname}`);
  }
}

Testing

I've verified the fix using the reproduction repo: https://github.com/asieradzk/i18ntest

With the fixed version of Astro:

  • No /es/es/ directories are created
  • No incorrect redirects are generated for pages that already have translations
  • Fallback routes still work correctly for pages that need them

The fix resolves the issue without requiring users to change their i18n configuration, allowing both:

  • Proper fallback routes for missing pages
  • No duplicate locale prefixes in output directories

Related Issues

Fixes #13638
#13638

Copy link

changeset-bot bot commented Apr 17, 2025

🦋 Changeset detected

Latest commit: 380a968

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added the pkg: astro Related to the core `astro` package (scope) label Apr 17, 2025
Copy link

codspeed-hq bot commented Apr 17, 2025

CodSpeed Performance Report

Merging #13650 will not alter performance

Comparing asieradzk:fix-i18n-duplicate-locale-paths (380a968) with main (6744842)

Summary

✅ 6 untouched benchmarks

Comment on lines +500 to +501
// Found duplicate locale - e.g., /es/es/
normalizedPathname = '/' + pathParts.slice(1).join('/');
Copy link
Member

@ematipico ematipico Apr 18, 2025

Choose a reason for hiding this comment

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

If we arrive here es/es/, it means that the bug is coming from somewhere else. It means we are "patching" something broken, instead of fixing it. Have you figured out where the incorrect pathname is coming from?

Copy link
Author

Choose a reason for hiding this comment

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

I can't locate it Maybe a second pair of eyes?

To summarise where I looked:

  1. Patched the final generation step in generate.ts
  2. From there I checked path generator function getRouteGenerator in manifest/generator.ts
    Confirmed it works correctly based on the input segments it receives. It only produces /es/es/... if given incorrect segments starting with [[es], [lang], ...].
  3. Then I looked at RouteData logic in manifest/create,ts but the initial route was created correctly ([[lang], ...])

What could this be? The segments data appears to be correctly created and incorrectly modified after initial creation but before the final path generation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg: astro Related to the core `astro` package (scope)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

i18n without baked-in redirects?
2 participants