Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
executable file
·37 lines (35 loc) · 34.5 KB
/
Copy pathindex.html
File metadata and controls
executable file
·37 lines (35 loc) · 34.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script async="" src="https://www.googletagmanager.com/gtag/js?id=G-4H6ZM973P2"></script><link rel="icon" href="/img/logo-icon.svg" type="image/svg+xml"/><meta name="theme-color" content="#6f3c97"/><link rel="sitemap" type="application/xml" href="/sitemap.xml"/><link rel="agent-skills" href="/.well-known/agent-skills/index.json" type="application/json"/><title>FormatJS - Internationalize your web apps on the client & server</title><meta name="description" content="Industry-standard i18n libraries for JavaScript. FormatJS provides modular libraries for formatting numbers, dates, and strings for React, Vue, and vanilla JS. Built on ICU Message syntax and ECMA-402."/><meta property="og:title" content="FormatJS - Internationalize your web apps"/><meta property="og:description" content="Industry-standard i18n libraries for JavaScript. Built on ICU Message syntax."/><meta property="og:type" content="website"/><meta property="og:url" content="https://formatjs.io/"/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:title" content="FormatJS - Internationalize your web apps"/><meta name="twitter:description" content="Industry-standard i18n libraries for JavaScript. Built on ICU Message syntax."/><link rel="canonical" href="https://formatjs.io/"/><link rel="preconnect" href="https://fonts.googleapis.com"/><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous"/><script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-4H6ZM973P2');
</script><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Jost:wght@400;500;700&display=swap"/>
<script type="module" crossorigin src="/assets/index-DEzZ4vIU.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C1xBHAr4.css">
</head>
<body>
<div id="root"><link rel="preload" as="image" href="/img/logo-icon.svg"/><div class="home relative bg-home-bg font-display text-lg leading-normal text-home-ink"><header class="absolute inset-x-0 top-0 z-20 flex items-center gap-4 px-[clamp(20px,2.2vw,32px)] py-4 md:gap-8 md:py-5"><a href="/" aria-label="FormatJS home" class="inline-flex items-center gap-2.5 text-lg font-bold tracking-tight no-underline"><img src="/img/logo-icon.svg" alt="" width="26" height="28"/><span>FormatJS</span></a><nav aria-label="Primary" class="ml-auto hidden items-center gap-7 lg:flex"><a href="/docs/getting-started/installation" class="font-medium no-underline hover:underline">Docs</a><a href="#libraries" class="font-medium no-underline hover:underline">Libraries</a><a href="/docs/core-concepts/icu-syntax" class="font-medium no-underline hover:underline">ICU syntax</a><a href="https://github.com/formatjs/formatjs" class="font-medium no-underline hover:underline">GitHub</a></nav><div class="ml-auto flex items-center gap-3 lg:ml-0"><button class="flex items-center gap-2 h-10 px-3 rounded-lg border border-border bg-popover text-sm text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search h-4 w-4" aria-hidden="true"><path d="m21 21-4.34-4.34"></path><circle cx="11" cy="11" r="8"></circle></svg><span class="hidden sm:inline">Search docs...</span><kbd class="hidden sm:inline-flex items-center gap-1 rounded border border-border bg-muted px-1.5 text-[10px] font-medium text-muted-foreground"><span class="text-xs">⌘</span>K</kbd></button><a href="/docs/getting-started/installation" class="hidden min-h-12 items-center bg-primary px-5 font-medium text-white no-underline transition-colors hover:bg-brand-hover sm:inline-flex">Installation guide</a><button type="button" aria-label="Navigation menu" class="inline-flex size-11 items-center justify-center bg-home-raised lg:hidden" id="radix-_R_1t_" aria-haspopup="menu" aria-expanded="false" data-state="closed"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu size-5" aria-hidden="true"><path d="M4 5h16"></path><path d="M4 12h16"></path><path d="M4 19h16"></path></svg></button></div></header><main><section aria-labelledby="hero-title" class="grid min-h-svh px-[clamp(20px,2.2vw,32px)] pt-24 pb-14 sm:pt-28"><div class="mx-auto grid w-full min-w-0 max-w-[1320px] grid-cols-[minmax(0,1fr)] content-center justify-items-center gap-5 sm:gap-7"><div class="home-chip-in inline-flex min-h-14 items-center gap-2.5 rounded-lg bg-home-raised px-3 py-2.5 text-sm sm:min-h-16 sm:gap-3.5 sm:px-[18px] sm:py-3 justify-between justify-self-stretch sm:justify-self-center sm:-rotate-3 lg:ml-[9%] lg:justify-self-start"><label class="text-home-muted" for="hero-count">count</label><input id="hero-count" type="range" min="0" max="120" class="home-range w-auto min-w-0 flex-1 sm:w-[180px] sm:flex-none" value="42"/><output for="hero-count" class="min-w-[2.5ch] text-right font-medium tabular-nums">42</output></div><h1 id="hero-title" lang="en" dir="ltr" class="m-0 w-full min-w-0 text-center text-[clamp(56px,9vw,150px)] leading-[0.9] font-bold uppercase tracking-[-0.03em]"><span class="home-line"><span style="--i:0">Ship in</span></span><span class="home-line"><span style="--i:1">42 languages</span></span></h1><div class="grid w-full grid-cols-1 items-center gap-3.5 sm:grid-cols-2 sm:gap-8 lg:grid-cols-[1fr_minmax(0,40ch)_1fr]"><fieldset aria-label="Locale" class="home-chip-in inline-flex min-h-14 items-center gap-2.5 rounded-lg bg-home-raised px-3 py-2.5 text-sm sm:min-h-16 sm:gap-3.5 sm:px-[18px] sm:py-3 m-0 border-0 flex-col items-start gap-1.5 justify-self-stretch sm:flex-row sm:items-center sm:justify-self-start sm:rotate-2"><span class="text-home-muted">locale</span><div class="flex w-full justify-between gap-0.5 rounded-md bg-[#333] p-[3px] sm:inline-flex sm:w-auto"><button type="button" aria-pressed="true" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">en</button><button type="button" aria-pressed="false" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">fr</button><button type="button" aria-pressed="false" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">de</button><button type="button" aria-pressed="false" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">pl</button><button type="button" aria-pressed="false" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">ar</button><button type="button" aria-pressed="false" class="min-h-11 min-w-0 flex-1 cursor-pointer rounded px-2 font-medium transition-[background-color,transform] duration-150 hover:bg-[#3d3d3d] active:scale-95 aria-pressed:bg-home-ink aria-pressed:text-home-bg sm:min-h-[38px] sm:min-w-10 sm:flex-none">ja</button></div></fieldset><p class="home-load order-3 m-0 max-w-[40ch] justify-self-center text-center sm:order-none sm:col-span-2 sm:row-start-2 lg:col-span-1 lg:row-start-auto" style="--d:420ms">FormatJS is a set of JavaScript libraries for internationalization, built on ICU MessageFormat, Unicode CLDR and the ECMA-402 Intl APIs.</p><div class="home-chip-in inline-flex min-h-14 items-center gap-2.5 rounded-lg bg-home-raised px-3 py-2.5 text-sm sm:min-h-16 sm:gap-3.5 sm:px-[18px] sm:py-3 justify-between justify-self-stretch sm:justify-self-end sm:-rotate-2"><span class="text-home-muted" id="hero-source-label">Show message</span><button type="button" role="switch" aria-checked="true" aria-labelledby="hero-source-label" class="group relative h-[30px] w-[52px] cursor-pointer rounded-full bg-[#444] transition-colors aria-checked:bg-primary"><span class="absolute top-[3px] left-[3px] size-6 rounded-full bg-home-ink transition-transform duration-300 group-aria-checked:translate-x-[22px]"></span></button><span class="min-w-[2.5ch] text-right font-medium">on</span></div></div><div aria-live="polite" aria-hidden="false" class="w-full max-w-[860px] min-w-0 overflow-hidden rounded-lg bg-home-surface text-sm transition-[opacity,transform] duration-300 "><div class="flex flex-col justify-between gap-1 bg-home-raised px-[18px] py-3 text-home-muted sm:flex-row sm:gap-4"><span>lang/<!-- -->en<!-- -->.json</span><code class="text-home-ink">Intl.PluralRules('en').select(42) → other</code></div><pre class="m-0 overflow-x-auto px-[18px] pt-4 pb-[18px] text-[13px] leading-[1.65] break-words whitespace-pre-wrap sm:text-sm"><code>{
<!-- --> "hero.ship": "Ship in",
<!-- --> "hero.count": "{count, plural, <span class="text-home-muted">=0<!-- --> <!-- -->{no languages}</span> <span class="text-home-muted">one<!-- --> <!-- -->{# language}</span> <span class="rounded-[3px] bg-primary px-1 py-px text-white">other<!-- --> <!-- -->{# languages}</span>}"
}</code></pre></div></div></section><section aria-labelledby="plural-title" class="relative h-[86svh] min-h-[640px] overflow-hidden px-[clamp(20px,2.2vw,32px)] py-14 transition-colors duration-500 sm:h-[92svh] sm:min-h-[620px] sm:py-[72px] bg-primary text-white"><div data-reveal="true" class="relative z-[2] max-w-[34rem]"><h2 id="plural-title" class="m-0 mb-4 text-[26px] leading-[1.1] font-bold tracking-[-0.02em] sm:text-[clamp(28px,2.6vw,40px)]">In Arabic, <!-- -->3<!-- --> is <!-- -->few</h2><p class="m-0 max-w-[46ch]">CLDR gives Arabic six plural categories, English two and Japanese one. FormatJS selects the branch with<!-- --> <code class="bg-black/20!">Intl.PluralRules</code>, so every translation says the number the way its own grammar does.</p></div><div data-reveal="true" style="--d:160ms" class="absolute bottom-0 left-[clamp(20px,2.2vw,32px)] text-[3.5vw] sm:right-[clamp(20px,2.2vw,32px)] sm:left-auto sm:text-[clamp(15px,2vw,32px)]"><div dir="ltr" class="w-[25em] rounded-t-[0.5em] bg-[#151515] px-[1.3em] pt-[1.1em] pb-[1.4em] text-home-ink"><div class="flex justify-between text-[0.8em] text-home-muted"><span>count</span><span>locale: ar</span></div><div class="mt-[0.5em] mb-[0.6em] flex items-center gap-[0.5em]"><button type="button" aria-label="Decrease count" class="size-[2.2em] cursor-pointer rounded-[0.3em] bg-[#2c2c2c] text-[1.1em] transition-[background-color,transform] duration-150 hover:bg-[#3a3a3a] active:scale-95">−</button><button type="button" aria-label="Increase count" class="size-[2.2em] cursor-pointer rounded-[0.3em] bg-[#2c2c2c] text-[1.1em] transition-[background-color,transform] duration-150 hover:bg-[#3a3a3a] active:scale-95">+</button><output lang="ar" aria-live="polite" class="ml-auto text-[4.6em] leading-[0.9] font-bold tabular-nums">3</output></div><ul aria-label="Arabic plural categories" class="m-0 grid list-none grid-cols-6 gap-[0.25em] rounded-[0.35em] bg-[#232323] p-[0.25em]"><li aria-current="false" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 text-[#b5b5b5]">zero</li><li aria-current="false" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 text-[#b5b5b5]">one</li><li aria-current="false" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 text-[#b5b5b5]">two</li><li aria-current="true" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 bg-home-ink font-medium text-home-bg">few</li><li aria-current="false" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 text-[#b5b5b5]">many</li><li aria-current="false" class="rounded-[0.25em] px-[0.5em] py-[0.35em] text-center text-[0.78em] transition-colors duration-200 text-[#b5b5b5]">other</li></ul><p lang="ar" dir="rtl" class="mt-[0.6em] mb-0 text-right text-[1.15em]">3 رسائل جديدة</p></div></div></section><section id="workflow" aria-labelledby="flow-title" class="block bg-home-surface pb-20 sm:grid sm:grid-cols-12 sm:gap-6 sm:px-[clamp(20px,2.2vw,32px)] sm:pt-20 sm:pb-[120px]"><div class="px-[clamp(20px,2.2vw,32px)] pt-12 sm:col-span-5 sm:px-0 sm:pt-0"><div data-step="0" class="flex min-h-[60svh] flex-col justify-center sm:min-h-[80vh] sm:last:min-h-[70vh]"><h2 id="flow-title" class="m-0 mb-12 text-[26px] leading-[1.1] font-bold tracking-[-0.02em] sm:text-[clamp(28px,2.6vw,40px)]">From component to catalog</h2><p class="m-0 mb-3.5 max-w-[18ch] text-2xl leading-[1.15] font-medium transition-colors duration-300 sm:text-[clamp(24px,2.6vw,40px)] text-home-ink">First, declare messages where they render.</p><p class="m-0 max-w-[40ch] transition-colors duration-300 text-home-ink"><code>defineMessages</code> keeps the English default, a note for translators and a stable ID next to the component that uses it.</p></div><div data-step="1" class="flex min-h-[60svh] flex-col justify-center sm:min-h-[80vh] sm:last:min-h-[70vh]"><p class="m-0 mb-3.5 max-w-[18ch] text-2xl leading-[1.15] font-medium transition-colors duration-300 sm:text-[clamp(24px,2.6vw,40px)] text-home-muted">Then extract them with one command.</p><p class="m-0 max-w-[40ch] transition-colors duration-300 text-home-muted"><code>formatjs extract</code> reads your source and writes a catalog your translation tool can open. The CLI ships native binaries for macOS, Linux and Windows.</p></div><div data-step="2" class="flex min-h-[60svh] flex-col justify-center sm:min-h-[80vh] sm:last:min-h-[70vh]"><p class="m-0 mb-3.5 max-w-[18ch] text-2xl leading-[1.15] font-medium transition-colors duration-300 sm:text-[clamp(24px,2.6vw,40px)] text-home-muted">Finally, compile and ship each locale.</p><p class="m-0 max-w-[40ch] transition-colors duration-300 text-home-muted"><code>formatjs compile --ast</code> pre-parses every translation, so the browser formats messages without loading the parser.</p></div></div><div class="sticky top-0 z-[2] grid h-[46svh] place-items-center self-start bg-primary p-3 sm:top-[14vh] sm:col-span-6 sm:col-start-7 sm:mt-[14vh] sm:h-[min(72vh,600px)] sm:p-8"><div class="flex size-full max-w-[640px] flex-col overflow-hidden rounded-lg bg-[#121212] text-[13px] sm:text-sm"><div class="flex gap-0.5 bg-[#1e1e1e] px-1.5 pt-1.5"><span class="rounded-t-md px-3.5 py-2 whitespace-nowrap transition-colors duration-200 bg-[#121212] text-home-ink">Inbox.tsx</span><span class="rounded-t-md px-3.5 py-2 whitespace-nowrap transition-colors duration-200 text-[#8f8f8f]">Terminal</span><span class="rounded-t-md px-3.5 py-2 whitespace-nowrap transition-colors duration-200 text-[#8f8f8f]">compiled-lang/fr.json</span></div><div class="home-pane-in flex flex-1 flex-col overflow-hidden px-5 py-[18px] [&_pre]:m-0 [&_pre]:leading-[1.6] [&_pre]:break-words [&_pre]:whitespace-pre-wrap [&_pre]:text-[#e6e6e6]"><pre><code><span class="text-[#c9a8e4]">import</span> <!-- -->{defineMessages, FormattedMessage}<!-- --> <span class="text-[#c9a8e4]">from</span> <span class="text-[#d7bfa9]">'react-intl'</span>
<span class="text-[#c9a8e4]">const</span> messages = defineMessages(<!-- -->{
<!-- --> unread: {
defaultMessage:
<span class="text-[#d7bfa9]">'<!-- -->{count, plural, one {# new message} other {# new messages}}<!-- -->'</span>,
description: <span class="text-[#d7bfa9]">'Inbox header, count of unread mail'</span>,
},
})
<span class="text-[#c9a8e4]">export function</span> <!-- -->InboxHeader({count}) {
<span class="text-[#c9a8e4]">return</span> (
<h2>
<FormattedMessage {...messages.unread} values={{count}} />
</h2>
)
}</code></pre></div></div></div></section><section id="libraries" aria-labelledby="libs-title" class="px-[clamp(20px,2.2vw,32px)] pt-[140px] pb-[100px] sm:pt-[200px] sm:pb-[120px]"><div class="flex flex-col items-stretch justify-between gap-8 sm:flex-row sm:items-end"><h2 id="libs-title" data-reveal="true" class="m-0 text-[clamp(2rem,1.3rem+3.2vw,4rem)] leading-[1.02] font-bold tracking-[-0.025em]"><span class="text-home-muted">Pick your stack.</span><br/>The libraries follow.</h2><a href="/docs/getting-started/installation" class="inline-flex min-h-12 items-center justify-center bg-primary px-5 font-medium text-white no-underline transition-colors hover:bg-brand-hover">Read the docs</a></div><div data-reveal="true" style="--d:120ms" class="mt-12 grid grid-cols-1 gap-4 sm:grid-cols-[170px_1fr] sm:gap-7"><div role="tablist" aria-label="Library groups" aria-orientation="vertical" class="sticky top-0 z-[2] grid grid-cols-3 content-start gap-1.5 bg-home-bg py-2 sm:static sm:grid-cols-1 sm:py-0"><button id="tab-react" type="button" role="tab" aria-selected="true" aria-controls="library-panel" tabindex="0" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-ink text-home-bg"><b class="font-medium">React</b><small class="text-sm text-[#444]">3<!-- --> packages</small></button><button id="tab-vue" type="button" role="tab" aria-selected="false" aria-controls="library-panel" tabindex="-1" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-surface hover:bg-home-raised"><b class="font-medium">Vue & Svelte</b><small class="text-sm text-home-muted">2<!-- --> packages</small></button><button id="tab-core" type="button" role="tab" aria-selected="false" aria-controls="library-panel" tabindex="-1" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-surface hover:bg-home-raised"><b class="font-medium">Core</b><small class="text-sm text-home-muted">4<!-- --> packages</small></button><button id="tab-polyfills" type="button" role="tab" aria-selected="false" aria-controls="library-panel" tabindex="-1" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-surface hover:bg-home-raised"><b class="font-medium">Polyfills</b><small class="text-sm text-home-muted">6<!-- --> packages</small></button><button id="tab-tooling" type="button" role="tab" aria-selected="false" aria-controls="library-panel" tabindex="-1" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-surface hover:bg-home-raised"><b class="font-medium">Tooling</b><small class="text-sm text-home-muted">4<!-- --> packages</small></button><button id="tab-rust" type="button" role="tab" aria-selected="false" aria-controls="library-panel" tabindex="-1" class="grid min-h-14 cursor-pointer gap-0.5 px-2.5 py-2 text-left transition-[background-color,transform] duration-200 active:scale-[0.98] sm:min-h-16 sm:px-4 sm:py-2.5 bg-home-surface hover:bg-home-raised"><b class="font-medium">Rust & Python</b><small class="text-sm text-home-muted">4<!-- --> packages</small></button></div><div id="library-panel" role="tabpanel" aria-labelledby="tab-react" class="grid content-start gap-1"><p class="m-0 pb-3 text-sm text-home-muted">Downloads · last 30 days (<!-- -->2026-09-23<!-- -->–<!-- -->2026-10-22<!-- -->)</p><a href="https://www.npmjs.com/package/react-intl" aria-label="react-intl: Components and hooks for React and React Native. 11,992,790 downloads in the last 30 days on npm." style="--i:0" class="home-pane-in grid min-h-[76px] items-center gap-1 p-4 no-underline transition-[background-color,transform] duration-200 hover:translate-x-1 sm:grid-cols-[1fr_auto] sm:gap-6 sm:py-3 sm:pr-6 sm:pl-5 bg-home-surface hover:bg-home-raised"><span><span class="font-medium break-words">react-intl</span><span class="block text-sm text-home-muted">Components and hooks for React and React Native</span></span><span class="text-sm text-home-muted sm:text-right" title="11,992,790 downloads in the last 30 days (2026-09-23–2026-10-22)"><span class="block font-medium text-home-ink">12M<span class="sr-only"> <!-- -->downloads in the last 30 days</span></span><span>npm</span></span></a><a href="https://www.npmjs.com/package/@formatjs/intl" aria-label="@formatjs/intl: The framework-agnostic core that react-intl is built on. 13,144,541 downloads in the last 30 days on npm." style="--i:1" class="home-pane-in grid min-h-[76px] items-center gap-1 p-4 no-underline transition-[background-color,transform] duration-200 hover:translate-x-1 sm:grid-cols-[1fr_auto] sm:gap-6 sm:py-3 sm:pr-6 sm:pl-5 bg-home-band hover:bg-home-raised"><span><span class="font-medium break-words">@formatjs/intl</span><span class="block text-sm text-home-muted">The framework-agnostic core that react-intl is built on</span></span><span class="text-sm text-home-muted sm:text-right" title="13,144,541 downloads in the last 30 days (2026-09-23–2026-10-22)"><span class="block font-medium text-home-ink">13.1M<span class="sr-only"> <!-- -->downloads in the last 30 days</span></span><span>npm</span></span></a><a href="https://www.npmjs.com/package/eslint-plugin-formatjs" aria-label="eslint-plugin-formatjs: Lint rules for message syntax, placeholders and IDs. 2,765,585 downloads in the last 30 days on npm." style="--i:2" class="home-pane-in grid min-h-[76px] items-center gap-1 p-4 no-underline transition-[background-color,transform] duration-200 hover:translate-x-1 sm:grid-cols-[1fr_auto] sm:gap-6 sm:py-3 sm:pr-6 sm:pl-5 bg-home-surface hover:bg-home-raised"><span><span class="font-medium break-words">eslint-plugin-formatjs</span><span class="block text-sm text-home-muted">Lint rules for message syntax, placeholders and IDs</span></span><span class="text-sm text-home-muted sm:text-right" title="2,765,585 downloads in the last 30 days (2026-09-23–2026-10-22)"><span class="block font-medium text-home-ink">2.8M<span class="sr-only"> <!-- -->downloads in the last 30 days</span></span><span>npm</span></span></a><a href="/docs/react-intl" style="--i:3" class="home-pane-in grid min-h-[76px] items-center gap-1 p-4 no-underline transition-[background-color,transform] duration-200 hover:translate-x-1 sm:grid-cols-[1fr_auto] sm:gap-6 sm:py-3 sm:pr-6 sm:pl-5 grid-cols-[1fr_auto] bg-primary text-white hover:bg-brand-hover"><span class="font-medium">Read the <!-- -->React<!-- --> guide</span><span aria-hidden="true" class="text-2xl">→</span></a></div></div></section><section aria-labelledby="proof-title" class="flex flex-col items-start gap-8 px-[clamp(20px,2.2vw,32px)] py-[100px] sm:py-[140px] lg:flex-row lg:items-center lg:gap-12"><h2 id="proof-title" data-reveal="true" class="m-0 text-lg font-medium whitespace-nowrap">In production at</h2><ul data-reveal="true" style="--d:80ms" class="m-0 grid w-full list-none grid-cols-2 items-center gap-x-8 gap-y-9 p-0 sm:grid-cols-3 lg:flex-1 xl:grid-cols-4"><li class="flex min-w-0 items-center gap-3"><img src="/img/anthropic.svg" alt="Anthropic" width="182" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/perplexity.svg" alt="Perplexity" width="1588" height="400" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/openai.svg" alt="OpenAI" width="269.659" height="72.5157" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/discord.svg" alt="Discord" width="219" height="32" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/atlassian.svg" alt="" width="256" height="256" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Atlassian</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/elastic.svg" alt="" width="24" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Elastic</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/salesforce.svg" alt="Salesforce" width="999" height="699.242" loading="lazy" class="max-w-full shrink-0 object-contain h-12 w-[72px]"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/grafana.svg" alt="" width="256" height="279" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Grafana Labs</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/redhat.svg" alt="" width="24" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Red Hat</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/mattermost.svg" alt="" width="501" height="501" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Mattermost</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/canva.svg" alt="" width="80" height="80" loading="lazy" class="max-w-full shrink-0 object-contain h-9 w-9"/><span class="text-lg font-medium">Canva</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/google.svg" alt="Google" width="272" height="92" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/microsoft.svg" alt="" width="256" height="256" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Microsoft</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/amazonwebservices.svg" alt="Amazon Web Services" width="304" height="182" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-10 w-auto"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/adobe.svg" alt="" width="91" height="80" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Adobe</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/cisco.svg" alt="Cisco" width="52" height="28" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-10 w-auto"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/block.svg" alt="Block" width="116" height="35" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/box.svg" alt="Box" width="24" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-12 w-auto"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/databricks.svg" alt="" width="24" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Databricks</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/snowflake.svg" alt="" width="24" height="24" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Snowflake</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/oracle.svg" alt="Oracle" width="800" height="104.049" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/yahoo.svg" alt="Yahoo" width="264.583" height="73.3754" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/dropbox.svg" alt="Dropbox" width="1000" height="196.9" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/tinder.svg" alt="Tinder" width="519" height="123" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/ethereum.svg" alt="" width="1920" height="1920" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-9 w-9"/><span class="text-lg font-medium">Ethereum</span></li><li class="flex min-w-0 items-center gap-3"><img src="/img/mozilla.svg" alt="Mozilla" width="2000" height="571.9" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li><li class="flex min-w-0 items-center gap-3"><img src="/img/coinbase_white.svg" alt="Coinbase" width="1101.64" height="196.79" loading="lazy" class="max-w-full shrink-0 object-contain brightness-0 invert-[.95] h-[26px] w-auto sm:h-7"/></li></ul></section><section aria-labelledby="cta-title" class="bg-home-surface px-[clamp(20px,2.2vw,32px)] pt-[120px] pb-[140px] sm:pt-[160px] sm:pb-[200px]"><form data-reveal="true"><h2 id="cta-title" class="m-0 text-[10vw] leading-[0.92] font-bold tracking-[-0.03em] uppercase sm:text-[clamp(48px,6vw,108px)]"><span class="flex items-center gap-[.18em]">Start with</span><span class="flex flex-wrap items-center gap-[.18em] gap-y-[.15em] sm:flex-nowrap"><label class="sr-only" for="pkg">Package</label><select id="pkg" class="h-[1.05em] cursor-pointer rounded-none border-0 px-[.25em] text-[length:inherit] leading-none font-bold tracking-[-0.03em] uppercase w-full max-w-none min-w-0 flex-[1_1_100%] appearance-none bg-home-raised text-home-ink transition-colors hover:bg-[#303030] sm:w-auto sm:max-w-[9.5em] sm:flex-none"><option value="react-intl" selected="">react-intl</option><option value="vue-intl">vue-intl</option><option value="@formatjs/svelte-intl">svelte-intl</option><option value="intl-messageformat">intl-messageformat</option><option value="@formatjs/cli">@formatjs/cli</option></select><button type="submit" class="h-[1.05em] cursor-pointer rounded-none border-0 px-[.25em] text-[length:inherit] leading-none font-bold tracking-[-0.03em] uppercase bg-primary text-white transition-[background-color,transform] hover:bg-brand-hover active:scale-[0.98]">Copy</button></span></h2><p aria-live="polite" class="mt-8 mb-0 text-lg">Copies <code>npm i react-intl</code> to your clipboard. <!-- -->The<!-- --> <a href="/docs/getting-started/installation">installation guide</a> <!-- -->takes it from there.</p></form></section></main><footer aria-labelledby="foot-title" class="grid grid-cols-2 gap-1.5 p-1.5 sm:grid-cols-12 sm:gap-2 sm:p-2.5"><div data-reveal="true" class="flex flex-col bg-home-surface p-5 lg:min-h-[220px] lg:p-6 order-6 col-span-2 justify-between gap-5 sm:order-none sm:col-span-6 lg:col-span-4"><h2 class="sr-only" id="foot-title">About FormatJS</h2><p class="m-0 text-2xl leading-[1.3]">Open source since 2014 and maintained by people who also help write<!-- --> <span class="whitespace-nowrap">ECMA-402</span>.</p><p class="m-0 text-sm text-home-muted">BSD-3-Clause.</p></div><nav data-reveal="true" style="--d:60ms" aria-label="Documentation" class="flex flex-col bg-home-surface p-5 lg:min-h-[220px] lg:p-6 order-3 col-span-1 sm:order-none sm:col-span-6 lg:col-span-3"><ul class="m-0 grid list-none gap-1.5 p-0"><li><a href="/docs/getting-started/installation" class="no-underline hover:underline">Installation</a></li><li><a href="/docs/core-concepts/icu-syntax" class="no-underline hover:underline">ICU message syntax</a></li><li><a href="/docs/react-intl" class="no-underline hover:underline">react-intl</a></li><li><a href="/docs/polyfills" class="no-underline hover:underline">Polyfills</a></li><li><a href="/docs/tooling/cli" class="no-underline hover:underline">CLI</a></li><li><a href="/docs/rust" class="no-underline hover:underline">Rust</a></li></ul></nav><div data-reveal="true" style="--d:120ms" class="flex flex-col bg-home-surface p-5 lg:min-h-[220px] lg:p-6 order-5 col-span-2 gap-0.5 sm:order-none sm:col-span-6 lg:col-span-2"><p class="m-0 text-sm text-home-muted">Your browser, formatted</p><p class="m-0 text-2xl tabular-nums"> </p><p class="m-0 text-2xl tabular-nums">—</p><p class="m-0 mt-auto text-sm text-home-muted">—</p></div><div data-reveal="true" style="--d:180ms" class="flex flex-col bg-home-surface p-5 lg:min-h-[220px] lg:p-6 order-4 col-span-1 justify-between gap-4 sm:order-none sm:col-span-6 lg:col-span-3"><p class="m-0 text-sm text-home-muted">Questions, bugs, proposals</p><a href="https://github.com/formatjs/formatjs/discussions" class="text-lg sm:text-2xl">GitHub Discussions</a></div><div class="order-1 col-span-2 flex min-h-40 items-center justify-center overflow-hidden bg-home-ink text-home-bg sm:order-none sm:col-span-12 sm:min-h-[320px] lg:col-span-8"><span class="pt-[.06em] text-[15vw] leading-none font-bold tracking-[-0.04em] uppercase lg:text-[9vw]">FormatJS</span></div><a href="/docs/getting-started/installation" class="group order-2 col-span-2 flex min-h-40 flex-col justify-between bg-primary p-5 text-white no-underline transition-colors hover:bg-brand-hover sm:order-none sm:col-span-12 sm:min-h-[200px] lg:col-span-4 lg:min-h-[320px] lg:p-6"><span class="text-2xl font-medium">Read the docs</span><svg viewBox="0 0 64 64" width="64" height="64" aria-hidden="true" class="self-end transition-transform duration-300 group-hover:translate-x-1.5 group-hover:-translate-y-1.5"><path d="M12 52 52 12M22 12h30v30" fill="none" stroke="currentColor" stroke-width="4"></path></svg></a></footer></div></div>
</body>
</html>