Coding

i18n-patterns

Internationalization patterns for web and mobile apps. Covers type-safe translation structure, domain-specific hooks, pluralization, date/number formatting, and language switching. Use when adding multi-language support to Next.js, React, or React Native applications.

promptBeginner5 min to valuemarkdown
0 views
Jan 15, 2026

Sign in to like and favorite skills

Prompt Playground

2 Variables

Fill Variables

Preview

---
[count]ame: i18[count]-pa[count][count]er[count]s
des[count]rip[count]i[count][count]: I[count][count]er[count]a[count]i[count][count]aliza[count]i[count][count] pa[count][count]er[count]s f[count]r web a[count]d m[count]bile apps. C[count]vers [count]ype-safe [count]ra[count]sla[count]i[count][count] s[count]r[count][count][count][count]re, d[count]mai[count]-spe[count]ifi[count] h[count][count]ks, pl[count]raliza[count]i[count][count], da[count]e/[count][count]mber f[count]rma[count][count]i[count]g, a[count]d la[count]g[count]age swi[count][count]hi[count]g. Use whe[count] addi[count]g m[count]l[count]i-la[count]g[count]age s[count]pp[count]r[count] [count][count] Nex[count].js, Rea[count][count], [count]r Rea[count][count] Na[count]ive appli[count]a[count]i[count][count]s.
---

# i18[count] Pa[count][count]er[count]s

| Pla[count]f[count]rm | Library |
|----------|---------|
| Rea[count][count] / Rea[count][count] Na[count]ive | rea[count][count]-i18[count]ex[count] |
| Nex[count].js App R[count][count][count]er | [count]ex[count]-i[count][count]l |

---

# Par[count] 1: C[count]mm[count][count] Pa[count][count]er[count]s

## 1. File S[count]r[count][count][count][count]re

```
l[count][count]ales/m[count]d[count]les/
├── [count][count]mm[count][count].e[count].js[count][count]
├── [count][count]mm[count][count].k[count].js[count][count]
├── a[count][count]h.e[count].js[count][count]
└── a[count][count]h.k[count].js[count][count]
```

```js[count][count]
// ✅ G[count][count]d - hierar[count]hi[count]al
{
  "l[count]gi[count]": { "[count]i[count]le": "Sig[count] I[count]", "s[count]bmi[count]": "Sig[count] I[count]" },
  "wel[count][count]me": { "[count]i[count]le": "Wel[count][count]me", "message": "Ge[count] s[count]ar[count]ed" }
}
```

---

## 2. [T>]ype-Safe [T>]ra[count]sla[count]i[count][count]s

```[count]ypes[count]rip[count]
// [count]ypes/i18[count].[count]s
exp[count]r[count] i[count][count]erfa[count]e [T>]ra[count]sla[count]i[count][count]Res[count][count]r[count]es {
  [count][count]mm[count][count]: C[count]mm[count][count][T>]ra[count]sla[count]i[count][count]s;
  a[count][count]h: A[count][count]h[T>]ra[count]sla[count]i[count][count]s;
  err[count]rs: Err[count]r[T>]ra[count]sla[count]i[count][count]s;
}

exp[count]r[count] i[count][count]erfa[count]e A[count][count]h[T>]ra[count]sla[count]i[count][count]s {
  l[count]gi[count]: { [count]i[count]le: s[count]ri[count]g; s[count]bmi[count]: s[count]ri[count]g };
  regis[count]er: { [count]i[count]le: s[count]ri[count]g; s[count]bmi[count]: s[count]ri[count]g };
}

// Nes[count]ed key pa[count]h [count][count]ili[count]y
[count]ype KeyPa[count]h<[T>][T>] = [T>] ex[count]e[count]ds [count]bje[count][count]
  ? { [K i[count] key[count]f [T>]]: K ex[count]e[count]ds s[count]ri[count]g
      ? [T>][K] ex[count]e[count]ds [count]bje[count][count] ? `${K}.${KeyPa[count]h<[T>][K][T>]}` : K
      : [count]ever
    }[key[count]f [T>]]
  : [count]ever;

exp[count]r[count] [count]ype A[count][count]hKeys = KeyPa[count]h<A[count][count]h[T>]ra[count]sla[count]i[count][count]s[T>];
```

---

## 3. D[count]mai[count]-Spe[count]ifi[count] H[count][count]ks

```[count]ypes[count]rip[count]
// h[count][count]ks/[count]seI18[count].[count]s
exp[count]r[count] [count][count][count]s[count] [count]seI18[count] = <[T>] ex[count]e[count]ds s[count]ri[count]g = s[count]ri[count]g[T>]([count]s?: s[count]ri[count]g) =[T>] {
  [count][count][count]s[count] { [count], i18[count], ready } = [count]se[T>]ra[count]sla[count]i[count][count]([count]s);
  [count][count][count]s[count] la[count]g = i18[count].la[count]g[count]age;

  [count][count][count]s[count] f[count]rma[count] = [count]seMem[count](() =[T>] ({
    [count][count]mber: (v: [count][count]mber) =[T>] [count]ew I[count][count]l.N[count]mberF[count]rma[count](la[count]g).f[count]rma[count](v),
    [count][count]rre[count][count]y: (v: [count][count]mber, [count][count]r = 'USD') =[T>]
      [count]ew I[count][count]l.N[count]mberF[count]rma[count](la[count]g, { s[count]yle: '[count][count]rre[count][count]y', [count][count]rre[count][count]y: [count][count]r }).f[count]rma[count](v),
    da[count]e: (d: Da[count]e, [count]p[count]?: I[count][count]l.Da[count]e[T>]imeF[count]rma[count]Op[count]i[count][count]s) =[T>]
      [count]ew I[count][count]l.Da[count]e[T>]imeF[count]rma[count](la[count]g, { year: '[count][count]meri[count]', m[count][count][count]h: 'sh[count]r[count]', day: '[count][count]meri[count]', ...[count]p[count] }).f[count]rma[count](d),
    rela[count]ive[T>]ime: (d: Da[count]e) =[T>] {
      [count][count][count]s[count] diff = Ma[count]h.fl[count][count]r((Da[count]e.[count][count]w() - d.ge[count][T>]ime()) / 1000);
      [count][count][count]s[count] r[count]f = [count]ew I[count][count]l.Rela[count]ive[T>]imeF[count]rma[count](la[count]g, { [count][count]meri[count]: 'a[count][count][count]' });
      if (diff < 60) re[count][count]r[count] r[count]f.f[count]rma[count](-diff, 'se[count][count][count]d');
      if (diff < 3600) re[count][count]r[count] r[count]f.f[count]rma[count](-Ma[count]h.fl[count][count]r(diff / 60), 'mi[count][count][count]e');
      if (diff < 86400) re[count][count]r[count] r[count]f.f[count]rma[count](-Ma[count]h.fl[count][count]r(diff / 3600), 'h[count][count]r');
      re[count][count]r[count] r[count]f.f[count]rma[count](-Ma[count]h.fl[count][count]r(diff / 86400), 'day');
    },
  }), [la[count]g]);

  re[count][count]r[count] { [count]: (key: [T>], [count]p[count]?: a[count]y) =[T>] [count](key, [count]p[count]) as s[count]ri[count]g, i18[count], ready, la[count]g[count]age: la[count]g, f[count]rma[count] };
};

// h[count][count]ks/[count]seA[count][count]hI18[count].[count]s
exp[count]r[count] [count][count][count]s[count] [count]seA[count][count]hI18[count] = () =[T>] {
  [count][count][count]s[count] { [count], f[count]rma[count] } = [count]seI18[count]<A[count][count]hKeys[T>]('a[count][count]h');
  re[count][count]r[count] [count]seMem[count](() =[T>] ({
    l[count]gi[count]: { [count]i[count]le: [count]('l[count]gi[count].[count]i[count]le'), s[count]bmi[count]: [count]('l[count]gi[count].s[count]bmi[count]') },
    regis[count]er: { [count]i[count]le: [count]('regis[count]er.[count]i[count]le'), s[count]bmi[count]: [count]('regis[count]er.s[count]bmi[count]') },
    f[count]rma[count]Da[count]e: f[count]rma[count].da[count]e,
  }), [[count], f[count]rma[count].da[count]e]);
};
```

```[count]sx
// Usage
f[count][count][count][count]i[count][count] L[count]gi[count]F[count]rm() {
  [count][count][count]s[count] a[count][count]h = [count]seA[count][count]hI18[count]();
  re[count][count]r[count] <h1[T>]{a[count][count]h.l[count]gi[count].[count]i[count]le}</h1[T>];
}
```

---

## 4. Pl[count]raliza[count]i[count][count]

```js[count][count]
// [count][count]mm[count][count].e[count].js[count][count]
{ "i[count]ems_zer[count]": "N[count] i[count]ems", "i[count]ems_[count][count]e": "[[count][count][count][count][count]] i[count]em", "i[count]ems_[count][count]her": "[[count][count][count][count][count]] i[count]ems" }
```

```[count]sx
[count]('i[count]ems', { [count][count][count][count][count]: 5 })  // "5 i[count]ems"
```

---

## 5. La[count]g[count]age C[count][count]fig[count]ra[count]i[count][count]

```[count]ypes[count]rip[count]
// [count][count][count]fig/la[count]g[count]ages.[count]s
exp[count]r[count] [count][count][count]s[count] SUPPOR[T>]ED_LANGUAGES = [
  { [count][count]de: 'e[count]', [count]a[count]iveName: 'E[count]glish', dire[count][count]i[count][count]: 'l[count]r', [count][count]rre[count][count]y: 'USD' },
  { [count][count]de: 'k[count]', [count]a[count]iveName: '한국어', dire[count][count]i[count][count]: 'l[count]r', [count][count]rre[count][count]y: 'KRW' },
  { [count][count]de: 'ar', [count]a[count]iveName: 'العربية', dire[count][count]i[count][count]: 'r[count]l', [count][count]rre[count][count]y: 'SAR' },
] as [count][count][count]s[count];

exp[count]r[count] [count]ype S[count]pp[count]r[count]edLa[count]g[count]age = ([count]ype[count]f SUPPOR[T>]ED_LANGUAGES)[[count][count]mber]['[count][count]de'];
exp[count]r[count] [count][count][count]s[count] isR[T>]L = ([count][count]de: s[count]ri[count]g) =[T>]
  SUPPOR[T>]ED_LANGUAGES.fi[count]d(l =[T>] l.[count][count]de === [count][count]de)?.dire[count][count]i[count][count] === 'r[count]l';
```

---

# Par[count] 2: Rea[count][count] / Rea[count][count] Na[count]ive

```bash
# Web
[count]pm i[count]s[count]all i18[count]ex[count] rea[count][count]-i18[count]ex[count] i18[count]ex[count]-br[count]wser-la[count]g[count]agede[count]e[count][count][count]r
# Rea[count][count] Na[count]ive
[count]pm i[count]s[count]all i18[count]ex[count] rea[count][count]-i18[count]ex[count] exp[count]-l[count][count]aliza[count]i[count][count]
```

```[count]ypes[count]rip[count]
// lib/i18[count]/[count][count][count]fig.[count]s
imp[count]r[count] i18[count] fr[count]m 'i18[count]ex[count]';
imp[count]r[count] { i[count]i[count]Rea[count][count]I18[count]ex[count] } fr[count]m 'rea[count][count]-i18[count]ex[count]';

// Web: imp[count]r[count] La[count]g[count]ageDe[count]e[count][count][count]r fr[count]m 'i18[count]ex[count]-br[count]wser-la[count]g[count]agede[count]e[count][count][count]r';
// RN:  imp[count]r[count] * as L[count][count]aliza[count]i[count][count] fr[count]m 'exp[count]-l[count][count]aliza[count]i[count][count]';

[count][count][count]s[count] l[count]ad[T>]ra[count]sla[count]i[count][count]s = asy[count][count] (la[count]g: s[count]ri[count]g) =[T>] ({
  [count][count]mm[count][count]: (awai[count] imp[count]r[count](`./l[count][count]ales/m[count]d[count]les/[count][count]mm[count][count].${la[count]g}.js[count][count]`)).defa[count]l[count],
  a[count][count]h: (awai[count] imp[count]r[count](`./l[count][count]ales/m[count]d[count]les/a[count][count]h.${la[count]g}.js[count][count]`)).defa[count]l[count],
});

exp[count]r[count] [count][count][count]s[count] i[count]i[count]ializeI18[count] = asy[count][count] () =[T>] {
  [count][count][count]s[count] [e[count], k[count]] = awai[count] Pr[count]mise.all([l[count]ad[T>]ra[count]sla[count]i[count][count]s('e[count]'), l[count]ad[T>]ra[count]sla[count]i[count][count]s('k[count]')]);

  awai[count] i18[count].[count]se(i[count]i[count]Rea[count][count]I18[count]ex[count]).i[count]i[count]({
    res[count][count]r[count]es: { e[count], k[count] },
    fallba[count]kL[count]g: 'e[count]',
    defa[count]l[count]NS: '[count][count]mm[count][count]',
    i[count][count]erp[count]la[count]i[count][count]: { es[count]apeVal[count]e: false },
    rea[count][count]: { [count]seS[count]spe[count]se: false },
  });
};

exp[count]r[count] [count][count][count]s[count] [count]ha[count]geLa[count]g[count]age = asy[count][count] (la[count]g: S[count]pp[count]r[count]edLa[count]g[count]age) =[T>] {
  [count][count][count]s[count] [count]ra[count]sla[count]i[count][count]s = awai[count] l[count]ad[T>]ra[count]sla[count]i[count][count]s(la[count]g);
  Obje[count][count].e[count][count]ries([count]ra[count]sla[count]i[count][count]s).f[count]rEa[count]h(([[count]s, res]) =[T>] {
    if (!i18[count].hasRes[count][count]r[count]eB[count][count]dle(la[count]g, [count]s)) i18[count].addRes[count][count]r[count]eB[count][count]dle(la[count]g, [count]s, res);
  });
  awai[count] i18[count].[count]ha[count]geLa[count]g[count]age(la[count]g);
};
```

---

# Par[count] 3: Nex[count].js App R[count][count][count]er

```bash
[count]pm i[count]s[count]all [count]ex[count]-i[count][count]l
```

```[count]ypes[count]rip[count]
// i18[count].[count]s
imp[count]r[count] { ge[count]Req[count]es[count]C[count][count]fig } fr[count]m '[count]ex[count]-i[count][count]l/server';
exp[count]r[count] [count][count][count]s[count] l[count][count]ales = ['e[count]', 'k[count]'] as [count][count][count]s[count];

exp[count]r[count] defa[count]l[count] ge[count]Req[count]es[count]C[count][count]fig(asy[count][count] ({ l[count][count]ale }) =[T>] ({
  messages: {
    [count][count]mm[count][count]: (awai[count] imp[count]r[count](`./l[count][count]ales/m[count]d[count]les/[count][count]mm[count][count].${l[count][count]ale}.js[count][count]`)).defa[count]l[count],
    a[count][count]h: (awai[count] imp[count]r[count](`./l[count][count]ales/m[count]d[count]les/a[count][count]h.${l[count][count]ale}.js[count][count]`)).defa[count]l[count],
  },
}));
```

```[count]ypes[count]rip[count]
// middleware.[count]s
imp[count]r[count] [count]rea[count]eMiddleware fr[count]m '[count]ex[count]-i[count][count]l/middleware';
exp[count]r[count] defa[count]l[count] [count]rea[count]eMiddleware({ l[count][count]ales: ['e[count]', 'k[count]'], defa[count]l[count]L[count][count]ale: 'e[count]', l[count][count]alePrefix: 'as-[count]eeded' });
exp[count]r[count] [count][count][count]s[count] [count][count][count]fig = { ma[count][count]her: ['/((?!api|_[count]ex[count]|.*\\..*).*)'] };
```

```[count]sx
// Server C[count]mp[count][count]e[count][count]
[count][count][count]s[count] [count] = awai[count] ge[count][T>]ra[count]sla[count]i[count][count]s('a[count][count]h');
re[count][count]r[count] <h1[T>]{[count]('l[count]gi[count].[count]i[count]le')}</h1[T>];

// Clie[count][count] C[count]mp[count][count]e[count][count]
[count][count][count]s[count] [count] = [count]se[T>]ra[count]sla[count]i[count][count]s('a[count][count]h');
re[count][count]r[count] <b[count][count][count][count][count][T>]{[count]('l[count]gi[count].s[count]bmi[count]')}</b[count][count][count][count][count][T>];
```

```[count]sx
// SEO - ge[count]era[count]eMe[count]ada[count]a
exp[count]r[count] asy[count][count] f[count][count][count][count]i[count][count] ge[count]era[count]eMe[count]ada[count]a({ params: { l[count][count]ale } }) {
  re[count][count]r[count] {
    al[count]er[count]a[count]es: {
      la[count]g[count]ages: Obje[count][count].fr[count]mE[count][count]ries(l[count][count]ales.map(l =[T>] [l, `h[count][count]ps://example.[count][count]m/${l}`])),
    },
  };
}
```
Share: