|
5 | 5 |
|
6 | 6 | # Replexica |
7 | 7 |
|
8 | | -Replexica is an open-source i18n compiler plugin for React + an AI translation platform. |
| 8 | +Replexica is a free, open-source compiler plugin for React, paired with an AI translation platform. It's a toolset that enables React apps to speak many languages. |
9 | 9 |
|
10 | | -Multi-language products get more users: 75% of the world doesn't speak English. But building such apps is a pain. *Extract* strings to JSON files, then *update* translations every time there is a change - it's a nightmare. |
| 10 | + |
| 11 | + |
11 | 12 |
|
12 | | -That's where Replexica comes in: it's a build system plugin, that translates React apps to multiple languages with AI, and doesn't require JSON files extraction / maintenance. |
| 13 | +Why does this matter? Because 75% of the world doesn't speak English. If the app is multilingual, it can serve many more users. But, let's be honest, making an app multilingual is a headache. You have to extract strings to JSON files and update translations every time something changes. |
13 | 14 |
|
14 | | -Replexica compiler is open-source, and the API is open so you can build your own translation engine. We're also building our own AI translation platform, to make it even easier to roll out your first multi-language app ;) |
| 15 | +That's where Replexica comes in: it's a build system plugin that translates React apps into multiple languages using AI. The best part? It doesn't require messing around with extracting or maintaining JSON files. |
| 16 | + |
| 17 | +## The API |
| 18 | + |
| 19 | +```js |
| 20 | +import compiler from '@replexica/compiler'; |
| 21 | + |
| 22 | +/** @type {import('next').NextConfig} */ |
| 23 | +const nextConfig = {}; |
| 24 | + |
| 25 | +/** @type {import('@replexica/compiler').ReplexicaConfig} */ |
| 26 | +const replexicaConfig = { |
| 27 | + locale: { |
| 28 | + source: 'en', |
| 29 | + targets: ['es'], |
| 30 | + }, |
| 31 | +}; |
| 32 | + |
| 33 | +export default compiler.next( |
| 34 | + replexicaConfig, |
| 35 | + nextConfig, |
| 36 | +); |
| 37 | + |
| 38 | +``` |
| 39 | + |
| 40 | +## The Roadmap |
15 | 41 |
|
16 | 42 | - [x] Replexica Compiler |
17 | | - - [x] Next.js |
| 43 | + - [x] Next.js App Router |
| 44 | + - [ ] Next.js Pages Router |
18 | 45 | - [ ] Remix |
19 | 46 | - [ ] Create React App |
20 | 47 | - [x] Replexica Framework |
21 | 48 | - [x] JSX translation |
22 | 49 | - [x] Custom context hints |
23 | | - - [ ] Translation of string literals using a helper |
| 50 | + - [x] Skipper for non-translatable text |
| 51 | + - [x] Avoid fetching unused translations |
| 52 | + - [x] Translation of JSX attributes (title, alt, placeholder) |
| 53 | + - [ ] Translation of generic literals with helper functions |
| 54 | + - [ ] Translation of arbitrary attributes |
24 | 55 | - [x] Replexica Platform |
25 | 56 | - [x] AI Translation Engine |
26 | 57 | - [x] Translation memory |
27 | 58 | - [x] Context awareness aka **Brand voice** |
28 | | - - [ ] i18n overrides |
29 | | - - [ ] i18n quality checks |
| 59 | + - [ ] Supported locales (production-ready, state-of-the-art quality) |
| 60 | + - [x] English |
| 61 | + - [x] Spanish |
| 62 | + - [ ] French (April 2024) |
| 63 | + - [ ] German (April 2024) |
| 64 | + - [ ] (Create a GitHub issue ) |
| 65 | + - [ ] Automated i18n quality checks (May 2024) |
| 66 | + - [ ] Documentation/examples on self-hosted translation engine |
30 | 67 | - [x] Replexica CLI |
31 | 68 | - [x] CLI for Replexica Platform |
32 | 69 | - [x] Open-source API schema |
33 | 70 | - [ ] GitHub Actions integration |
34 | 71 |
|
35 | | -## How it works |
| 72 | +The Replexica compiler is open-source, and the API is open, allowing you to build your own translation engine. We're also developing our own AI translation platform ([replexica.com](https://replexica.com)), to make it even easier to launch your first multi-language app! |
| 73 | + |
| 74 | +## How it Works |
36 | 75 |
|
37 | | -Replexica is a compiler plugin. It hooks into your build system, and collects all the user-facing text in your app, getting it ready for translation with the Replexica platform. Here's how it works: |
| 76 | +Replexica is a compiler plugin that integrates with the build system, collecting all user-facing text in the app and preparing it for translation with the Replexica platform. Here's how it works: |
38 | 77 |
|
39 | | -1. **Infers** metadata from your app, like the text that needs to be translated and the context it's in. The metadata is then stored alongside your build artifacts. |
40 | | -1. **Translates** the text using the CLI that connects to the Replexica platform. The platform uses AI to translate the text, and the more you use it, the better it gets. The API is open, so you can build your own translation engine if you want! |
| 78 | +1. **Infers** metadata from your app, such as the text that needs to be translated and its context. This metadata is then stored alongside the build artifacts. |
| 79 | +1. **Translates** the text using the CLI that connects to the Replexica platform. The platform uses AI to translate the text, and the more you use it, the better it gets. The API is open, so you can build your own translation engine if you wish! |
41 | 80 | 1. **Injects** the translations back into your app, so that the translated text is displayed to the user, based on their locale. |
42 | 81 |
|
43 | | -So, with Replexica, you can build multi-language apps without the hassle of JSON files, and with the power of AI translation. |
| 82 | +With Replexica, you can build multi-language apps without the hassle of managing JSON files, and with the power of AI translation. |
| 83 | + |
| 84 | +## The Replexica Rule |
| 85 | + |
| 86 | +At Replexica, we believe in the elegance of [Convention over configuration](https://en.wikipedia.org/wiki/Convention_over_configuration) principle. |
| 87 | + |
| 88 | +Therefore, there's an important rule to remember when using Replexica: |
| 89 | + |
| 90 | +> [!TIP] |
| 91 | +> Place translatable text inside `JSX`. |
| 92 | +
|
| 93 | +As long as you follow this rule, the Replexica Compiler can automatically infer the metadata from your app and prepare the text inside JSX for translation. |
| 94 | + |
| 95 | +If you don't follow the rule and decide to store some of your translatable content in variables, that **can be translated too**, but you'll need to manually wrap that text in a helper function. |
| 96 | + |
| 97 | +So, if you want a hassle-free i18n on autopilot, **follow The Replexica Rule** whenever possible. |
| 98 | + |
| 99 | +## Getting Started |
| 100 | + |
| 101 | +#### Step 1. Install Replexica |
| 102 | + |
| 103 | +```bash |
| 104 | +pnpm add replexica @replexica/compiler @replexica/react |
| 105 | +``` |
| 106 | + |
| 107 | +#### Step 2. Configure NextJS |
| 108 | + |
| 109 | +```js |
| 110 | +// next.config.mjs |
| 111 | + |
| 112 | +import compiler from '@replexica/compiler'; |
| 113 | + |
| 114 | +/** @type {import('next').NextConfig} */ |
| 115 | +const nextConfig = {}; |
| 116 | + |
| 117 | +/** @type {import('@replexica/compiler').ReplexicaConfig} */ |
| 118 | +const replexicaConfig = { |
| 119 | + locale: { |
| 120 | + source: 'en', // Language the app's content is in |
| 121 | + targets: ['es'], // Target language(s) |
| 122 | + }, |
| 123 | +}; |
| 124 | + |
| 125 | +export default compiler.next( |
| 126 | + replexicaConfig, |
| 127 | + nextConfig, |
| 128 | +); |
| 129 | + |
| 130 | +``` |
| 131 | + |
| 132 | +#### Step 3. Configure React App |
| 133 | + |
| 134 | +> [!NOTE] |
| 135 | +> This guide is for Next.js App Router apps only. Guides for other setups are coming soon (ETA April 2024). |
| 136 | +
|
| 137 | +If you plan on having `'use client'` components in your app (you probably do), you'll need to also wrap your entire component tree in `<ReplexicaProvider />`: |
| 138 | + |
| 139 | +```jsx |
| 140 | +import { ReplexicaIntlProvider } from '@replexica/react/client'; |
| 141 | +import { loadLocaleFromCookie } from '@replexica/react/next'; |
| 142 | + |
| 143 | +// ... rest of the code |
| 144 | + |
| 145 | +export default async function RootLayout({ |
| 146 | + children, |
| 147 | +}: Readonly<{ |
| 148 | + children: React.ReactNode; |
| 149 | +}>) { |
| 150 | + const locale = await loadLocaleFromCookie(); |
| 151 | + // Note the .client.json suffix of the i18n file below. |
| 152 | + // It means that only the values *actually used* get passed to the client, not the entire i18n dictionary. |
| 153 | + const localeData = await import(`@replexica/translations/${locale}.client.json`).then((m) => m.default); |
| 154 | + return ( |
| 155 | + <ReplexicaIntlProvider data={localeData}> |
| 156 | + <html lang={locale}> |
| 157 | + <body className={inter.className}>{children}</body> |
| 158 | + </html> |
| 159 | + </ReplexicaIntlProvider> |
| 160 | + ); |
| 161 | +} |
| 162 | + |
| 163 | +``` |
| 164 | + |
| 165 | +## How to Switch Between Languages |
| 166 | + |
| 167 | +Different apps use different strategies for switching between supported languages. Here are a few approaches we've seen: |
| 168 | + |
| 169 | +- Cookie value (get/set cookie value) |
| 170 | +- Subdomain (`en.myapp.com` / `es.myapp.com`) |
| 171 | +- TLD domain (`myapp.com` / `myapp.es`) |
| 172 | +- Pathname segments (`myapp.com/en` / `myapp.com/es`) |
| 173 | + |
| 174 | +... and so on. |
| 175 | + |
| 176 | +To support every possible strategy, now and in the future, Replexica does the following: |
| 177 | + |
| 178 | +*Replexica reads the value of the `REPLEXICA_LOCALE` cookie to determine the currently selected locale* |
| 179 | + |
| 180 | +So, whatever approach you choose for switching between locales, just be sure to update the value of the `REPLEXICA_LOCALE` cookie, and Replexica will handle the rest. |
44 | 181 |
|
45 | | -## Getting started |
| 182 | +## Questions? |
46 | 183 |
|
47 | | -## License |
| 184 | +If you have any questions, feel free to create a GitHub issue! |
0 commit comments