76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { usePage } from '@inertiajs/react';
|
|
import { useLocale } from './useLocale';
|
|
|
|
type LocalizedPathInput = string | null | undefined;
|
|
|
|
export const useLocalizedRoutes = () => {
|
|
const { props } = usePage<{ supportedLocales?: string[] }>();
|
|
const locale = useLocale();
|
|
const supportedLocales = props.supportedLocales ?? [];
|
|
|
|
const fallbackLocale = (() => {
|
|
if (locale && supportedLocales.includes(locale)) {
|
|
return locale;
|
|
}
|
|
|
|
if (supportedLocales.length > 0) {
|
|
return supportedLocales[0];
|
|
}
|
|
|
|
return 'de';
|
|
})();
|
|
|
|
const pathRewrites: Record<string, Record<string, string>> = {
|
|
'/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 rewriteForLocale = (path: string, targetLocale: string): string => {
|
|
const key = path === '' ? '/' : path;
|
|
const normalizedKey = key.startsWith('/') ? key : `/${key}`;
|
|
const rewrites = pathRewrites[normalizedKey] ?? {};
|
|
|
|
return rewrites[targetLocale] ?? normalizedKey;
|
|
};
|
|
|
|
const localizedPath = (path: LocalizedPathInput, targetLocale?: string) => {
|
|
if (typeof path !== 'string' || path.trim().length === 0) {
|
|
console.error('[useLocalizedRoutes] Invalid path input detected', {
|
|
path,
|
|
locale,
|
|
stack: new Error().stack,
|
|
});
|
|
|
|
return `/${fallbackLocale}`;
|
|
}
|
|
|
|
const nextLocale = targetLocale && supportedLocales.includes(targetLocale)
|
|
? targetLocale
|
|
: fallbackLocale;
|
|
|
|
const trimmed = path.trim();
|
|
const [rawPath, rawQuery] = trimmed.split('?');
|
|
const normalizedPath = rawPath.startsWith('/') ? rawPath : `/${rawPath}`;
|
|
const rewritten = rewriteForLocale(normalizedPath, nextLocale);
|
|
|
|
const base = rewritten === '/' ? `/${nextLocale}` : `/${nextLocale}${rewritten}`;
|
|
const sanitisedBase = base.replace(/\/{2,}/g, '/');
|
|
const query = rawQuery ? `?${rawQuery}` : '';
|
|
|
|
return `${sanitisedBase}${query}`;
|
|
};
|
|
|
|
return { localizedPath };
|
|
};
|