Internationalization

Adapting components to respect languages and cultures of users around the world is an important way to help make your application accessible to the widest number of people. React Aria supports over 30 languages, including right-to-left mirroring and interactions.

Introduction#


Internationalization is the process of structuring your code and user interface to support localization. React Aria supports many aspects of localization for many components out of the box, including translations for builtin strings, localized date and number formatting, right-to-left interactions, and more. By using React Aria to build your components, these aspects of internationalization are handled for you. You can also use our hooks in your own custom components.

Localization#


Localization is the process of adapting an application for a particular language or region. It includes translating text content, as well as adapting date formatting, number formatting, collation and sorting, text search, and more.

React Aria includes translations for all builtin strings in over 30 locales. However, because React Aria provides no rendering, most of the builtin strings are for non-visible content to provide accessible labels. All application provided content must be localized and passed in to components. This can be done with libraries such as react-intl. Internally, React Aria uses the same intl-messageformat library used by react-intl.

React Aria also formats, parses, and manipulates dates and numbers according to the user's preferred locale, and uses internationalized algorithms for collation, sorting, and text search. This is built into all of the components that need to perform these tasks out of the box, but you can also use our internationalization hooks in your own components. These are implemented with the builtin browser Intl APIs under the hood, so there's no large libraries or locale data for users to download.

See useDateFormatter, useNumberFormatter, and useCollator for more information about using our internationalization hooks. The Internationalized collection of libraries provides framework-agnostic utilities for representing and manipulating dates and times, and parsing and formatting numbers across many locales, calendar systems, numbering systems, and more.

Bi-directionality#


Many languages such as those written in the Latin script (e.g. English and French), Cyrillic script (e.g. Russian and Bulgarian), and logographic scripts (e.g. Chinese and Japanese) are written left to right. Other languages such as Arabic and Hebrew are written right to left. These languages are called “bi-directional,” or are also commonly referred to as “RTL” (“right-to-left”) languages.

In right-to-left languages, user interfaces are expected to be mirrored. Layouts flip such that components are positioned on the opposite side of the interface. For example, a button that would be displayed on the right side of a screen in a left-to-right language would appear on the left side of the screen in a right-to-left language. In addition, elements within a component are also expected to mirror. For example, in a checkbox component, the label would be placed on the left side of the checkmark rather than the right.

Since React Aria provides no styling, it is up to you to implement RTL support in your design. CSS flex and grid layouts automatically flip depending on the direction, and logical properties are a great way to handle margins, paddings, borders, and more.

Even though it is not responsible for rendering or layout, React Aria is aware of the current directionality, and adjusts interactions accordingly. For example, when navigating using the left and right arrow keys, React Aria automatically flips the direction so that the left arrow always navigates to the item physically to the left, and the right arrow always navigates to the item physically to the right.

Example#


The root most element of your application should define the lang and dir attributes so that the browser knows which language and direction the user interface should be rendered in. This can be done with the useLocale hook.

import {useLocale} from 'react-aria-components';

function YourApp() {
  let {locale, direction} = useLocale();

  return (
    <div lang={locale} dir={direction}>
      {/* your app here */}
    </div>
  );
}
import {useLocale} from 'react-aria-components';

function YourApp() {
  let {locale, direction} = useLocale();

  return (
    <div lang={locale} dir={direction}>
      {/* your app here */}
    </div>
  );
}
import {useLocale} from 'react-aria-components';

function YourApp() {
  let {
    locale,
    direction
  } = useLocale();

  return (
    <div
      lang={locale}
      dir={direction}
    >
      {/* your app here */}
    </div>
  );
}

React Aria automatically detects the user's current language by default, and even updates this if the browser or system language changes. However, if you would like to override this with an application specific setting, you can do so using the I18nProvider component.

import {I18nProvider} from 'react-aria-components';

<I18nProvider locale="fr-FR">
  <YourApp />
</I18nProvider>
import {I18nProvider} from 'react-aria-components';

<I18nProvider locale="fr-FR">
  <YourApp />
</I18nProvider>
import {I18nProvider} from 'react-aria-components';

<I18nProvider locale="fr-FR">
  <YourApp />
</I18nProvider>

Note: if you are using server side rendering, you should always specify a locale rather than relying on browser defaults to ensure that the server and client match. See the SSR docs for more information.

Supported locales#


React Aria currently includes translations for over 30 locales. They are listed below.

  • Arabic (United Arab Emirates)
  • Bulgarian (Bulgaria)
  • Chinese (Simplified)
  • Chinese (Traditional)
  • Croatian (Croatia)
  • Czech (Czech Republic)
  • Danish (Denmark)
  • Dutch (Netherlands)
  • English (Great Britain)
  • English (United States)
  • Estonian (Estonia)
  • Finnish (Finland)
  • French (Canada)
  • French (France)
  • German (Germany)
  • Greek (Greece)
  • Hebrew (Israel)
  • Hungarian (Hungary)
  • Italian (Italy)
  • Japanese (Japan)
  • Korean (Korea)
  • Latvian (Latvia)
  • Lithuanian (Lithuania)
  • Norwegian (Norway)
  • Polish (Poland)
  • Portuguese (Brazil)
  • Romanian (Romania)
  • Russian (Russia)
  • Serbian (Serbia)
  • Slovakian (Slovakia)
  • Slovenian (Slovenia)
  • Spanish (Spain)
  • Swedish (Sweden)
  • Turkish (Turkey)
  • Ukrainian (Ukraine)

Optimizing bundle size#


By default, React Aria includes translations for all of the languages listed above. This is inclusive to the most users out of the box, but comes at the cost of bundle size. If your application does not support all of these locales, you can use our build plugins to include only the languages that you do support in your JavaScript bundle.

Note: If you are using server side rendering, you can also optimize this even further by sending only the strings for the current user's language. See the SSR docs for more details.

webpack#

First, install @react-aria/optimize-locales-plugin with your package manager. Then, add the following to your webpack.config.js and change the locales setting accordingly:

// webpack.config.js
const optimizeLocales = require('@react-aria/optimize-locales-plugin');

module.exports = {
  // ...
  plugins: [
    optimizeLocales.webpack({
      locales: ['en-US', 'fr-FR']
    })
  ]
};
// webpack.config.js
const optimizeLocales = require(
  '@react-aria/optimize-locales-plugin'
);

module.exports = {
  // ...
  plugins: [
    optimizeLocales.webpack({
      locales: ['en-US', 'fr-FR']
    })
  ]
};
// webpack.config.js
const optimizeLocales =
  require(
    '@react-aria/optimize-locales-plugin'
  );

module.exports = {
  // ...
  plugins: [
    optimizeLocales
      .webpack({
        locales: [
          'en-US',
          'fr-FR'
        ]
      })
  ]
};

Next.js#

First, install @react-aria/optimize-locales-plugin with your package manager. Then, add the following to your next.config.js and change the locales setting accordingly:

// next.config.js
const optimizeLocales = require('@react-aria/optimize-locales-plugin');

module.exports = {
  webpack(config) {
    config.plugins.push(
      optimizeLocales.webpack({
        locales: ['en-US', 'fr-FR']
      })
    );
    return config;
  }
};
// next.config.js
const optimizeLocales = require(
  '@react-aria/optimize-locales-plugin'
);

module.exports = {
  webpack(config) {
    config.plugins.push(
      optimizeLocales.webpack({
        locales: ['en-US', 'fr-FR']
      })
    );
    return config;
  }
};
// next.config.js
const optimizeLocales =
  require(
    '@react-aria/optimize-locales-plugin'
  );

module.exports = {
  webpack(config) {
    config.plugins.push(
      optimizeLocales
        .webpack({
          locales: [
            'en-US',
            'fr-FR'
          ]
        })
    );
    return config;
  }
};

Vite#

First, install @react-aria/optimize-locales-plugin with your package manager. Then, add the following to your vite.config.js and change the locales setting accordingly:

// vite.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    {
      ...optimizeLocales.vite({
        locales: ['en-US', 'fr-FR']
      }),
      enforce: 'pre'
    }
  ]
};
// vite.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    {
      ...optimizeLocales.vite({
        locales: ['en-US', 'fr-FR']
      }),
      enforce: 'pre'
    }
  ]
};
// vite.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    {
      ...optimizeLocales
        .vite({
          locales: [
            'en-US',
            'fr-FR'
          ]
        }),
      enforce: 'pre'
    }
  ]
};

Rollup#

First, install @react-aria/optimize-locales-plugin with your package manager. Then, add the following to your rollup.config.js and change the locales setting accordingly:

// rollup.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    optimizeLocales.rollup({
      locales: ['en-US', 'fr-FR']
    })
  ]
};
// rollup.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    optimizeLocales.rollup({
      locales: ['en-US', 'fr-FR']
    })
  ]
};
// rollup.config.js
import optimizeLocales from '@react-aria/optimize-locales-plugin';

export default {
  plugins: [
    optimizeLocales
      .rollup({
        locales: [
          'en-US',
          'fr-FR'
        ]
      })
  ]
};

Esbuild#

First, install @react-aria/optimize-locales-plugin with your package manager. Then, add the following to your esbuild script and change the locales setting accordingly:

import {build} from 'esbuild';
import optimizeLocales from '@react-aria/optimize-locales-plugin';

build({
  plugins: [
    optimizeLocales.esbuild({
      locales: ['en-US', 'fr-FR']
    })
  ]
});
import {build} from 'esbuild';
import optimizeLocales from '@react-aria/optimize-locales-plugin';

build({
  plugins: [
    optimizeLocales.esbuild({
      locales: ['en-US', 'fr-FR']
    })
  ]
});
import {build} from 'esbuild';
import optimizeLocales from '@react-aria/optimize-locales-plugin';

build({
  plugins: [
    optimizeLocales
      .esbuild({
        locales: [
          'en-US',
          'fr-FR'
        ]
      })
  ]
});

Parcel#

First, install @react-aria/parcel-resolver-optimize-locales with your package manager. Then, add the following to your .parcelrc:

{
  "extends": "@parcel/config-default",
  "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "..."]
}
{
  "extends": "@parcel/config-default",
  "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "..."]
}
{
  "extends": "@parcel/config-default",
  "resolvers": ["@react-aria/parcel-resolver-optimize-locales", "..."]
}

Then, in your project root package.json, add a "locales" field containing the languages you want to support:

{
  "locales": ["en-US", "fr-FR"]
}
{
  "locales": ["en-US", "fr-FR"]
}
{
  "locales": ["en-US", "fr-FR"]
}