All Projects → moxystudio → next-intl

moxystudio / next-intl

Licence: MIT license
Library to integrate react-intl with Next.js.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to next-intl

Translation
The Translation component provides tools to internationalize your application.
Stars: ✭ 6,196 (+15012.2%)
Mutual labels:  l10n, intl
Globalize
A JavaScript library for internationalization and localization that leverages the official Unicode CLDR JSON data
Stars: ✭ 4,612 (+11148.78%)
Mutual labels:  l10n, intl
iXn
Control your localization of apps
Stars: ✭ 20 (-51.22%)
Mutual labels:  l10n, intl
Fluent
Fluent — planning, spec and documentation
Stars: ✭ 818 (+1895.12%)
Mutual labels:  l10n, intl
Nofw
A no-framework application skeleton
Stars: ✭ 212 (+417.07%)
Mutual labels:  l10n
Ngettext
A cross-platform .NET implementation of the GNU/Gettext library.
Stars: ✭ 172 (+319.51%)
Mutual labels:  l10n
Locales
🌎 a set of locales generated from the CLDR Project which can be used independently or within an i18n package; these were built for use with, but not exclusive to https://github.com/go-playground/universal-translator
Stars: ✭ 166 (+304.88%)
Mutual labels:  l10n
Punic
PHP translation and localization made easy!
Stars: ✭ 133 (+224.39%)
Mutual labels:  l10n
webpack-extract-translation-keys
This plugin extracts translation keys for applications requiring runtime translations
Stars: ✭ 35 (-14.63%)
Mutual labels:  l10n
i18n-literally
🍦 A simple way to introduce internationalization to your JS
Stars: ✭ 80 (+95.12%)
Mutual labels:  l10n
Weblate
Web based localization tool with tight version control integration.
Stars: ✭ 2,719 (+6531.71%)
Mutual labels:  l10n
Node Gettext
A JavaScript implementation of gettext, a localization framework.
Stars: ✭ 175 (+326.83%)
Mutual labels:  l10n
Serge
Continuous localization platform
Stars: ✭ 212 (+417.07%)
Mutual labels:  l10n
Es2015 I18n Tag
ES2015 template literal tag for i18n and l10n (translation and internationalization)
Stars: ✭ 171 (+317.07%)
Mutual labels:  l10n
git-manpages-l10n
Translation of git manpages
Stars: ✭ 193 (+370.73%)
Mutual labels:  l10n
Google Play Badge Svg
Hosting for localized versions of Google Play badges in SVG format.
Stars: ✭ 137 (+234.15%)
Mutual labels:  l10n
Glotpress Wp
🌍 🌎 🌏 GlotPress is a WordPress plugin to let you set up your own collaborative, web-based software translation tool.
Stars: ✭ 205 (+400%)
Mutual labels:  l10n
React Native Globalize
Internationalization (i18n) for React Native
Stars: ✭ 246 (+500%)
Mutual labels:  l10n
Universal Translator
💬 i18n Translator for Go/Golang using CLDR data + pluralization rules
Stars: ✭ 195 (+375.61%)
Mutual labels:  l10n
Cldr
Elixir implementation of CLDR/ICU
Stars: ✭ 178 (+334.15%)
Mutual labels:  l10n

next-intl

NPM version Downloads Build Status Coverage Status Dependency status Dev Dependency status

Library to integrate react-intl with Next.js.

Installation

$ npm install --save @moxy/next-intl react-intl

ℹ️ If you are running Node.js < 13.1.0, you must also install full-icu and start node with --icu-data-dir=node_modules/full-icu or use NODE_ICU_DATA=node_modules/full-icu.

Setup

1. Configure next.config.js

Please configure i18n as explained in the official Next.js docs.

// next.config.js
module.exports = {
    i18n: {
        locales: ['en', 'pt'],
        defaultLocale: 'en',
    },
};

2. Create a root folder named intl to hold translation files:

intl/
    en.json
    pt.json

The intl/en.json file contains the messages for the en locale, like so:

{
    "hello": "Hello World"
}

3. Wrap your app with withIntlApp() in pages/_app.js:

// pages/_app.js
import React from 'react';
import App from 'next/app';
import { withIntlApp } from '@moxy/next-intl';

// The example below dynamically downloads translations from your JSON files,
// but you may load them from external sources, such as a CMS.
// Please note that the result will be cached on the client-side,
// to avoid fetching translations on every page change.
const loadLocale = async (locale) => {
    const module = await import(/* webpackChunkName: "intl-messages" */ `../intl/${locale}.json`);

    return module.default;
};

export default withIntlApp(loadLocale)(App);

Here's an example if you have a custom app:

import React from 'react';
import { withIntlApp } from '@moxy/next-intl';
import Layout from '../components/layout';

const MyApp = ({ Component, pageProps }) => (
    <Layout>
        <Component { ...pageProps } />
    </Layout>
);

const loadLocale = async (locale) => {
    const module = await import(/* webpackChunkName: "intl-messages" */ `../intl/${locale}.json`);

    return module.default;
};

export default withIntlApp(loadLocale)(MyApp);

4. Use getIntlProps() in your pages.

// pages/index.js
import React from 'react';
import { getIntlProps } from '@moxy/next-intl';

const Home = () => (
    <main>
        <FormattedMessage id="hello" />
    </main>
);

export const getStaticProps = async ({ locale }) => ({
    props: await getIntlProps(locale),
});

export default Home;

If you already are using getStaticProps for something else:

export const getServerSideProps = async ({ locale }) => {
    const [foo, localeProps] = await Promise.all([
        fetchFoo(),
        getIntlProps(locale);
    ]);

    return {
        foo,
        ...localeProps,
    };
};

ℹ️ If you are using getServerSideProps(), then it works the same as the examples that use getStaticProps().

FAQ

How can I use this getIntlProps() in my page's getInitialProps()?

// pages/index.js
import React from 'react';
import { getIntlProps } from '@moxy/next-intl';
import { FormattedMessage } from 'react-intl';

const Home = () => (
    <main>
        <FormattedMessage id="hello" />
    </main>
);

Home.getInitialProps = async ({ locale }) => ({
    ...await getIntlProps(locale),
});

export default Home;

However, the locale parameter will be undefined in the getInitialProps() function above because Next.js doesn't pass it as of now, but there's an open pull-request to resolve it.

To circumvent this, you must override pages/_app.js like so:

// pages/_app.js
import App from 'next/app';

const MyApp = (props) => <App { ...props } />;

MyApp.getInitialProps = async (appCtx) => {
    appCtx.ctx.locale = appCtx.router.locale;
    appCtx.ctx.locales = appCtx.router.locales;
    appCtx.ctx.defaultLocale = appCtx.router.defaultLocale;

    const appProps = await App.getInitialProps(appCtx);

    return appProps;
};

export default MyApp;

⚠️ Please note that adding getInitialProps() to your App will disable Automatic Static Optimization in pages without Static Generation.

How do I avoid repeating getIntlProps() in all my pages?

You can use getIntlProps() once in your pages/_app.js, like so:

// pages/_app.js
import App from 'next/app';

const MyApp = (props) => <App { ...props } />;

MyApp.getInitialProps = async (appCtx) => {
    const [intlProps, appProps] = await Promise.all([
        getIntlProps(appCtx.router.locale),
        App.getInitialProps(appCtx),
    ]);

    return {
        ...intlProps,
        ...appProps,
    };
};

export default MyApp;

⚠️ Please note that adding getInitialProps() to your App will disable Automatic Static Optimization in pages without Static Generation.

How do I load intl polyfills?

In previous versions of this library, all polyfills were automatically downloaded. This is no longer the case. However, you may load any polyfills and locale data inside the loadLocale() function.

Here's an example that loads the @formatjs/intl-pluralrules polyfill.

// _app.js
import { shouldPolyfill as shouldPolyfillPluralRules } from '@formatjs/intl-pluralrules/should-polyfill';

// ...

const loadLocale = async (locale) => {
    if (shouldPolyfillPluralRules()) {
        await import(/* webpackChunkName: "intl-pluralrules" */ '@formatjs/intl-pluralrules/polyfill');
    }

    if (Intl.PluralRules.polyfilled) {
        switch (locale) {
        case 'pt':
            await import(/* webpackChunkName: "intl-pluralrules-pt" */ '@formatjs/intl-pluralrules/locale-data/pt')
            break;
        default:
            await import(/* webpackChunkName: "intl-pluralrules-en" */ '@formatjs/intl-pluralrules/locale-data/en')
            break
        }
    }

    const module = await import(/* webpackChunkName: "intl-messages" */ `../intl/${locale}.json`);

    return module.default;
};

export default withIntlApp(loadLocale)(App);

Tests

$ npm t
$ npm t -- --watch  # To run watch mode

License

Released under the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].