|Labs
Book a DemoPlatform
React (Lingo Compiler)
Alpha
React (MCP)React (i18n)
CLI

Overview

  • @lingo.dev/react

Getting started

  • Quickstart

Reference

  • LingoProvider
  • useLingo
  • Plurals and select
  • Formatting

useLingo

Max PrilutskiyMax Prilutskiy·Updated 8 days ago·2 min read

useLingo() is how components get to the runtime. It reads the nearest <LingoProvider> and returns the active Lingo object — call it once per component, hold the reference, and use whichever methods you need.

tsx
import { useLingo } from "@lingo.dev/react";

function Greeting() {
  const l = useLingo();
  return <p>{l.text("Hello", { context: "Hero heading" })}</p>;
}

It throws if called outside a provider, so test setups need to wrap the render — even with messages: {} if you don't care about translations in the test.

l.text(source, options) — plain strings#

The everyday call. Returns a translated string, or the source if no translation exists for the current locale.

tsx
l.text("Save", { context: "Form button" });
// → "Speichern" (de) / "Save" (en, fallback)

Interpolation#

{placeholder} segments are substituted from options.values.

tsx
l.text("Welcome back, {name}!", {
  values: { name: user.firstName },
  context: "Dashboard greeting",
});

Missing values render as {name} literally — handy for spotting bugs during dev, but make sure your tests assert on the rendered result so empty values don't slip through.

When the source contains ICU syntax#

If the source string contains plural / select / number / date markers, the runtime upgrades automatically — no extra API. See Plurals and select for the friendly wrapper.

l.rich(source, options) — React subtrees#

When the translated text contains React components (links, bold, an <Icon/>), use l.rich. The translation string carries placeholder tags like <link>...</link>; you map each tag to a renderer.

tsx
l.rich("Click <link>here</link> for {topic}", {
  tags: {
    link: (children) => <a href="/help">{children}</a>,
  },
  values: { topic: "details" },
  context: "Footer help link",
});
// → <>Click <a href="/help">here</a> for details</>

Self-closing tags work too:

tsx
l.rich("Loading <spinner/>...", {
  tags: { spinner: () => <Spinner /> },
  context: "Inline loading state",
});

Tags without a renderer fall back to the raw text — so the missing-tag case is visible in dev, not silently swallowed.

Don't put markup directly inside translated strings. l.rich exists so translators see neutral placeholders (<link>) instead of <a href="...">, which they'd have to preserve verbatim and often break. Define the renderer in your code, not in the locale file.

Locale metadata on l#

Beyond translation, the object exposes:

PropertyTypeNotes
l.localestringWhatever you passed to LingoProvider. BCP-47.
l.direction"ltr" | "rtl"Computed via Intl.Locale.textInfo + fallback RTL language list.
l.scriptstring | undefinedInferred when possible ("Latn", "Cyrl", "Arab", …).
l.regionstring | undefinedInferred from BCP-47 ("US", "DE", "SA", …).

Useful for layout decisions:

tsx
const l = useLingo();
return <div dir={l.direction}>...</div>;

Formatting methods#

l also carries num, currency, percent, date, time, datetime, relative, list, displayName, sort, segment, fileSize, compact, unit — see Formatting for the full breakdown. These are thin wrappers around native Intl.* formatters keyed to l.locale.

Outside of React#

useLingo only works inside components. For utilities, route loaders, or server code, build the same object directly:

ts
import { createLingo } from "@lingo.dev/react";

const l = createLingo("es", messages);
l.text("Hello", { context: "Email subject" });

It's the same Lingo shape, no provider needed. LingoProvider itself uses createLingo under the hood.

Was this page helpful?