react-locales
v1.0.29
Published
Simple framework for translations
Downloads
34
Readme
Use Locale
Simple framework for translations. Statically typed.
Installation
- The full thing
npm i react-locales @moveread/router-tools preferred-locale
yarn add react-locales @moveread/router-tools preferred-locale
- Simplified, w/o language detection nor routes
npm i react-locales
yarn add react-locales
Usage
- Define what locales you want
// locales.ts
import { make } from 'react-locales'
import { provider } from 'react-locales/provider'
export const framework = make(['en', 'es', 'ca'], { fallback: 'en' })
export const { LocaleCtx, useLocale, locales, DefaultProvider } = framework
export const LocaleProvider = provider(framework)
// or use the `DefaultProvider` with the basic installation
- Wrap app in provider
// {main|index}.tsx
import { LocaleProvider } from './locales.ts'
ReactDOM.createRoot(document.getElementById('root')!).render(
<LocaleProvider defaultLocale='en'>
<App />
</LocaleProvider>
)
- Define translations where they're used or elsewhere
// MyComponent.tsx
import { useLocale, t } from './locales.ts'
const subtitle = t({
en: 'Hello',
es: 'Hola',
ca: 'Hola',
...
})
function MyComponent() {
const { t, setLocale } = useLocale()
const title = t({
en: '...',
ca: '...',
es: '...',
fr: '...',
it: '...'
})
return (
<div>
<h1>{title}</h1>
<h2>{t(subtitle)}</h2>
<button onClick={() => setLocale('en')}>EN</button>
</div>
)
}
Advanced Usage
react-locales/provider
is just one of the infinitely many possible provider combinations. To select the default locale, it uses the following, in order:
- The
:locale
route parameter localStorage.getItem('locale')
- The detected
preferredLocale()
(usingpreferred-locale
) - The
defaultLocale
prop
But you can stack these arbitrarily, even passing your own provider. For example, let's say you want to give localStorage
priority over the route parameter:
import { make } from 'react-locales'
import { localStorageProvider } from 'react-locales/local'
import { routedProvider } from 'react-locales/routed'
export const framework = make(['en', 'es', 'ca'], { fallback: 'en' }) // eslint-disable-line
export const { LocaleCtx, useLocale, locales, DefaultProvider, makeT, t } = framework // eslint-disable-line
export function LocaleProvider() {
return (
<DefaultProvider defaultLocale='en'>
<RoutedProvider>
<LocalStorageProvider>
{children}
</LocalStorageProvider>
</RoutedProvider>
</DefaultProvider>
)
}
As they're written, each provider uses the wrapping context as a fallback default So, you can define a custom provider as:
function MyLocaleProvider({ children }) {
const { locale: defaultLocale } = useLocale()
const [myLocale, setMyLocale] = useState(defaultLocale)
return (
<LocaleCtx.Provider value={{ locale: myLocale, setLocale: setMyLocale, t: makeT(myLocale) }}>
{children}
</LocaleCtx.Provider>
)
}
And then nest it at whatever level you want according to the required priority, e.g:
<DefaultProvider defaultLocale='en'>
<MyLocaleProvider>
<RoutedProvider>
<LocalStorageProvider>
{children}
</LocalStorageProvider>
</RoutedProvider>
</MyLocaleProvider>
</DefaultProvider>