fix(i18n): improve language path handling and prevent unnecessary redirects
- Fix edge cases in path processing for language switching - Add checks to prevent redirects to the same page - Update documentation to reflect current project structure
This commit is contained in:
@@ -40,8 +40,10 @@ export default function LanguageSwitcher({ lang: initialLang }: LanguageSwitcher
|
||||
|
||||
// Check if the first part of the path is a known language code
|
||||
if (currentPathParts.length > 0 && Object.keys(i18nLanguages).includes(currentPathParts[0])) {
|
||||
// If the first part is a language code, remove it to get the base path
|
||||
basePath = '/' + currentPathParts.slice(1).join('/');
|
||||
} else {
|
||||
// If no language code in path, use the current path as base
|
||||
basePath = currentPathname;
|
||||
}
|
||||
|
||||
@@ -49,7 +51,9 @@ export default function LanguageSwitcher({ lang: initialLang }: LanguageSwitcher
|
||||
if (!basePath.startsWith('/')) {
|
||||
basePath = '/' + basePath;
|
||||
}
|
||||
// Fix for empty paths
|
||||
if (basePath === '//') basePath = '/';
|
||||
if (basePath === '') basePath = '/';
|
||||
|
||||
let newPath;
|
||||
// If the target language is the default language and prefixDefaultLocale is false (as per our astro.config.mjs)
|
||||
@@ -63,9 +67,13 @@ export default function LanguageSwitcher({ lang: initialLang }: LanguageSwitcher
|
||||
|
||||
// Clean up double slashes, just in case
|
||||
newPath = newPath.replace(/\/\/+/g, '/');
|
||||
if (newPath === '') newPath = '/'; // Handle case where basePath might be empty resulting in just /zh or /en
|
||||
|
||||
window.location.href = newPath;
|
||||
// Handle case where basePath might be empty resulting in just /zh or /en
|
||||
if (newPath === '') newPath = '/';
|
||||
|
||||
// Prevent unnecessary redirects to the same page
|
||||
if (newPath !== currentPathname) {
|
||||
window.location.href = newPath;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -23,30 +23,29 @@ export function getLocalizedPath(path: string, lang: Lang | undefined): string {
|
||||
const currentLang = lang || defaultLang;
|
||||
const basePath = import.meta.env.BASE_URL === '/' ? '' : import.meta.env.BASE_URL;
|
||||
|
||||
// Astro's i18n routing handles prefixing automatically based on astro.config.mjs settings.
|
||||
// We just need to ensure the path is correctly formed relative to the base.
|
||||
// If a language is explicitly provided and it's not the default,
|
||||
// and prefixDefaultLocale is false (meaning default lang has no prefix),
|
||||
// we might need to add it. However, Astro typically handles this.
|
||||
// For now, let's assume Astro's routing takes care of the prefix.
|
||||
// This function might become simpler or even unnecessary depending on how LanguageSwitcher is used.
|
||||
|
||||
let newPath = path;
|
||||
// Ensure path starts with a slash if it's not an external URL
|
||||
if (!newPath.startsWith('/') && !newPath.match(/^https?:\/\//)) {
|
||||
newPath = `/${newPath}`;
|
||||
}
|
||||
|
||||
// If prefixDefaultLocale is false (default in our config) and currentLang is not defaultLang,
|
||||
// Astro will expect /zh/path. If currentLang is defaultLang, it expects /path.
|
||||
// If prefixDefaultLocale is true, all locales get a prefix: /en/path, /zh/path.
|
||||
// Remove any existing language prefix from the path
|
||||
const pathParts = newPath.split('/').filter(p => p);
|
||||
if (pathParts.length > 0 && Object.keys(languages).includes(pathParts[0])) {
|
||||
newPath = '/' + pathParts.slice(1).join('/');
|
||||
}
|
||||
|
||||
// Given our astro.config.mjs: prefixDefaultLocale: false
|
||||
// If lang is 'zh', the path should be /zh/your-path
|
||||
// If lang is 'en' (default), the path should be /your-path
|
||||
// Astro's <a href> or Astro.redirect should handle this correctly when given a root-relative path.
|
||||
// This function's main job is to ensure the base path and the target path are combined correctly.
|
||||
// If the path is empty after processing, make it root
|
||||
if (newPath === '') newPath = '/';
|
||||
|
||||
// Add language prefix if needed
|
||||
// If currentLang is not the default language, add the language prefix
|
||||
if (currentLang !== defaultLang) {
|
||||
newPath = `/${currentLang}${newPath}`;
|
||||
}
|
||||
// No prefix needed for default language as per astro.config.mjs (prefixDefaultLocale: false)
|
||||
|
||||
// Combine with base path and clean up any double slashes
|
||||
const fullPath = `${basePath}${newPath}`;
|
||||
return fullPath.replace(/\/\/+/g, '/'); // Clean up any double slashes
|
||||
return fullPath.replace(/\/\/+/g, '/');
|
||||
}
|
||||
Reference in New Issue
Block a user