The purpose of this library is to provide ability to support i18next library in Solid applications
with <TransProvider />
and <Trans />
components.
Installation:
npm install @mbarzda/solid-i18next i18next --save
<TransProvider />
must wrap Solid application's most parent component (e.g. <App />
). <Trans />
component's key
property is mandatory.
Default value can be wrapped with <Trans />
component or set with options
or children
property.
// esm
import { TransProvider, Trans } from '@mbarzda/solid-i18next';
// cjs
const { TransProvider, Trans } = require('@mbarzda/solid-i18next');
render(() => (
<TransProvider>
<App>
<Trans key="greeting" />
{/* or */}
<Trans key="greeting">Hello!</Trans>
{/* or */}
<Trans key="greeting" options={{ defaultValue: 'Hello!' }} />
{/* or */}
<Trans key="greeting" options="Hello!" />
{/* or */}
<Trans key="greeting" children="Hello!" />
</App>
</TransProvider>
));
Resources can be added on initialization with options
property in <TransProvider />
or
by calling addResources
method from TransContext
, which can be got with useTransContext()
.
import { Trans, TransProvider, useTransContext } from '@mbarzda/solid-18next';
const resources = {
lt: {...},
pl: {...},
};
render(() => <TransProvider options={{ resources }} children={<App />} />, container);
{/* or */}
const Component = () => {
const [, actions] = useTransContext();
actions.addResources('lt', 'translation', resources.lt);
actions.addResources('pl', 'translation', resources.pl);
return <Trans key="greeting">Hello!</Trans>;
};
Default language can be provided to <TransProvider />
with lng
or options
property.
options.lng
overrides lng
property.
<TransProvider lng="lt" children={...} />
<TransProvider options={{lng: 'pl'}} children={...} />
To change a language you need to use TransContext
and call changeLanguage
.
import { useTransContext } from '@mbarzda/solid-18next';
const Component = () => {
const [, { changeLanguage }] = useTransContext();
return (
<article>
<button type="button" onClick={() => changeLanguage('en')}>
English
</button>
<button type="button" onClick={() => changeLanguage('lt')}>
Lietuvių
</button>
</article>
);
};
i18next have t
function, which is essential and sometimes there is need to use it without <Trans />
component.
TransContext
provides it in case you need it.
const Component = () => {
const [t] = useTransContext();
const messages = {
get greeting() {
return t('greeting', 'Hello!');
},
get bye() {
return t('bye', 'Bye!');
},
};
return <>{isLogin() ? messages.greeting : messages.bye}</>;
};
i18next has many plugins and utils.
They can be loaded with i18next.use
method. You need to have an i18next
instance for that.
There is possible to use default i18next
instance or create a separate one.
<TransProvider />
initializes i18next (i18next.init()
) under the hood, so you need to create an instance before initialization of the component.
Plugins options and other i18next options must be provided with options
property.
import { TransProvider, Trans } from '@mbarzda/solid-i18next';
import i18next from 'i18next';
import HttpBackend from 'i18next-http-backend';
// Use plugin with default instance.
render(() => {
i18next.use(HttpBackend);
const backend = { loadPath: '/locales/{{lng}}/{{ns}}.json' };
return (
<TransProvider options={{ backend }}>
<App>
<Trans key="greeting">Hello!</Trans>
</App>
</TransProvider>
);
});
// Use plugin with separate instance.
// New instance must be provided to `TransProvider` with `instance` property.
render(() => {
const instance = i18next.createInstance();
instance.use(HttpBackend);
const backend = { loadPath: '/locales/{{lng}}/{{ns}}.json' };
return (
<TransProvider instance={instance} options={{ backend }}>
<App>
<Trans key="greeting">Hello!</Trans>
</App>
</TransProvider>
);
});
If there is need something more than this library provides, you can get i18next instance from TransContext
and to do something with it.
If you are using default instance, you also can use i18next
global.
const Component = () => {
const [, { getI18next }] = useTransContext();
getI18next().on('loaded', () => {...});
{/* or, if you are using default instance */}
i18next.on('loaded', () => {...});
return <></>;
};
Default interpolation uses {{
and }}
as prefix and suffix. Solid uses {
and }
for properties propagation. In that case
messages with default interpolation must be put as string. Placeholder values should be provided
through options
property of <Trans />
component.
<Trans key="greeting" options={{ name: 'John Doe' }}>
{'Hello {{name}}!'}
</Trans>
i18next also allows to define custom interpolation prefix and suffix.
const resources = { lt: { greeting: 'Labas, ##name##!' } };
const interpolation = { prefix: '##', suffix: '##' };
<TransProvider options={{ interpolation, resources }}>
<Trans key="greeting" options={{ name: 'John Doe' }}>
Hello ##name##!
</Trans>
</TransProvider>;
This library supports nested JSX messages, like react-i18next. If you want use this feature, you need to install html-parse-string separately:
npm i html-parse-string
Then you can define your translation strings, like described in How to get the correct translation string?.
const resources = {
lt: { translation: { greeting_nested: '<0>Sveiki, {{fullName}}! </0><1>Tavo profilis</1>.' } },
};
<TransProvider options={{ interpolation, resources }}>
<Trans key="greeting_nested" options={{ name: 'John Doe' }}>
{'Hello {{ name }}! '}
<a href="/profile">Your Profile</a>.
</Trans>
</TransProvider>;
Keep in mind that elements, with interpolation, must be a string, e.g: 'Hello {{name}}!'
.
i18next provides default pluralization feature. Note, that pluralization keys were changed since i18next@21
.
Translation keys may be inconsistent through different languages and you would prefer something like ICU format.
For that case I recommend i18next-icu plugin. Note, that default interpolation would change.
npm i i18next-icu
import i18next from 'i18next';
import ICU from 'i18next-icu';
const instance = i18next.createInstance();
instance.use(ICU);
const resources = {
lt: {
photos: 'Tu { numPhotos, plural, 0 {neturi nuotraukų} other {turi { numPhotos, plural, one {# nuotrauką} few {# nuotraukas} other {# nuotraukų} }} }.'
}
}
<TransProvider instance={instance} options={{ resources }}>
<Trans key="photos" options={{ numPhotos: 10 }}>
{'You have {numPhotos, plural, =0 {no photos} =1 {one photo} other {# photos}}.'}
</Trans>
</TransProvider>;
Property | Description | Required |
---|---|---|
instance | i18next instance, see: i18n | No |
lng | default language, options.lng overrides it |
No |
options | i18next init options, see: InitOptions | No |
Property | Description | Required |
---|---|---|
key | translation key or keys TFunctionKeys | Yes |
options | t function's options, see: TOptions | string | No |
useTransContext
function returns TransContext
as array: [TFunction, TransProviderActions]
.
The first item is t
function, second - the list of actions, which are listed below.
TransProviderActions
Function | Description |
---|---|
addResources( lng, ns, resources, bundleOptions?: { deep?; overwrite? } ) |
adds translation resources, see addResourcesBundle |
changeLanguage(lng) | changes language and sets new t function |
getI18next | returns i18next instance, see i18n |