You make a Replit app multilingual by connecting its Git repository to GitHub and keeping the translation catalogs in that repository as committed files. Replit already stores every Agent checkpoint as a Git commit, so the repository exists before you think about languages; the work is getting it onto GitHub and letting the catalogs come back through the same history. globalize.now is AI-powered localization infrastructure: it produces the keys and locale files, and the runtime library your app already uses serves them. No dashboard sits in the runtime path, and nothing translates the page after it loads.
Why does asking the Agent to translate the app not work?
Because there is nothing to translate into. When you prompt Replit Agent for a dashboard, it writes <h2>Your bookings</h2> into a component, not a lookup against a catalog. Every heading, button, empty state, toast and validation error lands in JSX as a literal in the language you prompted in.
So when you later ask the Agent to "translate the app into Afrikaans", you get one of two half-results: a second copy of the components with the text swapped, or a hand-rolled translations object covering the screens the Agent happened to look at. Neither is a locale layer. The next feature ships in English again. We documented the same recurrence in Cursor keeps adding hardcoded strings; Replit Agent behaves no differently, because it solves the prompt in front of it, not the architecture behind it.
The fix is structural: give the strings keys, put the translations in files, and make the runtime read from the files. That is what "multilingual" means in a codebase, and it is a one-time change.
What does Replit Agent actually generate?
A conventional web project, which is the good news. Replit's curated app types are built around React with ShadCN UI on the front end, typically paired with an Express server in the same project, all in TypeScript. Since September 2025 the Agent also works with any framework you bring, including imported GitHub repositories, so a Next.js or Vue project is possible; the default path is still the React stack.
For localization, the stack is the only fact that matters, and it is standard ground. React plus Vite plus TypeScript is the most supported combination in the i18n ecosystem: i18next, Lingui and react-intl all target it directly. If the Agent built you a Next.js app instead, the choice is between next-intl, react-i18next and Lingui, and that comparison is a separate post.
What is different from a front-end-only builder is the second half of the project. A Replit app usually has a server, and servers have strings too. More on that below.
Where is the Git repository in a Replit app?
It is already there. Replit's version control is Git underneath, and Agent checkpoints are commits in that repository. Every time the Agent finishes a feature and offers you a rollback point, it has committed. Replit's own documentation recommends switching to ordinary Git commits for long-term tracking when you work with external repositories, which is exactly the situation here.
To get it onto GitHub:
- Add the Git tool from the Tools section of the project editor.
- Connect your GitHub account under connected services, then connect the repository from the Git pane. If the project has never been initialised, the pane offers to do that first.
- Push. The pane pushes with one click, and it stays in sync with anything you run in the Shell, so
git push origin mainworks too.
Replit also supports GitLab and Bitbucket, and the same flow applies. The point is not the provider; it is that the repository now lives somewhere a localization job can open a pull request against.
Do this before you touch a single string. Localization work is file work, and a diff is the right place to review it.
What does "without a dashboard" mean for a Replit app?
It means the translated strings are files in the repository and the app serves them like any other asset. No script tag, no external fetch on page load, no vendor account standing between a visitor and your copy.
The alternative is a runtime widget that swaps text after the page has painted. Its costs are structural: the first paint is English, the translated copy is not in the HTML crawlers read first, a third-party script sits in your production path, and your strings live in the vendor's store, so leaving means an export. The Lovable version of this argument is in Localize a Lovable app without a dashboard and transfers to Replit unchanged.
There is one Replit-specific reason it matters more here. Replit deploys the app for you, so the running copy on your Replit domain is whatever is in the project at deploy time. A widget would translate that deployment from outside. Catalogs in the repository mean the deployment already contains every language, and the Replit preview shows you the German version before you ship it.
The trade-off is real and worth stating: a copy change means a commit and a redeploy, not a save button. For a solo builder shipping from Replit that is a non-event; for someone who expects to edit live copy without touching the project, it is a constraint.
How does the repo-native setup work?
Connect the repository in the globalize.now app. The conversion runs once against the codebase: hardcoded strings become catalog units with keys, and the components start reading from a runtime library instead of holding literals. That is a one-time operation, not something that reruns later.
After the conversion, push jobs translate new catalog units as the app grows. Prompt the Agent for a new settings page, push, and the new units get translated; the existing ones stay put. Catalogs come back as committed files, JSON or PO depending on the runtime library, in a pull request you review like any other change.
Two boundaries, because the category is muddled. globalize.now does not replace the runtime library; i18next, Lingui and next-intl keep doing their job. And it is not a translation engine competing with DeepL. It is the layer in between that produces the keys and the locale files. The developer overview has the mechanics.
How do the translations get back into Replit?
Through the same Git pane, in the other direction. This is the step that differs from Bolt or Lovable, because Replit is also where the app runs.
- Review and merge the pull request on GitHub.
- In the Replit Git pane, select Pull. If you or the Agent changed the same files in the meantime, the pane highlights the conflicts and you resolve them in the editor before completing the merge.
- Redeploy. The catalogs are now part of the project, so the deployment carries every language.
One caveat that is specific to Replit: Agent checkpoints restore the whole project state, including files. If you roll back to a checkpoint created before you pulled the translation branch, the catalogs go with it. Treat the merge as a milestone, let the Agent create a checkpoint after it, and roll back to that one rather than an earlier one.
Which strings live on the server?
The ones the front end never sees as JSX. A Replit app with an Express back end has a second string surface: API error messages, validation responses, email subjects, notification bodies, CSV headers, anything the server formats before it sends. A front-end catalog does not reach them, and a widget cannot see them at all, because they are never in the DOM.
The pattern is the same as the client, applied server-side. Give the server a copy of the runtime library, read the visitor's locale from the request (an Accept-Language header or a locale field on the user record), and format responses from the catalog rather than from string literals. The key namespace stays shared, so errors.booking.overlap means the same thing in a toast and in a 409 response.
Skip this and the app looks multilingual until the first error, then speaks English.
What should you check before adding a second language?
Run through this before the conversion, because each item is cheaper to fix now than after five languages are in flight:
- Concatenated strings.
"Welcome back, " + user.namecannot be reordered by a translator. Interpolate instead. - Plurals. English has two forms; Polish has three, Arabic has six. A ternary on
count === 1is wrong in most languages. - Dates, numbers and currency. Use
Intl, not string formatting, on both client and server. - Layout. German and Finnish run longer than English. Fixed-width buttons break, and Tailwind classes look fine until the text arrives.
- Right-to-left. If Arabic or Hebrew is on the roadmap, decide now. Retrofitting RTL is the expensive one.
- Catalog drift. Once catalogs exist, a key added in one locale and not the others is a silent bug. Why translation files drift out of sync covers how it happens and what a push job does about it.
Pricing is per workspace, with no per-seat and no per-language charges, so the number of languages is a product decision rather than a budget line. Current figures are on the pricing page. For the same walkthrough on other builders, the vibe coders overview is the starting point.
Where to start
If your Replit project is already connected to GitHub, the next step is a conversion against that repository, not a decision about tooling. If it is not connected yet, the Git pane is the step before this one.
globalize.now turns hardcoded app copy into translation-ready locale files and keeps them updated as you ship.
Try globalize.now free