Internationalisation (i18n)

Building software so it can support multiple languages/regions.

t("cta_button")

String is looked up per locale.

html

<div class="i18n i18n--es i18n--ready">
  <p class="i18n__code">t(&quot;cta_button&quot;)</p>
  <button type="button" class="i18n__btn i18n__btn--hardcoded" style="background:#A8E6C1;">Submit</button>
  <button type="button" class="i18n__btn i18n__btn--en" style="background:#A8E6C1;">Submit</button>
  <button type="button" class="i18n__btn i18n__btn--es" style="background:#A8E6C1;">Enviar</button>
  <button type="button" class="i18n__btn i18n__btn--fr" style="background:#A8E6C1;">Envoyer</button>
  <p class="i18n__note">String is looked up per locale.</p>
</div>
<style>
.i18n { font: 14px/1.5 system-ui, sans-serif; color: #241430; background: #FAF7F2; padding: 20px; border-radius: 12px; width: 280px; box-sizing: border-box; text-align: center; }
.i18n__code { margin: 0 0 12px; font: 11px ui-monospace, monospace; color: #24143099; }
.i18n__btn { display: none; border: none; padding: 10px 20px; border-radius: 8px; color: #241430; font: 600 14px system-ui, sans-serif; cursor: pointer; }
.i18n__btn--hardcoded { display: inline-block; }
.i18n--ready .i18n__btn--hardcoded { display: none; }
.i18n--ready.i18n--en .i18n__btn--en, .i18n--ready.i18n--es .i18n__btn--es, .i18n--ready.i18n--fr .i18n__btn--fr { display: inline-block; }
.i18n__note { margin: 12px 0 0; font-size: 11px; color: #24143099; }
</style>

tailwind

<div class="i18ntw i18ntw--es i18ntw--ready font-sans text-[#241430] bg-[#FAF7F2] p-5 rounded-xl w-[280px] box-border text-center">
  <p class="m-0 mb-3 font-mono text-[11px] text-[#24143099]">t(&quot;cta_button&quot;)</p>
  <button type="button" class="i18ntw__btn i18ntw__btn--hardcoded inline-block border-none py-2.5 px-5 rounded-lg font-semibold text-sm cursor-pointer" style="background:#A8E6C1;">Submit</button>
  <button type="button" class="i18ntw__btn i18ntw__btn--en hidden border-none py-2.5 px-5 rounded-lg font-semibold text-sm cursor-pointer" style="background:#A8E6C1;">Submit</button>
  <button type="button" class="i18ntw__btn i18ntw__btn--es hidden border-none py-2.5 px-5 rounded-lg font-semibold text-sm cursor-pointer" style="background:#A8E6C1;">Enviar</button>
  <button type="button" class="i18ntw__btn i18ntw__btn--fr hidden border-none py-2.5 px-5 rounded-lg font-semibold text-sm cursor-pointer" style="background:#A8E6C1;">Envoyer</button>
  <p class="m-0 mt-3 text-[11px] text-[#24143099]">String is looked up per locale.</p>
</div>
<style>
.i18ntw--ready .i18ntw__btn--hardcoded { display: none; }
.i18ntw--ready.i18ntw--en .i18ntw__btn--en, .i18ntw--ready.i18ntw--es .i18ntw__btn--es, .i18ntw--ready.i18ntw--fr .i18ntw__btn--fr { display: inline-block; }
</style>

react

export function InternationalisationI18n({
  buttonKey = "cta_button",
  locale = "es",
  i18nReady = true,
  accent = "#A8E6C1",
}) {
  const labels = { en: "Submit", es: "Enviar", fr: "Envoyer" };
  const label = i18nReady ? labels[locale] : "Submit";
  const btnStyle = { border: "none", padding: "10px 20px", borderRadius: 8, color: "#241430", fontWeight: 600, fontSize: 14, cursor: "pointer", background: accent };
  return (
    <div style={{ font: "14px/1.5 system-ui, sans-serif", color: "#241430", background: "#FAF7F2", padding: 20, borderRadius: 12, width: 280, boxSizing: "border-box", textAlign: "center" }}>
      <p style={{ margin: "0 0 12px", fontFamily: "ui-monospace, monospace", fontSize: 11, color: "#24143099" }}>t("{buttonKey}")</p>
      <button type="button" style={btnStyle}>{label}</button>
      <p style={{ margin: "12px 0 0", fontSize: 11, color: "#24143099" }}>{i18nReady ? "String is looked up per locale." : "Text is hardcoded \u2014 it never changes with locale."}</p>
    </div>
  );
}