AI Regression Is a Software Problem
When an AI workflow suddenly behaves worse after weeks of success, the problem is rarely mood. It is usually missing ...
11 min read
26.08.2026, By Stephan Schwab
Internationalization is an early product decision, not a cleanup task after launch. Translation itself is not the expensive part; the cost comes from an application model that turns language into runtime architecture. Keep the web model: let browsers do browser work, servers deliver language-specific documents, and use web components only where reusable UI genuinely helps. Multilingual business software should stay boring.
The first mistake is usually managerial, not technical.
Teams treat i18n as if it were a scale problem for later, even when the market makes it obvious from the start. That works right up to the moment the product needs a second language and somebody discovers that text, routing, metadata, support flows, and content ownership were all designed as if English would remain the permanent default.
For CTOs, this is not primarily a frontend style argument. It is a delivery argument. If multilingual support is a normal business requirement, then the right question is not “which framework feels modern?” The right question is “which application model keeps this requirement boring enough to ship and maintain?”
Europe is the obvious example. The EU runs with 24 official languages, and the European Commission says its websites on europa.eu are generally available in all 24. In European business software, multilingual users are normal: people switch between local language, English, and sometimes a neighboring market’s language without treating that as remarkable. A German company may sell into Spain, hire in Poland, report to a Dutch parent, and run vendor calls in English. The product can be local, but the workflow rarely is. EU multilingualism policy, Commission language use.
The United States is different, but not as simple as people pretend. Census data released on June 3, 2025 says that 22% of people age 5 and older spoke a language other than English at home in the 2017-2021 period. Many US business apps still get away with English-first because their buyers and office users are usually fluent enough in English that language friction does not block the sale on day one. That is a market shortcut, not a technical truth. U.S. Census release.
Then there is the post-Soviet business space, where the picture bends again. Local state languages matter, but Russian still persists as a commercial lingua franca in much of the region. Research highlighted by the University of Colorado describes Russian as a “significant commercial lingua franca” in post-Soviet countries. Commercial lingua franca research summary.
The point is not sociolinguistics for its own sake.
The point is that many companies operate in markets where language support arrives early and stays. If that need is predictable, the architecture should treat it as normal instead of pretending it can be taped on after the product model has already hardened.
The sales pitch was seductive because it addressed a real frustration.
Page reloads felt clunky. Mobile apps felt smoother. JavaScript engines got faster. Frameworks promised a single application shell, instant transitions, reusable components, and a user experience that looked more like software and less like a pile of linked documents.
That part was emotionally persuasive, and sometimes genuinely useful.
For a while, many teams concluded that the browser’s document model was the old world and the SPA was the future. If the page could stay alive and the client could do the coordination, everything would feel faster, richer, and more modern.
Then normal business requirements showed up.
MDN’s own SPA glossary is less romantic than the conference circuit. It defines an SPA as a single document updated via JavaScript and notes the tradeoffs plainly: SEO issues, more effort to maintain state, implement navigation, and do meaningful performance monitoring. That is before legal, finance, or customer support asks for German, Spanish, and English to behave consistently across the same workflow. Even MDN says the tradeoff exists.
That is the first useful fact.
The second is nastier.
i18n is not hard in SPAs because developers are stupid. It is hard because the SPA moved concerns that the browser used to handle at the document level into application code. Language support lands directly on that decision.
Browsers already know how to do a great many things SPA culture spent a decade pretending were too primitive:
The History API has been widely available since July 2015. PWAs extend the same platform with installability, offline capability, and device integration where the browser supports them. That is not a toy platform.
So when someone says the SPA was necessary because “users expect app-like behavior,” the obvious reply is: yes, and the web platform learned that lesson years ago.
The browser grew up.
The frontend industry just kept billing like it had not.
The browser has been more capable than the framework habit admits. What many teams still call modern web development is often just a complicated way to avoid trusting the platform.
The result is predictable. Once a product needs multiple languages, the SPA has to coordinate route semantics, language detection, text loading, fallback behavior, metadata, and state survival in one continuously running client application. What used to be document delivery becomes runtime choreography.
Framework docs quietly admit this in different ways.
Angular gives you a full extraction and localized-build pipeline. React usually hands you an ecosystem stack with backends, language detectors, namespaces, and loading behavior. Vue adds a dedicated i18n layer with migration baggage of its own. Next.js helps with internationalized routing and then explicitly says that support is meant to complement external i18n libraries rather than replace them. The frameworks are not hiding the complexity. They are documenting it.
Angular deserves credit because it does not pretend i18n will just happen by sprinkling fairy dust over components.
Its official docs tell you to add @angular/localize, mark strings with i18n attributes or $localize, run ng extract-i18n, copy the source language file into per-language translation files, translate plurals and alternate expressions, and then use the localize build option to generate a full application variant for each locale. The docs also spell out the supported interchange formats: XLIFF, XLIFF 2, XMB, JSON, and ARB. Angular i18n overview, add package, translation files, merge localized variants.
That is not a criticism of Angular.
That is Angular being honest.
If your entire UI lives inside a long-running client application, then localization becomes a build pipeline, an extraction pipeline, a translation-file lifecycle, and a deployment problem. Angular did not invent that burden. Angular merely documented it clearly enough that nobody gets to pretend it is free.
The nicest thing you can say about Angular’s model is that it centralizes the pain.
The less nice thing is that the pain still exists.
And remember: Angular is the framework with actual built-in support. The others mostly prove the same point with different tooling choices. React’s common answer is react-i18next, with backend loading, browser language detection, fallback language handling, and loading behavior that can trigger Suspense while translations are still arriving. Official instance setup, official hook behavior. Vue uses a dedicated vue-i18n layer and is still carrying migration pressure from legacy API mode toward the Composition API. Getting started with Vue I18n, Composition API docs, breaking changes in v11. Next.js improves routing, but its own Pages Router docs explicitly say the i18n routing support is meant to complement existing i18n libraries rather than replace them. Pages Router i18n docs, App Router i18n docs.
The trap is thinking that i18n means “put strings in files.”
That was never the full story, and SPA architecture makes the surrounding story larger:
That last point is where the frontend culture gets a deserved slap.
If your design system cannot tolerate German becoming longer than English, the issue is not translation quality. The issue is that the system was built around a screenshot, not a language.
Still, the broader point stands: a document-centric app can let the server return the correct language as a complete document. An SPA tends to turn language into one more reactive subsystem that can load late, fail oddly, or require suspenseful ceremony before the user even sees the page correctly.
That is not progress.
That is framework rent.
The alternative is not to swing back to a tangle of copy-pasted server templates and no reusable UI.
The calmer option is this:
That model is easier to explain upward because it aligns responsibility with the business need. A language-specific URL returns a language-specific document. A reusable UI element remains reusable without forcing the entire application into SPA behavior. You still get componentization. You still get modern browser capabilities. You just stop paying the full architectural tax of the SPA when the product does not need it.
For a CTO, this matters because it reduces moving parts in exactly the place that tends to become political. Multilingual support should be a content and workflow concern with some technical discipline around it. It should not become a fragile negotiation between routing strategy, translation bundles, runtime state, and whichever frontend libraries are fashionable this year.
MDN’s PWA docs describe the capability envelope plainly: a PWA can share one codebase across platforms and, where the browser and device support it, be installed, work offline or in the background, and integrate with the device. The current web.dev checklist says a good PWA works in any browser, adapts to any screen size, provides offline behavior, and is installable. MDN PWA overview, web.dev PWA checklist.
That is most of what business stakeholders usually mean when they say “we need app behavior.”
They rarely mean:
They mean:
Those are web requirements.
Not SPA requirements.
The industry spent years confusing the two because the SPA looked like modernity and the browser looked like yesterday’s plumbing.
Now the browser does most of the respectable work, and teams are still dragging framework debt around like an heirloom.
Web components fit neatly here because they preserve what is useful about component thinking without demanding the full SPA bargain. A date picker, pricing card, workflow status panel, or localized account widget can be a component. The whole business application does not need to become one giant client-side runtime just because some parts are interactive.
This is the part where the usual objection deserves a fair answer.
Some applications really do want a heavy client runtime:
Fine. Build the app you actually need.
But be honest about what you bought.
You bought a larger frontend surface. You bought state orchestration. You bought routing logic. You bought i18n as runtime architecture. You bought more chances for loading mismatches, more library coordination, more migrations, and more work to keep URLs, metadata, accessibility, and translations aligned.
That can still be the right trade.
It is just not the default right trade for a multilingual business webapp with forms, lists, detail screens, approvals, invoices, and dashboards.
Those systems are usually documents with workflow, not miniature operating systems.
Treat them that way and the multilingual story gets saner immediately.
SPAs were often sold as the inevitable answer to “modern webapps.”
That claim aged badly.
The web platform got stronger. PWA capabilities matured. Browsers standardized more of the useful behavior. The framework world has moved back toward server rendering, route awareness, and selective client execution because the all-client dream made too many ordinary problems worse.
i18n is one of the clearest proofs.
The multilingual bill reveals whether the architecture serves the product or whether the product is quietly serving the architecture.
If adding German and Spanish turns into weeks of route negotiation, bundle choreography, fallback debugging, and framework-library diplomacy, the problem is not that translation is inherently impossible.
The problem is that the application model moved too much responsibility into the client.
Most business webapps never needed that bargain.
They needed solid HTML, sane URLs, server-rendered language boundaries, progressive enhancement where it helps, and PWA features where they add real value.
That stack is less fashionable.
Good.
Fashion is how teams end up explaining Suspense to a button label.
Tell me what is happening. I listen, ask a few practical questions, and reflect back what I see: where the risk may sit, what may be blocking delivery, and what looks worth checking next. No pitch, no obligation. Confidential and direct.
Talk it through. Practical reflection, no pitch.
Start a ConversationVisibility and hands-on delivery
Navigator gives your leadership clear insight into patterns, blockers, and capacity. Our Embedded Delivery Partner writes production code with your team and gets delivery moving.