Thin SolidJS wrappers around popular i18n libraries, powered by Apiglot.
Currently supported:
- i18next - the most popular i18n library for JavaScript
Planned:
npm install i18next @apiglot/solidjs
# or
pnpm add i18next @apiglot/solidjs
# or
yarn add i18next @apiglot/solidjsPeer dependency: solid-js >= 1.6.0
Wrap your app with the I18NextContext provider, passing your Apiglot project credentials:
import { render } from 'solid-js/web';
import { I18NextContext } from '@apiglot/solidjs/i18next';
import App from './App';
render(
() => (
<I18NextContext
projectId="your-project-id"
apiKey="your-api-key"
>
<App />
</I18NextContext>
),
document.getElementById('root')!
);| Prop | Type | Required | Description |
|---|---|---|---|
projectId |
string |
Yes | Your Apiglot project ID |
apiKey |
string |
Yes | Your Apiglot API key |
host |
string |
No | Custom API host (defaults to https://api.apiglot.com) |
debug |
boolean |
No | Enable i18next debug mode |
The primary way to translate text. Optionally pass a namespace to load.
import { useTranslation } from '@apiglot/solidjs/i18next';
function Greeting() {
const { t } = useTranslation('common');
return (
<div>
<h1>{t('welcome_title')}</h1>
<p>{t('welcome_message', 'Welcome!')}</p>
</div>
);
}The second argument to t() can be a default value string or an i18next options object:
const { t } = useTranslation('common');
// With a default value
t('greeting', 'Hello!')
// With i18next interpolation options
t('greeting_name', { name: 'World' })A declarative alternative to the useTranslation hook:
import { Translateable } from '@apiglot/solidjs/i18next';
function ProductCard() {
return (
<div>
<Translateable key="product.title" namespace="shop" />
<Translateable
key="product.description"
namespace="shop"
placeholders={{ price: '9.99', currency: 'USD' }}
/>
<Translateable
key="product.disclaimer"
namespace="shop"
renderHtml={true}
/>
</div>
);
}| Prop | Type | Required | Description |
|---|---|---|---|
key |
string |
Yes | Translation key |
namespace |
string | string[] |
No | Namespace(s) to load |
placeholders |
Record<string, any> |
No | Interpolation values |
renderHtml |
boolean |
No | Render HTML tags in the translation string (default: false) |
A ready-made <select> dropdown for switching languages. It automatically lists all languages configured in your Apiglot project.
import { LanguageSwitch } from '@apiglot/solidjs/i18next';
function Header() {
return (
<nav>
<h1>My App</h1>
<LanguageSwitch class="lang-picker" />
</nav>
);
}It accepts all standard <select> HTML attributes.
For advanced use cases, access the full context object:
import { useI18Next } from '@apiglot/solidjs/i18next';
function LanguageInfo() {
const ctx = useI18Next();
return (
<div>
<p>Current language: {ctx?.currentLanguage()}</p>
<p>Available: {ctx?.languages().map(l => l.name).join(', ')}</p>
<button onClick={() => ctx?.changeLanguage('es')}>
Switch to Spanish
</button>
</div>
);
}The context object provides:
| Property | Type | Description |
|---|---|---|
loading |
Accessor<boolean> |
Whether project info is still loading |
languages |
Accessor<Language[]> |
All available languages |
currentLanguage |
Accessor<string | null> |
Current language code |
changeLanguage |
(langCode: string) => Promise<void> |
Switch the active language |
loadNamespace |
(ns: string | string[]) => Promise<void> |
Load additional namespace(s) |
loadRawJson |
(langCode: string, ns: string) => Promise<Record<string, any>> |
Fetch raw translation JSON |
i18next |
i18next |
The underlying i18next instance |
@apiglot/solidjs/i18next ships with a Resources interface that you can augment via TypeScript module augmentation to get autocompletion and type-checking on namespaces and translation keys.
Each key in Resources is a namespace, and its value is a union of all translation keys in that namespace:
// src/types/apiglot.d.ts
declare module '@apiglot/solidjs/i18next' {
interface Resources {
common: 'welcome_title' | 'welcome_message' | 'logout_button';
shop: 'product.title' | 'product.description' | 'product.disclaimer';
}
}Once augmented, useTranslation will narrow the namespace and key types based on your declarations:
const { t } = useTranslation('common');
t('welcome_title'); // ✅ ok
t('logout_button'); // ✅ ok
t('product.title'); // ❌ Type error — not a key of the 'common' namespace
const { t: t2 } = useTranslation('unknown'); // ❌ Type error — not a declared namespaceMaintaining the Resources interface by hand is tedious and gets out of sync quickly. The Apiglot CLI can introspect your Apiglot project and generate the augmentation file for you:
npx apiglot i18next typesRun it after adding or renaming keys in Apiglot (and ideally as a step in your CI or pre-build script) to keep the type definitions in sync with your project.
MIT