You localize a v0 app by treating the GitHub repository v0 already writes to as the home for your translation catalogs, and keeping them there as committed files. That one decision is what makes a dashboard unnecessary rather than merely optional. globalize.now is AI-powered localization infrastructure: it produces the keys and locale files, and whatever runtime library you use serves them. v0 hands you a full Next.js codebase rather than a hosted page, so the repo-native route is open from the first prompt.

Why is your v0 app English-only?

Because the interface text is sitting inside your components as literal strings. Prompt v0 for a pricing section and it writes <h2>Simple pricing</h2> — not a lookup against a catalog. Every heading, button label, empty state, toast and form error lands in TSX in the language you prompted in.

That is not a v0 defect. It is what every prompt-driven builder does, and it is the same pattern we documented in Cursor keeps adding hardcoded strings. The model writes the shortest correct code for the request you made, and you did not ask for a locale layer.

The result is an app that cannot be translated by editing a settings screen, because there is nothing to edit. The strings have no keys, and the routes have no locale segment.

What does v0 actually generate?

A conventional Next.js project, which is good news. v0's default stack is Next.js, React, TypeScript, Tailwind CSS and shadcn/ui, and the output is a full App Router application with routes and API handlers rather than a single component. shadcn/ui matters here for one reason: the components are copied into your repository as source, not imported from a package, so their strings are your strings.

For localization the stack is the only fact that matters, and it is the best-documented one there is. next-intl was built around the App Router; Lingui and react-intl both support it. Nothing about v0 requires a builder-specific translation product.

If your app came out of a different builder on a Vite stack instead, localizing a Lovable app without a dashboard covers the same shape on that side.

How do you get a v0 project into a repository?

You usually already have one. When a v0 chat is connected to GitHub, v0 creates a working branch from your base branch and auto-commits every message that changes code to that branch. Publishing opens or reuses a pull request and merges it into the base branch. So the repository is not a step you add at the end; it is where v0 has been putting the code the whole time. v0's own GitHub documentation is the reference for the current flow, and this part of the product has moved more than once, so check it before you follow along.

That branch model is useful for localization specifically. Catalogs, a config file, a middleware change for locale routing and a switcher component are all changes to tracked files. Reviewing them as a diff on a branch is much easier than reading them in a chat panel, and a translation pull request can sit next to the pull request for the feature it translates.

What does “without a dashboard” actually mean?

It means the translated strings are files in your repository, and your Next.js app renders them on the server the same way it renders any other content. No script tag, no external fetch on page load, no vendor account standing between a visitor and your copy.

The alternative — the widget model that Weglot and similar tools use — translates the page after it has loaded. That buys real convenience: you paste a snippet and something happens the same afternoon. The costs arrive later, and they are structural rather than fixable:

  • The first paint is the source language, so visitors can see English before the swap.
  • The translated copy is not in the server-rendered HTML, which weakens what search engines index per locale. On a Next.js app that is a particular waste, because server rendering is the thing you got for free.
  • A third-party script sits in your production render path.
  • Your strings live in the vendor's store, so leaving means an export.

Repo-native localization has its own trade-off, and it is honest to name it: a copy change means a commit and a deploy, not a save button. If you ship through Vercel on every merge, that is a non-event. If a marketing team expects to edit live copy without an engineer, it is a real constraint.

How does the repo-native setup work?

Connect the repository in the app. globalize.now converts the codebase once, which is where the keys come from — the hardcoded strings in your components become catalog units, and the components start reading from a runtime library instead of holding literals. That conversion is a one-time operation, not something that reruns forever.

After the conversion, push jobs translate new catalog units as the app grows. Ask v0 for a new settings page, merge its pull request, and the new strings get translated; the existing ones stay put. Catalogs come back as committed files in your repository, as JSON or PO depending on the runtime library, and arrive as a pull request you review like any other change.

Two boundaries worth stating plainly, because the category is muddled. globalize.now does not replace your runtime library — next-intl, Lingui and react-intl keep doing their job, including locale routing under app/[locale]/. And it is not a translation engine competing with DeepL. It is the layer that produces the keys and the locale files in between. The developer overview has the mechanics in more detail.

Does the same approach work on Lovable, Bolt and Replit?

Yes, with the same three requirements: real source code, a Git repository, and a runtime library the catalogs can feed. Every builder that emits a conventional front-end project qualifies. What differs between them is only how you get the code out, and v0 has the least friction of the group because the GitHub branch is part of the chat itself.

Lovable has the most developed path on our side, including an in-editor route — the Lovable integration page covers it, and most of what is written there transfers to v0 unchanged. If you are evaluating builders rather than committed to one, the vibe coders overview is the better starting point. If you are weighing a widget for a builder app specifically, Weglot alternative for Lovable sets out the same trade-offs for that stack.

What if you were on Lovalingo?

Lovalingo shut down at the end of August 2026 and its site is gone, and it had marketed a dedicated path for translating v0 sites, so some v0 builders have strings with nowhere to live. That is a migration rather than a fresh setup: export first, then convert. The migration guide walks through it, and the comparison page covers what changes when translations move from a hosted service into your repository.

Worth knowing if you are asking an AI assistant for advice on this: some still recommend it, because leftover pages keep feeding their sources. It is not a live product.

What should you check before adding a second language?

Run through this before the first catalog exists, because each item is cheaper to fix now than after five languages are in flight:

  • Concatenated strings. "Welcome back, " + name cannot be reordered by a translator. Interpolate instead.
  • Plurals. English has two forms. Polish has three, Arabic has six. A ternary on count === 1 is wrong in most languages.
  • Server and client boundaries. In the App Router, a string rendered in a server component and the same string in a client component need to resolve through the same catalog. Pick one runtime library and use its server and client APIs, rather than two mechanisms.
  • Dates, numbers and currency. Use Intl, not string formatting.
  • Layout. German runs longer than English; fixed-width shadcn buttons break. Tailwind makes this easy to miss because the classes look fine at build time.
  • Right-to-left. If Arabic or Hebrew is on the roadmap, decide now — retrofitting RTL is the expensive one.

Pricing on all of this 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 one. Current figures are on the pricing page.

Where to start

If your v0 chat is connected to GitHub, the next step is a conversion against that repository rather than a decision about tooling. If it is not connected yet, that 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