astrofy
astrofy copied to clipboard
Switching languages
I'm trying to implement switching languages, I follow a couple of guides of i18n, but neither way works, can you help me please? I'm using utils.ts and ui.ts. in the basic url everything works (localhost:4321) but using language url get 404 error (localhost:4321/en/ for example)
This is the utils.ts:
import { ui } from "./ui";
export const LANGUAGES = {
en: "English",
de: "Deutsch",
es: "Español",
};
export const DEFAULT_LANG = "en";
export type UiType = keyof typeof ui;
export function getLangFromUrl(url: URL) {
const [, lang] = url.pathname.split("/");
if (lang in ui) return lang as UiType;
return DEFAULT_LANG;
}
export function useTranslations(lang?: UiType) {
return function t(
key: keyof (typeof ui)[typeof DEFAULT_LANG],
...args: any[]
) {
let translation = ui[lang ?? DEFAULT_LANG][key] || ui[DEFAULT_LANG][key];
if (args.length > 0) {
for (let i = 0; i < args.length; i++) {
translation = translation.replace(`{${i}}`, args[i]);
}
}
return translation;
};
}
export function pathNameIsInLanguage(pathname: string, lang: UiType) {
return (
pathname.startsWith(`/${lang}`) ||
(lang === DEFAULT_LANG && !pathNameStartsWithLanguage(pathname))
);
}
function pathNameStartsWithLanguage(pathname: string) {
let startsWithLanguage = false;
const languages = Object.keys(LANGUAGES);
for (let i = 0; i < languages.length; i++) {
const lang = languages[i];
if (pathname.startsWith(`/${lang}`)) {
startsWithLanguage = true;
break;
}
}
return startsWithLanguage;
}
export function getLocalizedPathname(pathname: string, lang: UiType) {
if (pathNameStartsWithLanguage(pathname)) {
const availableLanguages = Object.keys(LANGUAGES).join("|");
const regex = new RegExp(`^\/(${availableLanguages})`);
return pathname.replace(regex, `/${lang}`);
}
return `/${lang}${pathname}`;
}