1
1 Comment

One codebase, 5 languages: the i18n decision tree (single vs multi-domain)

We run 14+ products at Inithouse. Two of them hit the same problem from opposite sides: how do you serve an app in five languages?

Tarotas, a tarot reflection app (78 cards, 20 spreads, 5 languages), sits on a single domain with locale routes: tarotas.com/cs, /en, /pl, /sk, /de.

Živá Fotka, an AI photo animator, runs on five separate domains: zivafotka.cz, zivafotka.sk, zywafotka.pl, alivephoto.online, lebendigfoto.de.

Same React codebase under both. Same Lovable stack. Same Supabase backend. The only difference is how we route languages to the outside world. Six months in, here's what that decision actually costs.

The decision tree we ended up with

We didn't have a framework when we started. We built one after watching both approaches play out. Three questions decide it:

1. Does the brand name translate?

Tarotas works everywhere. Tarot is tarot in Czech, English, Polish, German. One domain, no confusion. Živá Fotka means "living photo" in Czech. That name is the product in CZ/SK. But "zivafotka" means nothing to a Polish or German user. We needed zywafotka.pl (Polish spelling) and lebendigfoto.de (German) and alivephoto.online (English). The name itself forced multi-domain.

If your product name is language-neutral (SaaS names, made-up words, English-first brands): single domain. If the name carries meaning in a specific language, you probably need separate domains.

2. How much content differs per locale?

Tarotas has ~90% shared content. The card database, spread layouts, and UI are identical. Only the interpretation text and UI strings change. Serving that from one domain with i18n JSON files is clean. One deploy, one sitemap, one set of analytics.

Živá Fotka is different. Each locale has its own landing copy, its own social proof (Czech users reference Czech holidays, Polish users reference Polish cultural moments), and its own SEO keyword set. The CZ landing page and the DE landing page share maybe 40% of actual text. At that divergence level, separate domains felt right. Each locale gets its own content strategy without stepping on the others.

Rule of thumb we landed on: above ~70% content overlap, single domain wins. Below that, the maintenance cost of keeping one domain's locale routing clean exceeds the cost of running separate deploys.

3. Does ccTLD ranking matter in your market?

For Tarotas, organic search isn't the primary channel. People find tarot apps through recommendations, app stores, direct links. The .com works fine across all five markets.

For Živá Fotka, local organic search is everything. "oživení fotky" in Czech, "ożywienie zdjęcia" in Polish. These are localized queries where a .cz or .pl domain has a measurable ranking edge. We saw the .cz domain index target keywords within 8 days of launch. The .com English version (alivephoto.online, not even a .com) took noticeably longer to gain traction for equivalent English queries, partly because .online doesn't carry the same ccTLD trust signal.

What it actually costs to maintain

Single domain (Tarotas model):

  • One Lovable project, one deploy pipeline
  • i18n via JSON locale files. Adding a language means adding one JSON file and translating card interpretations
  • One GSC property, one GA4 property, one Clarity project
  • One sitemap with hreflang tags (this is the annoying part. Hreflang is easy to get wrong, and Google takes weeks to re-crawl after you fix it)
  • Total overhead per new language: maybe 2-3 hours of translation + 30 min of config

Multi-domain (Živá Fotka model):

  • One Lovable codebase, but five published instances
  • Five GSC properties, five GA4 properties, five Clarity projects
  • Five separate domain registrations and DNS configs
  • Five sitemaps (simpler individually, no hreflang headaches, each domain is its own canonical)
  • Drift risk: a bug fix in the CZ version needs to be deployed to all five. We've had cases where PL was running a day behind CZ because we forgot to publish one instance
  • Total overhead per new language: 4-6 hours (domain purchase, DNS, deploy config, analytics setup, initial content localization)

The drift problem is real. With Tarotas, a fix goes out once and every locale gets it. With Živá Fotka, we've shipped a feature to Czech users and realized three days later that Polish users were still on the old version. We built a deploy checklist for this, but it's manual overhead that compounds.

Cross-portfolio learning

Running both approaches in parallel taught us something we wouldn't have learned from either alone.

Tarotas showed us that hreflang implementation is deceptively tricky. We had Czech pages ranking for German queries for two weeks because of a hreflang misconfiguration. Google's documentation on this is thorough but the feedback loop (waiting for re-crawl) is painfully slow.

Živá Fotka showed us that ccTLD advantage is real but narrow. The .cz domain ranks well for Czech queries, but the content quality and page experience matter more than the TLD once you're past the initial indexing phase. If we'd known that upfront, we might have started with a single domain and only split off ccTLDs for the markets where we had proven traction.

What we'd do differently

Start single-domain. Always. Even if you think you'll need multi-domain later.

The migration path from single-domain to multi-domain is straightforward. You already have the i18n infrastructure, you just point new domains at locale-specific routes and eventually split them out. Going the other direction, consolidating five domains into one, is a redirect nightmare that risks losing whatever SEO equity you built.

We'd also skip hreflang for anything under three languages. The implementation cost and debugging time aren't worth it when you only have two locales. A simple language switcher with proper canonical tags does the job.

And the naming question? We'd think about it before writing the first line of code. "Tarotas" working globally was lucky. "Živá Fotka" being untranslatable was predictable. We just didn't think about it until we needed a Polish domain and realized we were committed to locale-specific branding.

The i18n decision isn't really a technical one. It's a branding decision that has technical consequences. Start there.

on June 30, 2026
  1. 1

    Really useful breakdown. The distinction between shared UI strings and market-specific content is especially interesting.

    Across the products you localized, what created more friction in practice: the technical i18n setup, or deciding whether the translated wording actually felt natural for each market?

    I’m particularly curious whether short UI strings were easy to reuse, while landing pages and user-facing copy needed more context and local judgment.