This project is designed to be used in SPAs (Single page applications) with no server side rendering.
If you're not using either Vite or Create-React-App, i18nifty is probably not the best choice for you.
yarnadd--devi18nifty
npminstall--save-devi18nifty
bunadd--devi18nifty
pnpmadd--save-devi18nifty
Before diving into the thick of things let's make sure you can do local imports relative to your src directory. It will prevent you from having to write imports like:
import { useTranslations } from "../../../../i18n";
import { createI18nApi, declareComponentKeys } from"i18nifty";export { declareComponentKeys };//List the languages you with to supportexportconstlanguages= ["en","fr"] asconst;//If the user's browser language doesn't match any //of the languages above specify the language to fallback to: exportconstfallbackLanguage="en";exporttypeLanguage=typeof languages[number];exporttypeLocalizedString=Parameters<typeof resolveLocalizedString>[0];exportconst { useTranslation,resolveLocalizedString,useLang,$lang,useResolveLocalizedString,/** For use outside of React */getTranslation} = createI18nApi<|import ("components/MyComponent").I18n|import ("components/MyOtherComponent").I18n>()( { languages, fallbackLanguage }, {"en": {"MyComponent": {"greating": ({ who })=>`Hello ${who}`,"how are you":"How are you feeling today?","learn more": ({ href }) => ( <> Learn more about <ahref={href}>this website</a>. </> ) },"MyOtherComponent": {"open":"Open","delete":"Delete","unread messages": ({ howMany })=> {switch(howMany){case0: return`You don't have any new message`;case1: return`You have a new message`;default: return`You have ${howMany} new messages`; } } }, },/* spell-checker: disable */"fr": {"MyComponent": {"greating": ({ who })=>`Bonjour ${who}`,"how are you":"Comment vous sentez vous au jour d'hui?","learn more": ({ href }) => ( <> En savoir plus à propos de <ahref={href}>ce site web</a>. </> ) },"MyOtherComponent": {"open":"Ouvrir","delete":"Supprimer",//We will translate this later, for now, fallback to english"unread messages":undefined }, }/* spell-checker: enable */ });
Now go back to your component and use the translation function:
MyComponent.ts
+import { useTranslation, declareComponentKeys } from "i18n"; //You can import it like that thanks to baseUrl type Props = { name: string; }; export function MyComponent(props: Props) { const { name } = props;+ const { t } = useTranslation({ MyComponent }); return ( <>- <h1>Hello {name}</h1>+ <h1>{t("greeting", { who: name })}</h1>- <h3>How are you feeling today?</h3>+ <h3>{t("how are you")}</h3>- <p>- Click <a href="https://example.com">hrere</a> to - learn more about this website- </p>+ <p>{t("learn more", { href: "https://example.com" })}</p> </> ); } const { i18n } = declareComponentKeys< | { K: "greating"; P: { who: string; } } | "how are you" | { K: "learn more"; P: { href: string; }; R: JSX.Element } >()({ MyComponent }); export type I18n = typeof i18n;
And so forth for your other components.
Now this setup is great if you're supporting only a few languages and you're app does not contain a lot of text. As you app grow however, you probably want to enable only only the resources for a specific language to be dowloaded.