Highlights
foura.ai now ships in six languages. The site, the Dashboard chrome, and the nine marketing pages were extracted, translated, and rewired to serve the right locale based on the URL. Open the sitemap in a browser and it renders as a styled table instead of raw XML.
What's New
The site speaks six languages
English, Bulgarian, German, Polish, Vietnamese, and Chinese. URL-prefix routing means each locale lives at its own path: /de/, /pl/, /zh/, and so on. The bare path serves English, and /en/ redirects to it so there's only one canonical URL per English page. A globe in the top nav lets you switch, and your choice persists across pages.
Server-side rendering does the heavy lifting for SEO. Every page now ships with a correct lang attribute, a full hreflang set, locale-specific Open Graph metadata, and a localized <title> and <meta description>. The sitemap exposes every URL across every locale. Search engines that prefer one locale over another (Baidu wants Chinese, the Polish edition of a search engine wants Polish) now get the right page on the first crawl.
ICU plurals work the way you'd expect. "1 API key" stays singular, "2 API keys" goes plural, and the rule changes per language. Polish has three plural forms, English has two, Chinese has one. The runtime resolver uses Intl.PluralRules, a built-in browser API, so nothing extra shipped to your bundle.
And if you read in English, nothing visibly changes. Your URLs stay where they were.
Playground UI is localized
Roughly 80 strings in the Playground tool (labels, hints, placeholders, tooltips) now follow the locale you've selected. Technical content stays English on purpose: HTTP method names, code samples, JSON keys, header names, status codes, and the values you'd paste into a request all read the same in every locale. The UI around them speaks your language; the wire stays English.
That separation matters. Anyone debugging a request across a team that doesn't share a first language can still copy the request body and match it against the docs without translation drift.
Sitemap renders as a table
Drop https://foura.ai/sitemap.xml into a browser tab and you'll see a styled table in FourA's dark theme instead of raw XML. We added an XSLT stylesheet that handles both individual sitemaps and the sitemap index.
The reason we needed one: browsers stopped rendering localized sitemaps as their built-in styled tree once <xhtml:link> alternate-locale entries appear. The choice was either ship a sitemap without alternates (and lose the SEO signal that ties locales together) or render our own styling. So we picked the second. Crawlers ignore the stylesheet and parse the XML as before, so nothing changes for them.
A sitemap is a real page on a real site. It should look like one.
Under the Hood
Translations come from an automated pipeline. We only commit the English source strings; on merge to main, the pipeline generates every other locale and commits the result. A copy edit lands in one place and propagates across six languages.
One bug fix worth calling out. The first localized deploy briefly shipped raw translation placeholders to production (you'd see home.h1a where the headline should be) because the build stage was missing the locales directory. We pinned the fix and made the build read the locales directory before producing the bundle, so this can't recur.
A site that ships in six languages is, structurally, six different sites. Search engines, screen readers, and a customer in Warsaw who Googles in Polish all benefit when the right locale arrives at the right URL with the right metadata. The wire stays the same; the surface meets each reader where they are.