home / skills / toilahuongg / shopify-agents-kit / shopify-app-i18n
This skill guides adding multi-language support to Shopify Apps using i18next, including setup, translation files, and admin context for broad reach.
npx playbooks add skill toilahuongg/shopify-agents-kit --skill shopify-app-i18nReview the files below or copy the command above to add this skill to your agents.
---
name: shopify-app-i18n
description: Guide for adding Multi-language support to Shopify Apps using i18next. Covers setup, localization files, and Admin context.
---
# Internationalization (i18n) for Shopify Apps
Shopify merchants exist globally. Your app MUST support multiple languages to be featured or widely adopted.
## 1. Stack
- **Library**: `i18next` (Standard)
- **React**: `react-i18next`
- **Remix**: `remix-i18next`
## 2. Setup
### Installation
```bash
npm install i18next react-i18next remix-i18next i18next-fs-backend i18next-http-backend
```
### Configuration (`app/i18n.server.ts`)
Create a server-side instance to detect language.
```typescript
import { RemixI18Next } from "remix-i18next/server";
import { createInstance } from "i18next";
import i18n from "~/i18n"; // client config
import { resolve } from "node:path";
export const i18nServer = new RemixI18Next({
detection: {
supportedLanguages: i18n.supportedLngs,
fallbackLanguage: i18n.fallbackLng,
},
// This is the configuration for i18next
i18next: {
...i18n,
backend: {
loadPath: resolve("./public/locales/{{lng}}/{{ns}}.json"),
},
},
});
```
### Root Loader (`app/root.tsx`)
Inject the locale into the document.
```typescript
export async function loader({ request }: LoaderFunctionArgs) {
const locale = await i18nServer.getLocale(request);
return json({ locale });
}
export const handle = {
// In the handle export, we can add a reference to a translation namespace
// This will load the translations for this namespace for this route
i18n: "common",
};
export default function App() {
const { locale } = useLoaderData<typeof loader>();
useChangeLanguage(locale); // Syncs remix locale with i18next
return (
<html lang={locale} dir={i18n.dir(locale)}>
{/* ... */}
</html>
);
}
```
## 3. Translation Files
Store JSON files in `public/locales`.
```
public/
locales/
en/
common.json
fr/
common.json
vi/
common.json
```
**Example `common.json`**:
```json
{
"welcome": "Welcome to my app",
"dashboard": {
"title": "Dashboard",
"stats": "Statistics"
}
}
```
## 4. Usage in Components
```typescript
import { useTranslation } from "react-i18next";
export function DashboardHeader() {
const { t } = useTranslation("common");
return (
<Page title={t("dashboard.title")}>
<p>{t("welcome")}</p>
</Page>
);
}
```
## 5. Detecting Shopify Admin Language
Shopify passes the locale in the URL query params (`?locale=fr-FR`) or you can fetch it from the GraphQL Admin API (`Shop.billingAddress.country` or similar, though strictly speaking the Admin UI language is preferred).
Typically, `remix-i18next` detection handles the request headers/query params automatically if configured correctly.
## 6. Translating App Extensions
For Theme App Extensions or Checkout UI Extensions, they have their *own* `locales` folder in their directory. They do NOT share the Remix app's locales.
- **Theme Extension**: `extensions/my-ext/locales/en.default.json`
- **Checkout UI**: `extensions/checkout-ui/locales/en.json`
This skill guides adding multi-language support to Shopify Apps using i18next, react-i18next, and remix-i18next. It focuses on practical setup, where to store localization files, and how to detect and apply the Shopify Admin language. The guidance covers both server and client integration and notes special handling for app extensions.
Set up i18next on both server and client, using remix-i18next to detect locale from requests and sync Remix with i18next. Store JSON translation files under public/locales with one folder per language and namespace files (for example common.json). Use react-i18next hooks in components to load translations and render localized content. Extensions (theme or checkout) require their own locales folder inside the extension directory.
Where should translation files live?
Place them under public/locales/{{lng}}/{{ns}}.json for the Remix app; extensions must use their own locales folder inside the extension directory.
How do I detect the Shopify Admin language?
remix-i18next can detect locale from request headers or query params (Shopify sends ?locale=xx-XX); prefer the Admin UI locale or use the Admin API if needed.