Skip to content

Commit bf0cbff

Browse files
committed
docs: revert accidental delete of react-intl.md, fix formatjs#1996
1 parent 8b4e25d commit bf0cbff

File tree

3 files changed

+314
-3
lines changed

3 files changed

+314
-3
lines changed

website/docs/react-intl.md

Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
---
2+
id: react-intl
3+
title: Overview
4+
---
5+
6+
[![npm Version](https://img.shields.io/npm/v/react-intl.svg?style=flat-square)](https://www.npmjs.org/package/react-intl)
7+
8+
**Welcome to React Intl's docs! This is the place to find React Intl's docs**. Feel free to open a pull request and contribute to the docs to make them better.
9+
10+
## Runtime Requirements
11+
12+
**We support IE11 & 2 most recent versions of Edge, Chrome, Firefox & Safari.**
13+
14+
React Intl relies on these `Intl` APIs:
15+
16+
- [Intl.NumberFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat): Available on IE11+
17+
- [Intl.DateTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat): Available on IE11+
18+
- [Intl.PluralRules](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules): This can be polyfilled using [this package](polyfills/intl-pluralrules.md).
19+
- [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat): This can be polyfilled using [this package](polyfills/intl-relativetimeformat.md).
20+
- (Optional) [Intl.DisplayNames](https://tc39.es/proposal-intl-displaynames/): Required if you use [`formatDisplayName`](react-intl/api.md#formatdisplayname)
21+
or [`FormattedDisplayName`](react-intl/components.md#formatteddisplayname). This can be polyfilled using [this package](polyfills/intl-displaynames.md).
22+
23+
If you need to support older browsers, we recommend you do the following:
24+
25+
1. Polyfill `Intl.NumberFormat` with [`@formatjs/intl-numberformat`](polyfills/intl-numberformat.md).
26+
2. Polyfill `Intl.DateTimeFormat` with [`@formatjs/intl-datetimeformat`](polyfills/intl-datetimeformat.md)
27+
3. If you're supporting browsers that do not have [`Intl.PluralRules`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules) (e.g IE11 & Safari 12-), include this [polyfill](polyfills/intl-pluralrules.md) in your build.
28+
29+
4. If you're supporting browsers that do not have [Intl.RelativeTimeFormat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat) (e.g IE11, Edge, Safari 12-), include this [polyfill](polyfills/intl-relativetimeformat.md) in your build along with individual CLDR data for each locale you support.
30+
31+
5. If you need `Intl.DisplayNames`, include this [polyfill](polyfills/intl-displaynames.md) in your build along with individual CLDR data for each locale you support.
32+
33+
### Browser
34+
35+
We officially support IE11 along with 2 most recent versions of Edge, Chrome & Firefox.
36+
37+
### Node.js
38+
39+
#### full-icu
40+
41+
Starting with Node.js 13.0.0 full-icu is supported by default.
42+
43+
If using React Intl in an earlier version of Node.js, your `node` binary has to either:
44+
45+
- Get compiled with `full-icu` using these [instructions](https://nodejs.org/api/intl.html)
46+
47+
**OR**
48+
49+
- Uses [`full-icu` npm package](https://www.npmjs.com/package/full-icu)
50+
51+
If your `node` version is missing any of the `Intl` APIs above, you'd have to polyfill them accordingly.
52+
53+
### React Native
54+
55+
If you're using `react-intl` in React Native, make sure your runtime has built-in `Intl` support (similar to [JSC International variant](https://github.com/react-native-community/jsc-android-buildscripts#international-variant)). See these issues for more details:
56+
57+
- https://github.com/formatjs/formatjs/issues/1356
58+
- https://github.com/formatjs/formatjs/issues/992
59+
60+
#### React Native on iOS
61+
62+
If you cannot use the Intl variant of JSC (e.g on iOS), follow the instructions in [Runtime Requirements](#runtime-requirements) to polyfill those APIs accordingly.
63+
64+
## Experimental Intl Features
65+
66+
FormatJS also provides types & polyfill for the following Intl API proposals:
67+
68+
- NumberFormat: [polyfill](polyfills/intl-numberformat.md) & [spec](https://tc39.es/ecma402/)
69+
- DisplayNames: [polyfill](polyfills/intl-displaynames.md) & [spec](https://tc39.es/proposal-intl-displaynames/)
70+
71+
## The `react-intl` Package
72+
73+
Install the [`react-intl` npm package](https://www.npmjs.com/package/react-intl) via npm:
74+
75+
```bash
76+
$ npm install react-intl --save
77+
```
78+
79+
The `react-intl` npm package distributes the following modules (links from [unpkg](https://unpkg.com/)):
80+
81+
- [**CommonJS**](https://unpkg.com/react-intl@latest/dist/index.js):
82+
unbundled dependencies, `"main"` in `package.json`, warnings in dev.
83+
- [**ES6**](https://unpkg.com/react-intl@latest/lib/index.js):
84+
unbundled dependencies, `"module"` in `package.json`, warnings in dev.
85+
- [**UMD dev**](https://unpkg.com/react-intl@latest/dist/react-intl.js):
86+
bundled dependencies (except `react`), browser or Node, warnings.
87+
- [**UMD prod**](https://unpkg.com/react-intl@latest/dist/react-intl.min.js):
88+
minified, bundled dependencies (except `react`), browser or Node, no warnings.
89+
90+
### Module Bundlers
91+
92+
We've made React Intl work well with module bundlers like: Browserify, Webpack, or Rollup which can be used to bundle React Intl for the browser:
93+
94+
- The `"browser"` field in `package.json` is specified so that only basic English locale data is included when bundling. This way when using the `"main"` module in Node all locale data is loaded, but ignored when bundled for the browser.
95+
96+
- An ES6 version of React Intl is provided as `"jsnext:main"` and `"module"` in `package.json` and can be used with Rollup.
97+
98+
- Development-time warnings are wrapped with `process.env.NODE_ENV !== 'production'`, this allows you to specify `NODE_ENV` when bundling and minifying to have these code blocks removed.
99+
100+
## The React Intl Module
101+
102+
Whether you use the ES6, CommonJS, or UMD version of React Intl, they all provide the same named exports:
103+
104+
- [`injectIntl`](react-intl/api.md#injectintl)
105+
- [`defineMessages`](react-intl/api.md#definemessages)
106+
- [`IntlProvider`](react-intl/components.md#intlprovider)
107+
- [`FormattedDate`](react-intl/components.md#formatteddate)
108+
- [`FormattedTime`](react-intl/components.md#formattedtime)
109+
- [`FormattedRelativeTime`](react-intl/components.md#formattedrelativetime)
110+
- [`FormattedNumber`](react-intl/components.md#formattednumber)
111+
- [`FormattedPlural`](react-intl/components.md#formattedplural)
112+
- [`FormattedMessage`](react-intl/components.md#formattedmessage)
113+
114+
:::danger react
115+
When using the UMD version of React Intl _without_ a module system, it will expect `react` to exist on the global variable: **`React`**, and put the above named exports on the global variable: **`ReactIntl`**.
116+
:::
117+
118+
## Creating an I18n Context
119+
120+
Now with React Intl and its locale data loaded an i18n context can be created for your React app.
121+
122+
React Intl uses the provider pattern to scope an i18n context to a tree of components. This allows configuration like the current locale and set of translated strings/messages to be provided at the root of a component tree and made available to the `<Formatted*>` components. This is the same concept as what Flux frameworks like [Redux](http://redux.js.org/) use to provide access to a store within a component tree.
123+
124+
**All apps using React Intl must use the [`<IntlProvider>` component](react-intl/components.md#intlprovider).**
125+
126+
The most common usage is to wrap your root React component with `<IntlProvider>` and configure it with the user's current locale and the corresponding translated strings/messages:
127+
128+
```tsx
129+
ReactDOM.render(
130+
<IntlProvider locale={usersLocale} messages={translationsForUsersLocale}>
131+
<App />
132+
</IntlProvider>,
133+
document.getElementById('container')
134+
)
135+
```
136+
137+
**See:** The [**`<IntlProvider>` docs**](react-intl/components.md#intlprovider) for more details.
138+
139+
## Formatting Data
140+
141+
React Intl has two ways to format data, through [React components](react-intl/components.md) and its [API](react-intl/api.md). The components provide an idiomatic-React way of integrating internationalization into a React app, and the `<Formatted*>` components have [benefits](react-intl/components.md#why-components) over always using the imperative API directly. The API should be used when your React component needs to format data to a string value where a React element is not suitable; e.g., a `title` or `aria` attribute, or for side-effect in `componentDidMount`.
142+
143+
React Intl's imperative API is accessed via [**`injectIntl`**](react-intl/api.md#injectintl), a High-Order Component (HOC) factory. It will wrap the passed-in React component with another React component which provides the imperative formatting API into the wrapped component via its `props`. (This is similar to the connect-to-stores pattern found in many Flux implementations.)
144+
145+
Here's an example using `<IntlProvider>`, `<Formatted*>` components, and the imperative API to setup an i18n context and format data:
146+
147+
```tsx
148+
import React from 'react';
149+
import ReactDOM from 'react-dom';
150+
import {injectIntl, IntlProvider, FormattedRelative, useIntl} from 'react-intl';
151+
152+
const MS_IN_DAY = 1e3 * 3600 * 24
153+
154+
const PostDate = ({date}) => {
155+
const intl = useIntl()
156+
return (
157+
<span title={intl.formatDate(date)}>
158+
<FormattedRelativeTime value={(Date.now() - date)/MS_IN_DAY} unit="day"/>
159+
</span>
160+
)
161+
});
162+
163+
const App = ({post}) => (
164+
<div>
165+
<h1>{post.title}</h1>
166+
<p>
167+
<PostDate date={post.date} />
168+
</p>
169+
<div>{post.body}</div>
170+
</div>
171+
);
172+
173+
ReactDOM.render(
174+
<IntlProvider locale={navigator.language}>
175+
<App
176+
post={{
177+
title: 'Hello, World!',
178+
date: new Date(1459913574887),
179+
body: 'Amazing content.',
180+
}}
181+
/>
182+
</IntlProvider>,
183+
document.getElementById('container')
184+
);
185+
```
186+
187+
Assuming `navigator.language` is `"en-us"`:
188+
189+
```html
190+
<div>
191+
<h1>Hello, World!</h1>
192+
<p><span title="4/5/2016">yesterday</span></p>
193+
<div>
194+
Amazing content.
195+
</div>
196+
</div>
197+
```
198+
199+
**See:** The [**API docs**][api] and [**Component docs**][components] for more details.
200+
201+
# ESM Build
202+
203+
`react-intl` and its underlying libraries (`intl-messageformat-parser`, `intl-messageformat`, `@formatjs/intl-relativetimeformat`, `intl-utils`) export ESM artifacts. This means you should configure your build toolchain to transpile those libraries.
204+
205+
### Jest
206+
207+
Add `transformIgnorePatterns` to always include those libraries, e.g:
208+
209+
```tsx
210+
{
211+
transformIgnorePatterns: [
212+
'/node_modules/(?!intl-messageformat|intl-messageformat-parser).+\\.js$',
213+
],
214+
}
215+
```
216+
217+
### webpack
218+
219+
If you're using `babel-loader`, or `ts-loader`, you can do 1 of the following:
220+
221+
1. Add those libraries in `include`:
222+
223+
```ts
224+
{
225+
include: [
226+
path.join(__dirname, 'node_modules/react-intl'),
227+
path.join(__dirname, 'node_modules/intl-messageformat'),
228+
path.join(__dirname, 'node_modules/intl-messageformat-parser'),
229+
]
230+
}
231+
```
232+
233+
OR
234+
235+
2. Add those libraries in `exclude`:
236+
237+
```tsx
238+
exclude: /node_modules\/(?!react-intl|intl-messageformat|intl-messageformat-parser)/,
239+
```
240+
241+
# Core Concepts
242+
243+
- Formatters (Date, Number, Message, Relative)
244+
- Provider and Injector
245+
- API and Components
246+
- Message Descriptor
247+
- Message Syntax
248+
- Defining default messages for extraction
249+
- Custom, named formats
250+
251+
# Example Apps
252+
253+
There are several [**runnable example apps**](https://github.com/formatjs/formatjs/tree/master/packages/react-intl/examples) in this Git repo. These are a great way to see React Intl's [core concepts](#core-concepts) in action in simplified applications.
254+
255+
# API Reference
256+
257+
There are a few API layers that React Intl provides and is built on. When using React Intl you'll be interacting with `Intl` built-ins, React Intl's API, and its React components:
258+
259+
- [ECMAScript Internationalization API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
260+
- [React Intl API](react-intl/api.md)
261+
- [React Intl Components](react-intl/components.md)
262+
263+
# TypeScript Usage
264+
265+
`react-intl` is written in TypeScript, thus having 1st-class TS support.
266+
267+
In order to use `react-intl` in TypeScript, make sure your `compilerOptions`'s `lib` config include `["esnext.intl", "es2017.intl", "es2018.intl"]`.
268+
269+
# Advanced Usage
270+
271+
Our [Advanced Usage](guides/advanced-usage.md) has further guides for production setup in environments where performance is important.
272+
273+
# Supported Tooling
274+
275+
## Message extraction
276+
277+
We've built [@formatjs/cli](tooling/cli.md) that helps you extract messages from a list of files. It uses [babel-plugin-react-intl](tooling/babel-plugin.md) under the hood and should be able to extract messages if you're declaring using 1 of the mechanisms below:
278+
279+
```tsx
280+
import {defineMessages} from 'react-intl'
281+
282+
defineMessages({
283+
foo: {
284+
id: 'foo',
285+
defaultMessage: 'foo',
286+
description: 'bar',
287+
},
288+
})
289+
```
290+
291+
```tsx
292+
import {FormattedMessage} from 'react-intl'
293+
;<FormattedMessage id="foo" defaultMessage="foo" description="bar" />
294+
```
295+
296+
```tsx
297+
function Comp(props) {
298+
const {intl} = props
299+
return intl.formatMessage({
300+
// The whole `intl.formatMessage` is required so we can extract
301+
id: 'foo',
302+
defaultMessage: 'foo',
303+
description: 'bar',
304+
})
305+
}
306+
```
307+
308+
## ESLint Plugin
309+
310+
We've also built [eslint-plugin-formatjs](tooling/linter.md) that helps enforcing specific rules on your messages if your translation vendor has restrictions.

website/docusaurus.config.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ module.exports = {
3232
activeBaseRegex: `docs/(getting-started|guides|core-concepts)`,
3333
},
3434
{
35-
to: 'docs/react-intl/components',
35+
to: 'docs/react-intl',
3636
label: 'API References',
3737
position: 'left',
3838
activeBaseRegex: `docs/(react-intl|intl-messageformat|intl-messageformat-parser)`,
@@ -63,7 +63,7 @@ module.exports = {
6363
items: [
6464
{
6565
label: 'Getting Started',
66-
to: 'docs/core-concepts/basic-internationalization-principles',
66+
to: 'docs/getting-started/installation',
6767
},
6868
{
6969
to: 'docs/polyfills',

website/sidebars.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module.exports = {
2222
},
2323
api: {
2424
'react-intl': [
25+
'react-intl',
2526
'react-intl/components',
2627
'react-intl/api',
2728
'react-intl/upgrade-guide-5x',
@@ -53,4 +54,4 @@ module.exports = {
5354
'tooling/ts-transformer',
5455
],
5556
},
56-
};
57+
}

0 commit comments

Comments
 (0)