Join Our Newsletter!

Keep up to date with our latest blog posts, new widgets and features, and the Common Ninja Developer Platform.

How to Translate a Lovable Website

Sergei Davidov, · Updated Aug 24, 2026

Summary (TL;DR): How to translate a website built with Lovable: the difference between real internationalisation inside the app and a translation layer on top, what each costs in time and maintenance, which one search engines can actually index, how to add a translator to a Lovable project, what should never be machine translated, and how to test the result before trusting it.

How to Translate a Lovable Website

You built a site with Lovable, it works, and then somebody arrived who does not read the language it is written in. Maybe you saw it in your analytics, maybe a customer asked, maybe you always intended to sell somewhere else and have finally got round to it.

So you search for how to translate it, and you get two completely different kinds of answer. One set talks about translation widgets and language selectors and takes about ten minutes. The other talks about internationalisation libraries, locale files, namespaces and routing, and clearly takes a week.

Both are correct. They are answers to different questions, and almost nobody tells you which question you are actually asking. Choosing wrong is expensive in one direction and merely disappointing in the other: you either spend a fortnight rebuilding how your app renders text when a widget would have done, or you ship a widget and wonder for three months why you still have no visitors from Germany.

This article is about telling those two apart, then doing whichever one you need.

What You Get From Lovable Before You Change Anything

Worth setting expectations first, because a lot of the confusion starts here.

Lovable generates a real web application. That is the useful thing about it and it is also the thing that shapes this whole question. There is no switch that converts a finished site into a multilingual one, because being multilingual is not a feature a site has, it is a property of how the app renders text. A site is multilingual when its text comes from somewhere that can supply more than one language, and that is a decision made in the structure of the app rather than in a settings panel.

What this means in practice is better than it sounds. Because Lovable writes ordinary React, everything the wider ecosystem knows about translating a React app applies to your project unchanged. The standard libraries work. The standard patterns work. And Lovable is perfectly capable of setting them up for you, provided you ask for the structure rather than the outcome.

That distinction is the single most useful prompting tip in this article. "Make my site available in German" is a vague instruction and tends to produce a German version of whatever text was in view at the time, which is not a multilingual site, it is a translated page. "Set up internationalisation with locale files and a language prefix in the route" is a structural instruction and produces something you can actually build on. Ask for the plumbing, not the result.

The other thing to know before choosing is where your text currently lives. In a freshly generated app, the words are usually sitting directly inside the components, written as plain strings. Every approach below is, in some form, about changing where those words come from, either by moving them into files you control or by intercepting them after they reach the browser. Knowing that makes the rest of this straightforward.

If you already know you want the fast route and just want the thing on the page, the website translator widget is the short answer and the rest of this article explains when it is the right one and when it is not.

The Two Routes, and Why They Are Not Interchangeable

Strip away the jargon and the difference is where the translation happens.

Real internationalisation happens in your code, before the page is sent. Every piece of text in your app is replaced by a key, and each key has a value in each language you support, kept in a file. The app decides which language to use, usually from the URL, and renders that language. The visitor receives a page that was German from the moment it left the server.

A translation layer happens in the visitor's browser, after the page arrives. Your app is built and sent in one language. A script then walks the finished page and swaps the text it finds for translated text. The visitor receives an English page that becomes German a moment later.

That single difference in timing decides everything else: how long it takes to build, what happens when you add a paragraph next week, how good the translations are, and, the part people miss entirely, whether search engines ever see the other language at all.

Here is the comparison in the form that actually helps.

 Real internationalisationTranslation layer
Where it happensIn your code, before sendingIn the browser, after arriving
Time to first resultDays for a small siteMinutes
Separate URL per languageYesNo
Cost of adding a new pageExtract its strings, translate each oneNothing, it is covered automatically
Translation qualityWhatever you put in the file, including humanMachine, unless the tool allows overrides
Can build search presence in the languageYesNo
Ongoing maintenanceReal and permanentClose to none

Route One: Internationalisation Inside the App

This is the proper version, and Lovable can write most of it for you if you ask in the right terms.

The shape of the work is always the same. You add an internationalisation library. You create a file per language, each holding the same set of keys with different values. You replace every hardcoded string in every component with a lookup against those keys. You add a way for the visitor to choose, and, importantly, you put the chosen language in the URL rather than in a cookie, so that each language version is a distinct address. Then you add hreflang annotations, which are small tags that tell search engines these pages are versions of each other in different languages.

A reasonable prompt to Lovable is something like: "Set up internationalisation with a language prefix in the route, so English is at the root and German is under a slash de. Extract every user facing string in the app into locale files, one per language. Add a language switcher in the header and hreflang tags in the document head."

What nobody warns you about is the second week. The library setup is the easy part and Lovable will do it well. The permanent cost is that every string you write from then on has to go into every locale file, and the moment one slips through, your German page has an English sentence in the middle of it. On a small marketing site that is manageable. On an app with a lot of copy it is a discipline, and if you are not going to keep it up, you are better off not starting.

Take this route when another language is part of what your site is for: you sell in that market, you want to be found in that market, and the copy matters enough to be written rather than generated.

Route Two: A Translation Layer on Top

This is the ten minute version, and it is not a lesser choice, it is a different one.

You add a widget. It puts a language selector somewhere on the page, and when a visitor picks a language, the text on the page is replaced with a translated version. Your components do not change. Your routing does not change. A page you add next month is covered without you doing anything, because the widget translates whatever is on the page rather than a list of strings you maintained by hand.

The advantages are real and worth naming plainly. It works immediately. It covers the whole site including the pages you forget about. It survives redesigns. And it costs you nothing in ongoing discipline, which matters more than people expect, because the thing that kills a half built internationalisation setup is not difficulty, it is attention.

The trade is equally real. The translations are machine translations, so they are decent for navigation, headings and general prose and unreliable for anything precise. There is a visible moment where the page is in the original language before the swap happens. And, the important one, it does not build search presence in the translated language, for reasons in the next section.

Take this route when the goal is comprehension rather than acquisition: visitors are already finding you, some of them do not read your language, and you want them to understand the site rather than to have found it in their own language in the first place.

The website translator widget is the version of this we make, and there are Lovable specific notes on the website translator for Lovable page.

The Part About Search That Decides It

This is where most advice goes quiet, and it is usually the fact that settles which route you need.

Google's guidance on multilingual sites is direct about structure. It asks you to use a different URL for each language version of a page rather than relying on cookies or browser settings, and to connect those versions with hreflang annotations. It also states that Google works out a page's language from the visible content of the page, not from a lang attribute and not from the URL.

Put those two together and the consequence for a translation layer follows on its own. A translation layer serves one URL. The content that leaves your server is in the original language, and the swap happens afterwards in the visitor's browser. There is no second address for a search engine to index, and no separate page whose visible content is German. So the German version is not a thing that can rank, because as far as the index is concerned it does not exist as a page.

That is not a criticism of translation widgets and it is not a penalty. It is simply a description of what each tool is for. The widget serves the reader who is already on your site. Internationalisation serves the person who has not found you yet and is searching in their own language.

One related myth is worth killing while we are here, because it makes people afraid of a tool they should be using. Google does not treat machine translation as spam by default. Its spam policies name translation in the specific context of scaled content abuse, which means mass generating pages through automated transformation in order to manipulate rankings. A language selector that helps genuine visitors read your genuine site is not that, and nothing about adding one puts your site at risk.

The real risk with machine translation is quality, not penalties, and that is a different problem with a different answer, covered further down.

Adding a Translator to a Lovable Project

If you have chosen the layer, the mechanics take about as long as reading this section.

Build the widget first: choose which languages to offer, decide whether the selector sits in the header or floats in a corner, and style it so it looks like part of the site rather than a bolted on control. Then copy the embed snippet, which is a container element plus a loader script.

Getting it into Lovable is the only step with a catch, and it is the same catch for every third party embed. A Lovable project is a React application, and a snippet pasted in as raw HTML will render the container while silently never running the script, which produces an empty gap that looks exactly like a broken widget. The reliable routes are to prompt Lovable and tell it explicitly that the loader must be added as a real script element, or to put the script tag in the project's index.html so it loads once for the whole app. We covered that in detail, including why it happens, in widgets to embed on your Lovable site.

Two things worth deciding while you are in there. Put the selector where a visitor who cannot read the page can still find it, which usually means the top of the page and an icon rather than the word "Language" written in English. And consider whether to let it detect the browser language automatically: it is convenient, but a visitor whose browser is set to one language and who prefers to read another finds it irritating, so if you do detect, always leave the selector visible so the choice can be overridden.

What Should Never Be Machine Translated

Whichever route you take, some text should not be handled automatically, and the rule is easier than it sounds: anything that commits you to something gets translated by a person, and everything else can be generated.

  • Terms, privacy policies and refund conditions. These are promises with legal weight, and a machine translation can change the promise without changing anything that looks wrong.
  • Pricing and what is included. A mistranslated qualifier turns a limit into an entitlement, and you will find out when somebody holds you to it.
  • Safety, medical, financial or regulatory copy. If the field has rules about how you describe things, those rules apply in every language you publish in.
  • Your name, your product names and your taglines. Translators translate them, which is how a brand ends up meaning something unfortunate. Most tools let you mark terms as do not translate, and it is worth the five minutes.
  • Anything inside an image. Text baked into a graphic is invisible to every translation method, so if a diagram carries meaning, it needs a translated version or a caption that does the work.

Everything else, navigation, headings, feature descriptions, blog prose, is exactly what machine translation is good at, and holding it back until you can afford a human translator usually means it never happens at all.

Testing It Before You Trust It

Translated sites break in ways that are invisible if you only ever look at them in your own language, and all of the common failures are cheap to catch.

Look at the longest language you support. German and Finnish words are frequently much longer than their English equivalents, and a button sized to fit "Save" will not fit the translation. Buttons, tabs, table headers and anything in a fixed width container are where this shows up first.

Read one page end to end in each language, on a phone. Not skim, read. Half translated pages, where a heading changed and a button did not, are the single most common defect and they are obvious the moment somebody actually reads the page.

Check the things that are not words. Dates, currencies, number formats and units carry meaning and are not always converted. A price that stays in one currency beside translated text is confusing, and a date written the American way in a European language is genuinely ambiguous.

Try it with the widget blocked. If the script fails to load, on a bad connection or behind a corporate filter, your site should still be a working site in the original language rather than a broken one.

If you offer a right to left language, check the layout and not just the words. Arabic, Hebrew, Persian and Urdu read from right to left, and translating the text without flipping the layout produces a page that is technically correct and genuinely hard to use: navigation on the wrong side, text aligned against the wrong edge, icons pointing the wrong way. Real internationalisation lets you set the document direction along with the language, so the layout mirrors properly. A translation layer usually swaps the words and leaves the layout exactly where it was, so if one of these languages matters to you, test it specifically rather than assuming it came along with the rest.

If you went the internationalisation route, add one more check: confirm each language really is on its own URL and that the hreflang tags point at each other correctly. A set of language versions that all live at the same address is the failure mode that quietly wastes the entire effort, because it gives you the maintenance cost of doing it properly and the search results of not having bothered.

So Which One Do You Need

One question decides it, and it is not a technical question.

Do you want to be found in that language, or understood in it?

If you want to be found, if the plan is that somebody in Spain searches in Spanish and lands on you, then you need real internationalisation with its own URLs and hreflang, and you need the important pages translated by a person rather than a machine. Nothing else produces that outcome, and no widget will.

If you want to be understood, if people are already arriving and some of them are struggling, then a translation layer is the correct tool and the week you would have spent on locale files is better spent elsewhere. It is not a compromise. It is the thing that matches the problem.

And if the answer is both, do them in that order: the layer today, because it helps the visitors you already have and costs almost nothing, then real internationalisation for the specific market you decide to commit to, once you know which one that is. The mistake is doing the expensive one first for a market you were only guessing about.

If you want the quick version now, start from the website translator widget or the Lovable install notes. If you are still filling in the rest of the site, our roundup of widgets to embed on your Lovable site covers the other six things a generated app usually turns out to be missing.

Sergei Davidov

Sergei Davidov

Sergei Davidov is a Growth Manager at Common Ninja with nearly a decade of experience spanning content strategy, SEO, conversion optimization, and business development. He's helped launch products, optimize funnels, and build marketing systems across e-commerce and SaaS. When he's not dissecting funnel metrics, he writes fiction and experiments in the kitchen.

LinkedIn

FAQ

Add a translator widget. It puts a language selector on the page and translates the text in place, it takes minutes rather than days, and it needs no changes to your components or your routing. That is the right answer when your goal is that a visitor who does not read your language can still understand your site. It is the wrong answer if your goal is to rank in another language, which needs the other route described in this article.

There are free options on both routes. Open source internationalisation libraries cost nothing to use, though the work of extracting every string and maintaining a file per language is real and ongoing. Translator widgets typically have a free tier that covers a small site. The honest cost comparison is not the licence, it is your time: one route is an afternoon and the other is a structural change to how your app renders text.

No, and it is worth being clear about that rather than hopeful. Google asks for a different URL for each language version of a page, and it works out a page's language from the visible content it receives. A translation layer serves one URL whose source content is in one language and swaps the text in the visitor's browser afterwards. That helps the reader in front of you. It does not create the separate language versions that rank. If search presence in another language is the goal, you want real internationalisation with its own URLs and hreflang annotations.

Not as a rule, and the widespread claim that it does overstates what Google actually says. Its spam policies name translation in the context of scaled content abuse, meaning mass generating pages through automated transformation to manipulate rankings. A language selector that helps real visitors read your real site is not that. The practical risk is not a penalty, it is quality: an unreviewed machine translation of a page that commits you to something, like terms or a refund policy, can be wrong in ways you will not notice.

Create the widget, copy its embed snippet, then get the loader script into the app. Prompting Lovable in chat is the shortest route and works on any plan. The one thing to watch is that a Lovable project is a React app, so an embed pasted in as raw HTML renders the container but never runs the script, which looks like a broken widget and is not. There is a full explanation of that in our article on widgets to embed on your Lovable site.

Let your analytics answer rather than your ambition. Look at which countries your visitors already come from and which languages their browsers request, then add the top one or two and see whether anything changes. Adding twelve languages on day one produces twelve versions to maintain and usually no more customers. The exception is when you already know exactly who you are selling to in another market, in which case start there and translate properly rather than automatically.