@maximux13/svelte-i18next
v2.0.0
Published
Add internationalization (i18n) support to your SvelteKit project
Downloads
19
Readme
Svelte.i18next
Table of Contents
Introduction
Svelte.i18next is a library that makes it easy to add internationalization (i18n) support to your SvelteKit. It provides a simple interface for configuring i18next and managing translations.
Installation
To install Svelte.i18next, simply run:
pnpm install @maximux13/svelte-i18next i18next i18next-browser-languagedetector i18next-http-backend
Configuration
To set up Svelte.i18next in your project, you'll need to go through the following configuration steps:
i18n Config File
Step 1: Create an i18n Configuration File
Create a file named src/i18n.ts and populate it with the i18n configuration. Here is an example:
export default {
supportedLngs: ['en', 'es'], // Supported languages
fallbackLng: 'en', // Fallback language
defaultNS: 'common' // Default namespace
};
Locale Files
Step 2: Create Locale Files
Create locale JSON files inside the static/locales/{lng}/{ns}.json directory. Replace {lng} with the language code (e.g., en, es) and {ns} with the namespace (e.g., common).
Example content for static/locales/en/common.json
:
{
"title": "Svelte i18next - Hello {{name}}!",
"world": "World"
}
Server Initialization
Step 3: Initialize SvelteI18next Instance
In your src/i18n.server.ts, initialize a new SvelteI18next instance as shown below:
// src/i18n.server.ts
import Backend from 'i18next-http-backend';
import { SvelteI18next } from '@maximux13/svelte-i18next';
import i18n from './i18n';
const i18next = new SvelteI18next({
i18next: {
...i18n,
backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' }
},
backend: Backend
});
export default i18next;
Add Server Hook
Step 4: Add Server Hook
Create a server hook to initialize i18next in src/hook.server.ts:
import type { Handle } from '@sveltejs/kit';
import { createInstance } from 'i18next';
import Backend from 'i18next-http-backend';
import i18n from './i18n';
import i18next from './i18n.server';
import { createFetchRequest } from '@maximux13/svelte-i18next';
export const handle: Handle = async (props) => {
const { event, resolve } = props;
const instance = createInstance();
const lng = await i18next.getLocale(event);
const ns = await i18next.getNamespaces(event);
const request = createFetchRequest(event.fetch);
await instance
.use(Backend)
.init({ ...i18n, backend: { loadPath: '/locales/{{lng}}/{{ns}}.json', request }, lng, ns });
const initOptions = i18next.getInitOptions(instance);
event.locals.i18n = Object.assign(instance, { initOptions });
return resolve(event, {
transformPageChunk: ({ html }) => html.replace('<html lang="en">', `<html lang="${lng}">`)
});
};
Client Initialization
Step 5: Client Instance Setup
Finally, set up a client instance to expose i18next functionalities in your code. For example, in src/routes/+layout.server.ts and src/routes/+layout.ts:
src/routes/+layout.server.ts
import type { LayoutServerLoad } from './$types';
export const load: LayoutServerLoad = async ({ locals, depends }) => {
depends('i18n:lng');
return { i18n: locals.i18n.initOptions };
};
src/routes/+layout.ts
import type { LayoutLoad } from './$types';
import i18next from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { createStore } from '@maximux13/svelte-i18next';
export const load: LayoutLoad = async ({ data }) => {
i18next
.use(Backend)
.use(LanguageDetector)
.init({
...data.i18n,
detection: { caches: ['cookie'], order: ['htmlTag'] }
});
const store = createStore(i18next);
return { i18n: store };
};
Usage
Once you've completed the Configuration steps, you can start using Svelte.i18next in your Svelte components and server-side code.
In Svelte Components
You can use the i18n store in your Svelte components to access translations. Here's an example:
<script lang="ts">
export let data;
$: ({ i18n } = data);
</script>
<h1>{$i18n.t('title', { name: $i18n.t('world') })}</h1>
In Svelte Server Code
You can also use i18n functionalities in your server-side code. For instance:
// Example in a server-side Svelte file
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals, depends }) => {
depends('i18n:lng');
return { world: locals.i18n.t('world') };
};
Note: We use depends('i18n:lng');
to invalidate the data when the language changes. This invalidation is triggered by the i18n store when calling $i18n.changeLanguage
method.
Advanced Features
Managing Namespaces
To manage namespaces, specify which namespaces should be loaded on each page by setting the ns
property in your page or layout configuration. For example:
// src/routes/page.(server).ts
export const config = {
ns: ['page']
};
This will load the page
namespace for the corresponding page. You can also use an array to load multiple namespaces:
export const config = {
ns: ['page', 'otherNamespace']
};
getFixedT
The getFixedT
function allows you to use a fixed translation function in your server-side code. Example:
// Inside a server-side Svelte file
export function GET(event) {
const t = i18next.getFixedT(event, { locale: 'en', namespaces: 'test', options: {} });
return new Response(t('title'));
}
Trans Component
The Trans
component provides a convenient way to include complex translations with HTML tags and Svelte components.
Props
| Prop | Type | Description | | ------------ | ------------ | --------------------------------------------------------- | | i18n | i18n | i18n store instance (required if not wrapped in provider) | | t | i18n.t | Custom translation function | | tOptions | object | Options to pass to the translation function | | key | string | Translation key | | values | object | Values for interpolation | | count | number | Count for pluralization | | context | string | Context for pluralization | | ns | string | Namespace | | defaultValue | string | Default value | | components | array/object | Components to be used for interpolation |
For detailed usage of the Trans
component, please refer to this section.
Trans Component Usage
The Trans
component is designed to handle more complex translations that may include HTML tags, variables, and even Svelte components. Below are some examples and use-cases where you might find the Trans
component useful.
Basic Usage
At its simplest, the Trans
component can be used to translate static text.
<Trans key="hello_world" />
With Variables
You can also pass variables for interpolation.
<Trans key="greeting" values={{ name: 'John' }} />
With HTML Tags
HTML tags can be included in the translation string and mapped to actual HTML tags using the components
prop.
Example translation string: Click <link>here</link>
<Trans key="click_here" components={{ link: 'a' }} />
Different Ways to Declare Components
As a String
You can declare the component as a string, representing the HTML tag name.
<Trans key="click_here" components={{ link: 'a' }} />
As an Object
You can also declare the component as an object, providing more options including props.
<Trans
key="click_here"
components={{
link: { component: 'a', props: { href: '/page' } }
}}
/>
As a Svelte Component
You can use a Svelte component directly and pass props to it.
<Trans
key="click_here"
components={{
link: { component: CustomLink, props: { href: '/page' } }
}}
/>
components
as an Array or Object
The components
prop can either be an array or an object, depending on your needs.
As an Array
When declared as an array, the components will replace the tags in the order they appear in the translation string.
Translation string: Hello <0>World</0> and <1>universe</1>
<Trans key="key" components={['strong', 'i']} />
As an Object
When declared as an object, you can use meaningful keys to represent your tags, making your code more readable.
Translation string: Hello <bold>World</bold> and <italic>universe</italic>
<Trans key="key" components={{ bold: 'strong', italic: 'i' }} />
Passing Props to Components
You can pass additional props to the components by using the object notation.
<Trans
key="click_here"
components={{
bold: { component: 'strong', props: { class: 'font-semibold' } },
link: { component: CustomLink, props: { href: '#/' } }
}}
/>
Advanced Props
The Trans
component also accepts a number of advanced props like count
, context
, defaultValue
, and so on.
<Trans key="itemCount" count={5} />
This could translate to "5 items" depending on your translation string and pluralization rules.
Acknowledgements
This library was inspired by the excellent work of SergioDXA on the remix-i18next library. Special thanks to all contributors and users for their support and feedback.
Troubleshooting
If you encounter any issues while using Svelte.i18next, please refer to the following resources for guidance:
- Documentation: Make sure to read the documentation carefully for any configuration or usage details you might have missed.
- GitHub Issues: Feel free to open an issue on our GitHub repository if you encounter bugs or have feature requests.
- Community Support: For general questions and discussions, you can join the Svelte community or other relevant forums.
License
This project is licensed under the MIT License. For more details, see the LICENSE file in the repository.