fixed language switching in the frontend
This commit is contained in:
29
resources/js/lib/__tests__/localizedPath.test.ts
Normal file
29
resources/js/lib/__tests__/localizedPath.test.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildLocalizedPath, defaultLocaleRewrites } from '../localizedPath';
|
||||
|
||||
describe('buildLocalizedPath', () => {
|
||||
const supported = ['de', 'en'];
|
||||
|
||||
it('prefixes path with locale', () => {
|
||||
expect(buildLocalizedPath('/packages', 'en', supported)).toBe('/en/packages');
|
||||
expect(buildLocalizedPath('/packages', 'de', supported)).toBe('/de/packages');
|
||||
});
|
||||
|
||||
it('applies rewrite rules between locales', () => {
|
||||
expect(buildLocalizedPath('/kontakt', 'en', supported, 'de', defaultLocaleRewrites)).toBe('/en/contact');
|
||||
expect(buildLocalizedPath('/contact', 'de', supported, 'de', defaultLocaleRewrites)).toBe('/de/kontakt');
|
||||
});
|
||||
|
||||
it('preserves query strings', () => {
|
||||
expect(buildLocalizedPath('/contact?ref=ad', 'de', supported)).toBe('/de/kontakt?ref=ad');
|
||||
});
|
||||
|
||||
it('falls back to default locale when target not supported', () => {
|
||||
expect(buildLocalizedPath('/demo', 'fr', supported)).toBe('/de/demo');
|
||||
});
|
||||
|
||||
it('handles empty or invalid paths gracefully', () => {
|
||||
expect(buildLocalizedPath('', 'en', supported)).toBe('/de');
|
||||
expect(buildLocalizedPath(undefined, 'en', supported)).toBe('/de');
|
||||
});
|
||||
});
|
||||
57
resources/js/lib/localizedPath.ts
Normal file
57
resources/js/lib/localizedPath.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
export type LocaleRewriteMap = Record<string, Record<string, string>>;
|
||||
|
||||
export const defaultLocaleRewrites: LocaleRewriteMap = {
|
||||
'/': {},
|
||||
'/kontakt': { en: '/contact' },
|
||||
'/contact': { de: '/kontakt' },
|
||||
'/so-funktionierts': { en: '/how-it-works' },
|
||||
'/how-it-works': { de: '/so-funktionierts' },
|
||||
'/anlaesse': { en: '/occasions' },
|
||||
'/anlaesse/hochzeit': { en: '/occasions/wedding' },
|
||||
'/anlaesse/geburtstag': { en: '/occasions/birthday' },
|
||||
'/anlaesse/firmenevent': { en: '/occasions/corporate-event' },
|
||||
'/anlaesse/konfirmation': { en: '/occasions/confirmation' },
|
||||
'/occasions/wedding': { de: '/anlaesse/hochzeit' },
|
||||
'/occasions/birthday': { de: '/anlaesse/geburtstag' },
|
||||
'/occasions/corporate-event': { de: '/anlaesse/firmenevent' },
|
||||
'/occasions/confirmation': { de: '/anlaesse/konfirmation' },
|
||||
};
|
||||
|
||||
const sanitizePath = (input: string): string => {
|
||||
if (!input || input.trim().length === 0) {
|
||||
return '/';
|
||||
}
|
||||
|
||||
const withLeading = input.startsWith('/') ? input : `/${input}`;
|
||||
const withoutTrailing = withLeading.replace(/\/{2,}/g, '/');
|
||||
|
||||
return withoutTrailing;
|
||||
};
|
||||
|
||||
export const buildLocalizedPath = (
|
||||
path: string | null | undefined,
|
||||
targetLocale: string | undefined,
|
||||
supportedLocales: string[],
|
||||
defaultLocale = 'de',
|
||||
rewrites: LocaleRewriteMap = defaultLocaleRewrites,
|
||||
): string => {
|
||||
const fallbackLocale = supportedLocales.length > 0 ? supportedLocales[0] : defaultLocale;
|
||||
const nextLocale = targetLocale && supportedLocales.includes(targetLocale)
|
||||
? targetLocale
|
||||
: fallbackLocale;
|
||||
|
||||
if (typeof path !== 'string' || path.trim().length === 0) {
|
||||
return `/${fallbackLocale}`;
|
||||
}
|
||||
|
||||
const trimmed = path.trim();
|
||||
const [rawPath, rawQuery] = trimmed.split('?');
|
||||
const normalizedPath = sanitizePath(rawPath);
|
||||
const rewritesForPath = rewrites[normalizedPath] ?? {};
|
||||
const rewrittenPath = rewritesForPath[nextLocale] ?? normalizedPath;
|
||||
const base = rewrittenPath === '/' ? `/${nextLocale}` : `/${nextLocale}${rewrittenPath}`;
|
||||
const sanitisedBase = base.replace(/\/{2,}/g, '/');
|
||||
const query = rawQuery ? `?${rawQuery}` : '';
|
||||
|
||||
return `${sanitisedBase}${query}`;
|
||||
};
|
||||
Reference in New Issue
Block a user