diff --git a/website/docs/misc/examples.md b/website/docs/misc/examples.md index 1a9c0682e..e51f69d03 100644 --- a/website/docs/misc/examples.md +++ b/website/docs/misc/examples.md @@ -13,8 +13,8 @@ Check out the example projects below: - [Create React App](https://github.com/lingui/js-lingui/tree/main/examples/create-react-app) - [Vanilla JS](https://github.com/lingui/js-lingui/tree/main/examples/js) - [Next.js with Babel](https://github.com/lingui/js-lingui/tree/main/examples/nextjs-babel) -- [Next.js with SWC](https://github.com/lingui/js-lingui/tree/main/examples/nextjs-swc) -- [React Native](https://github.com/lingui/js-lingui/tree/main/examples/react-native) +- [Next.js with SWC and app router](https://github.com/lingui/js-lingui/tree/main/examples/nextjs-swc) +- [React Native (uses Expo)](https://github.com/lingui/js-lingui/tree/main/examples/react-native) - [React with Vite and Babel](https://github.com/lingui/js-lingui/tree/main/examples/vite-project-react-babel) - [React with Vite and SWC](https://github.com/lingui/js-lingui/tree/main/examples/vite-project-react-swc) - [Rspack with SWC](https://github.com/lingui/js-lingui/tree/main/examples/rspack) diff --git a/website/docs/misc/resources.md b/website/docs/misc/resources.md index a9e983b3a..f933598c5 100644 --- a/website/docs/misc/resources.md +++ b/website/docs/misc/resources.md @@ -5,7 +5,6 @@ - [How to Localize JavaScript and React Apps with LinguiJS](https://crowdin.com/blog/2022/12/13/lingui-i18n?utm_source=lingui.dev&utm_medium=referral&utm_campaign=lingui.dev) - by [Crowdin](https://crowdin.com/?utm_source=lingui.dev&utm_medium=referral&utm_campaign=lingui.dev) - [How to build a fully internationalized Nextjs application using Lingui v4](https://bravo-kernel.com/blog/2023/05/how-to-build-a-fully-internationalized-nextjs-application-using-lingui-v4) by [Bravo_Kernel](https://twitter.com/bravo_kernel) - [The complete guide to internationalization in Next.js](https://blog.logrocket.com/complete-guide-internationalization-nextjs/) - by [Ivan Vlatkovic](https://blog.logrocket.com/author/ivanvlatkovic/) -- [Internationalization of Next.js 13 app with App Router](https://medium.com/@amir.latypov/internationalization-of-nextjs-13-app-with-app-router-946ff017962b) - by [Amir Latypov](https://medium.com/@amir.latypov) - [How We Migrated a Large React Application from react-i18next to LinguiJS in 1 Day](https://medium.com/@radist2s/one-command-one-day-multiple-languages-our-migration-from-react-i18next-to-linguijs-4b07ac73a9bb) - by [Alex Batalov](https://medium.com/@radist2s) - [Javascript i18n with Lingui](https://mikewilliamson.wordpress.com/2017/11/05/javascript-i18n-with-lingui/) - by [Mike Williamson](https://mikewilliamson.wordpress.com/) diff --git a/website/docs/tutorials/react-native.md b/website/docs/tutorials/react-native.md index ab22b1ba8..8bc2c4c09 100644 --- a/website/docs/tutorials/react-native.md +++ b/website/docs/tutorials/react-native.md @@ -5,7 +5,7 @@ description: Learn how to add internationalization to a React Native application # Internationalization of React Native apps -In this tutorial, we'll learn how to add internationalization to an existing application in React Native. Before going further, please follow the [setup guide](/docs/tutorials/setup-react.mdx) for installation and setup instructions. +In this tutorial, we'll learn how to add internationalization to an existing application in React Native. Before going further, please follow the [setup guide](/docs/tutorials/setup-react.mdx?babel-or-swc=babel) (for Babel) for installation and configuration instructions. :::caution Warning @@ -186,7 +186,7 @@ const showDeleteConfirmation = () => { The last remaining piece of the puzzle is changing the active locale. The `i18n` object exposes [`i18n.loadAndActivate()`](/ref/core#i18n.loadAndActivate) for that. Call the method and the [`I18nProvider`](/docs/ref/react.md#i18nprovider) will re-render the translations. It all becomes clear when you take a look at the [final code](https://github.com/lingui/js-lingui/tree/main/examples/react-native/src/MainScreen.tsx#L29). -However, we don't recommend that you change the locale like this, as it can cause conflicts in how your app ui is localized. This is further [explained here](https://www.youtube.com/live/uLicTDG5hSs?feature=share&t=9088). +However, we don't recommend that you change the locale like this in mobile apps, as it can cause conflicts in how your app ui is localized. This is further [explained here](https://www.youtube.com/live/uLicTDG5hSs?feature=share&t=9088). ## Choosing the default locale diff --git a/website/docs/tutorials/react-rsc.md b/website/docs/tutorials/react-rsc.md new file mode 100644 index 000000000..870353d2f --- /dev/null +++ b/website/docs/tutorials/react-rsc.md @@ -0,0 +1,186 @@ +--- +title: Lingui with React Server Components +description: Learn how to setup and use Lingui with RSC & Next.js +--- + +Lingui provides support for React Server Components (RSC) as of v4.10.0. In this tutorial, we'll learn how to add internationalization to an application with the Next.js [App Router](https://nextjs.org/docs/app). However, the same principles are applicable to any RSC-based solution. + +:::tip Hint +There's a working example available [here](#). We will make references to the important parts of it throughout the tutorial. The example is more complete than this tutorial. + +The example uses both Pages Router and App Router, so you can see how to use Lingui with both in [this commit](#). +::: + +Before going further, please follow the [React setup](/tutorials/setup-react?babel-or-swc=swc) for installation and configuration instructions (for SWC or Babel depending on which you use - most likely it's SWC). You may also need to configure your `tsconfig.json` according to [this visual guide](https://twitter.com/mattpocockuk/status/1724462050288587123). This is so that TypeScript understands the values exported from `@lingui/react` package. + +### Adding i18n support to Next.js + +Firstly, your Next.js app needs to be ready for routing and rendering of content in multiple languages. This is done through the middleware (see the [example app's middleware](#)). Please read the [official Next.js docs](https://nextjs.org/docs/app/building-your-application/routing/internationalization) for more information. + +After configuring the middleware, make sure your page and route files are moved from `app` to `app/[lang]` folder (example: `app/[lang]/layout.tsx`). This enables the Next.js router to dynamically handle different locales in the route, and forward the `lang` parameter to every layout and page. + +### Next.js Config + +Secondly, add the `swc-plugin` to the `next.config.js`, so that you can use [Lingui macros](https://lingui.dev/ref/macro). + +```js title="next.config.js" +/** @type {import('next').NextConfig} */ +module.exports = { + // to use Lingui macros + experimental: { + swcPlugins: [["@lingui/swc-plugin", {}]], + }, +}; +``` + +### Setup with server components + +With Lingui, the experience of localizing React is the same in client and server components: `Trans` and `useLingui` can be used identically in both worlds, even though internally there are two implementations. + +:::tip Under the hood +Translation strings, one way or another, are obtained from an [I18n](/docs/ref/core.md) object instance. In client components, this instance is passed around using React context. Because context is not available in Server components, instead [`cache`](https://react.dev/reference/react/cache) is used to maintain an I18n instance for each request. +::: + +To make Lingui work in both server and client components, we need to take the `lang` prop which Next.js will pass to our layouts and pages, and create a corresponding instance of the I18n object. We then make it available to the components in our app. This is a 2-step process: + +1. given `lang`, take an I18n instance and store it in the [`cache`](https://react.dev/reference/react/cache) so it can be used server-side +2. given `lang`, take an I18n instance and make it available to client components via I18nProvider + +This is how step (1) can be implemented: + +```tsx title="src/app/[lang]/layout.tsx" +import { setI18n } from "@lingui/react/server"; +import { allI18nInstances } from "./appRouterI18n"; +import { LinguiClientProvider } from "./LinguiClientProvider"; + +type Props = { + params: { + lang: string; + }; + children: React.ReactNode; +}; + +export default function RootLayout({ params: { lang }, children }: Props) { + const i18n = allI18nInstances[lang]; // get a ready-made i18n instance for the given locale + setI18n(i18n); // make it available server-side for the current request + + return ( + +
+
+
{t(i18n)`Other Item`}
+