@weglot/translate-react
Translate your
React,
Next.js or
Vite app
No t() wrappers, no JSON files. Add a build plugin and a Weglot API key: the text in your JSX is translated when your app builds, and your team edits translations in Weglot without touching code.
Copy the prompt for · · · read the docs · view on npm
Requires React 19 Next.js 15 / 16.0.4+ (App Router) or Vite Node 20.9+
111,368+ global brands rely on Weglot to translate their websites
// how it works
Four steps. Your components stay as they are.
Source and target languages come from your Weglot project, not from your code. The plugin reads the text in your JSX at build time and fetches its translations.
-
Install the package and add your API key
Create a Weglot 2.0 project, then copy its API key from the project settings. It starts with
pk_. Keep.envout of version control.terminal · .env$ npm install @weglot/translate-react # .env WEGLOT_API_KEY=pk_your_weglot_api_key
-
Add the plugin
Wrap your Next.js config with
withWeglot. PointsourceRootto the folder that holds your pages and components.Add
weglotPluginto your Vite config. With Webpack, import it from@weglot/translate-react/webpackinstead.next.config.tsimport type { NextConfig } from "next"; import { withWeglot } from "@weglot/translate-react/next"; const nextConfig: NextConfig = {}; export default async function (): Promise<NextConfig> { return await withWeglot(nextConfig, { sourceRoot: "./app" }); }
vite.config.tsimport { defineConfig } from "vite"; import { weglotPlugin } from "@weglot/translate-react/vite"; export default defineConfig({ plugins: [weglotPlugin({ sourceRoot: "src" })], });
-
Add the provider
Wrap your root layout with
WeglotProviderfrom the Next.js entry point, so that changing language refreshes your server components.Wrap your app with
WeglotProvider, as early as possible.app/layout.tsximport { WeglotProvider } from "@weglot/translate-react/react/next"; export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <WeglotProvider>{children}</WeglotProvider> </body> </html> ); }
src/main.tsximport { WeglotProvider } from "@weglot/translate-react/react"; root.render( <WeglotProvider> <App /> </WeglotProvider>, );
-
Build, and ship in every language of your project
Each build fetches missing translations from Weglot and writes
public/translations/<locale>.json. Ignore that folder. Add a language switcher withLocaleSwitcheroruseWeglotContext..gitignorepublic/translations/
// compare
Why not a classic i18n library?
i18n libraries ask you to replace every string with a key and keep one file per language. Weglot reads the strings you already wrote. Here is how the options compare.
| Criteria | Weglot@weglot/translate-react |
next-intl / i18next | Paraglide JS | CMS native localization |
|---|---|---|---|---|
| Wrap strings in t() or message functions | NoText in JSX is detected at build time. | Yest("key") for every string. |
Yesm.key() message functions. |
Content onlyStrings in your code still need a library. |
| Translation files per language | None to maintainGenerated at build, git-ignored. | YesTypically one JSON file per locale. | YesOne message file per locale. | NoStored in the CMS. |
| Multilingual routing and SEO (URL per language, hreflang) | Not yetLanguage stored in a cookie. Same URLs for all languages, source language indexed. | next-intl: yesLocale routing built in. i18next: through your framework setup. | YesLocalized URLs built in: locale prefixes, translated paths or domains. Add hreflang tags yourself. | Front endA headless CMS stores content per locale. URLs and hreflang come from your front end. |
| Translations generated for you | YesWeglot translates with an LLM during the build. | NoBring your own translations or a TMS. | With toolinginlang CLI machine translation, or your coding agent. | Paid add-onAI translation on paid plans: Contentful AI Actions, Sanity AI Assist, Strapi AI Translations. |
| Edit translations without a developer | YesReview and edit in the Weglot dashboard. | NoEdit JSON files, or add a separate TMS. | With Finkinlang's web editor, with a GitHub account. | YesIn the CMS editor. |
| Set up by a coding agent in one prompt | YesOne install, two config edits. Copyable prompt below. | Long taskThe agent rewrites every string into keys and files. | Long taskinit runs without prompts for agents, then every string becomes an m.key() message. |
n/aConfigured in the CMS. |
// built for coding agents
Built for AI coding agents
If you build with Claude Code, Cursor or Codex, your agent can add Weglot on its own. There are no strings to rewrite, so the change is small and easy to review.
01 · setup
The agent installs and configures it
One npm install, one plugin, one provider, one line in .gitignore. The agent only asks you for the API key.
02 · docs
Docs that LLMs can read
The documentation has an llms.txt index, and every page has a Markdown version: add .md to its URL.
03 · prompt
A prompt ready to copy
Each step of the prompt matches the getting-started guide, with the real import paths. Copy it below.
$ npm install @weglot/translate-react
// for your team
Edit and review without touching code
Every translation appears in your Weglot project. Product, marketing and translators review and edit the wording there, without opening a pull request.
- Review the translations Weglot generates for your app.
- Edit any translation in the Weglot dashboard.
- Exclude anything from code with
translate="no"ordata-weglot-skip.
// fit
When to use Weglot, and when not to
The package is in preview. Here is where it fits today.
Use @weglot/translate-react if
- Your app runs React 19 on Next.js (App Router) or Vite.
- You don't want to wrap strings in t() or maintain one file per language.
- Your coding agent writes most of the code, and you want translation to keep up with it.
- People who don't code need to review and edit translations.
- Your UI text lives in code, with CMS content you can translate server-side.
Use something else if
- You need one URL per language and translated pages indexed by search engines today. Use next-intl or Paraglide JS.
- You want translations as files in your repo, reviewed in pull requests. Use inlang with Paraglide JS or i18next.
- Your app is on React 18, the Next.js Pages Router, or Next.js 14 or older.
- Your site is built in a CMS or website builder, not React. Use Weglot's CMS integrations.
FAQ
Does it handle SEO: one URL per language and hreflang?
Not today. The visitor's language is stored in a cookie and every language is served on the same URLs, so search engines index the source language only.
You can translate page titles and descriptions with tDynamicAll in generateMetadata. If you need indexed URLs per language now, use a library with locale routing, such as next-intl or Paraglide JS.
How do I translate dynamic content from a CMS, an API or users?
The plugin only translates text written in your code. For content your code never sees, call tDynamic, tDynamicAll or tDynamicHtml from @weglot/translate-react/dynamic in Next.js server components.
If the API takes longer than 500 ms, or a text is requested for the first time, they return the source text. The translation is ready on a later request. If you cache data yourself, make the cache depend on the visitor's language.
Next.js or Vite: what changes?
Next.js uses withWeglot from @weglot/translate-react/next and WeglotProvider from @weglot/translate-react/react/next. Vite uses weglotPlugin from @weglot/translate-react/vite and WeglotProvider from @weglot/translate-react/react. Webpack uses weglotPlugin from @weglot/translate-react/webpack.
The dynamic content functions only run in Next.js server components.
Does it work with React Server Components?
Yes, with the Next.js App Router. Import WeglotProvider from @weglot/translate-react/react/next so that changing language refreshes your server components. tDynamic, tDynamicAll and tDynamicHtml run server-side, in server components.
What happens when I build?
The plugin finds the text in the JSX under sourceRoot and asks the Weglot API for the translations it lacks. Weglot generates them with an LLM, and the build waits up to translationTimeout (300 seconds by default). It then writes public/translations/<locale>.json.
If translation fails, the build fails and keeps what it received in the local cache: build again to continue. With buildMode: "cache-only", the build makes no network calls.
Where are the translations stored?
In your Weglot project, where you review and edit them. Each build also keeps the translations it received in <sourceRoot>/weglot/cache/<locale>.json. Commit that folder to build without calling the API, or ignore it. public/translations/ is generated and goes in .gitignore.
What gets translated, and how do I exclude something?
Text in JSX, string literals inside JSX expressions, strings read from constants, and attributes such as title, alt, placeholder and aria-label. Code, URLs, class names and strings outside JSX are left alone. Add translate="no" or data-weglot-skip to keep an element in the original language. Declare your own text props with translatableAttributes.
Make your React app multilingual without rewriting it
Install the package, add your API key, build.
$ npm install @weglot/translate-react
Prefer to do it yourself? Read the docs or view the package on npm