useLocale
Read the locale the server detected for this request, during server rendering and in the browser.
tsx
import { useLocale } from '@gio.js/react';
export function Price({ amount }: { amount: number }) {
const locale = useLocale() || 'en';
return <>{new Intl.NumberFormat(locale, { style: 'currency', currency: 'EUR' }).format(amount)}</>;
}Reference
Parameters
useLocale takes no parameters.
Returns
A string:
- with
[i18n] localesset ingio.toml, one of them: the locale the server detected, ordefault_localewhen nothing matched, spelled exactly as inlocales; - without
[i18n],''.
How the locale is detected
The Rust server tries the sources in [i18n] detect_from order (default ["path", "accept-language", "cookie"]) and takes the first that names a configured locale:
path- a first path segment that is a locale (/fr/about). The prefix is always removed before routing, so the page isapp/about/page.tsxandusePathname()is/about.accept-language- the preferred language in the header that is a locale, by full tag (fr-CA) or language (fr). The languages are tried from the highestqweight down (the header's order breaks ties), and one markedq=0is never picked.cookie- thegio_localecookie.
For HTML responses in a locale other than the default, the server also sets the <html> element's lang to the locale, replacing the one the root layout wrote.
Behavior
- The value travels with the page, so the server render and the hydration render agree and the server HTML already holds locale-dependent output, such as a
<LocaleLink>'s prefixedhref. - After a soft navigation, hydrated components read the new page's locale.
- Outside a tree GioJS rendered (a unit test, a separate React root), it returns
''on the first render and thendocument.documentElement.lang, read in an effect so hydration cannot mismatch.
Examples
Translating strings
app/(site)/greeting.tsx
import { useLocale } from '@gio.js/react';
const MESSAGES: Record<string, { hello: string }> = {
en: { hello: 'Hello' },
fr: { hello: 'Bonjour' },
};
export function Greeting() {
const locale = useLocale();
return <p>{(MESSAGES[locale] ?? MESSAGES.en).hello}</p>;
}Formatting dates
tsx
const locale = useLocale() || 'en';
const published = new Intl.DateTimeFormat(locale, { dateStyle: 'long' }).format(new Date(post.publishedAt));Good to know
- On the server, route handlers and
getServerSidePropsread the same value asreq.locale(''without[i18n]) andctx.locale(absent without[i18n]). - The page cache keeps one copy per locale. A URL without a locale prefix depends on the visitor's headers (unless
detect_fromis only["path"]), so its response is never markedpublicfor CDNs and carries noETag; link to prefixed URLs where shared caching matters. - GioJS never sets the
gio_localecookie; set it yourself to remember a visitor's choice. - In the server-only root layout the value is that of the page loaded in full.
- Locales are matched exactly as written in
localesfor the path and the cookie; theAccept-Languagematch ignores case. The value is always spelled as inlocales:Accept-Language: pt-brwith a configuredpt-BRgives'pt-BR'.
Related
- Internationalization - the guide.
[i18n]-locales,default_locale,detect_from.<LocaleLink>- links that keep the locale.usePathname- the path without the prefix.
Version history
| Version | Changes |
|---|---|
v0.1.0-beta.8 | Returns the request locale during server rendering too, from the navigation state GioJS provides. A locale from Accept-Language is spelled as in locales (it was lowercased) and picked by q weight. |
v0.1.0-beta.6 | No longer causes hydration mismatches. |
v0.1.0-beta.1 | Introduced. |