In March this year, a customer of ours who runs a mid-sized manufacturing group called me about something that had nothing to do with features. They had spent two years building an ERP on our platform. Purchase orders, quality inspection, warehouse management, the works. It worked. Their people knew it. Then they acquired a factory overseas, and the new general manager there asked, very politely, one question during the handover meeting: "Can the system speak English?"
I said yes. Of course I said yes. And then I spent the next two months learning exactly how much that "yes" was going to cost.
Internationalization sounds like a checkbox. Add a language switcher, translate some labels, done. Every platform marketing page lists "multi-language support" in the same sentence as "multi-tenant" and "responsive layout." It sits there, harmless, one bullet among many.
It is not a checkbox. It is an architectural confession. A second language does not test whether you can translate strings. It tests where language actually lives inside your platform — and in most low-code platforms, the honest answer is: everywhere, carelessly.
The first thing that breaks is the schema, not the UI
When people think of i18n, they think of interface text. Buttons, menus, placeholders. That part is genuinely easy. Any competent platform has a translation layer for its own chrome.
But a low-code platform does not just ship a UI. It ships a construction kit. The customer builds their own data models, their own forms, their own workflows, their own validation rules. So the question is not "can our menus speak English." The question is: when a customer renames a field, where does that name go?
If the field label is a single string on the field definition, you have a problem. That string is simultaneously the display label, the thing the search engine indexes, the thing reports print in headers, and the thing AI-generated descriptions reference. When the second language arrives, you discover that "label" was never one thing. It was four things wearing one coat.
The fix is not adding a second string. It is deciding that text visible to humans is a localized object — a small map from locale to string, with a fallback chain, from the very first day you design the metadata model. Retrofitting that after a thousand tenants have built apps is one of the least pleasant exercises in software engineering. I have done adjacent versions of it. I do not recommend it.
Dropdowns are where optimism goes to die
Here is the detail that humbled me. A form field of type "single select" has options. Each option has a display name. In the customer's original build, those option names were ordinary text: "Pending," "Approved," "Rejected" — except in Chinese, obviously.
Now add English. Where does "Approved" live? If options are strings, someone has to duplicate every option list per language, and now the data stored is the Chinese string, so filtering "status equals Approved" silently returns nothing in the English UI. If you change the option to store an ID instead, you have migrated every workflow condition, every report filter, every script that compares against the old literal.
We watched a variant of this happen in the customer's approval workflow. The workflow engine stored node names and branch conditions as text. The branch said: if department equals "采购部", route to procurement lead. In English UI, the department dropdown showed "Procurement." The condition never matched. Orders quietly fell into the default branch. Nothing errored. It just made wrong decisions, politely, for eleven days before anyone noticed.
That is the real danger of i18n failures in low-code platforms. They do not throw exceptions. They translate the surface and leave the logic monolingual, and the system keeps running with a small, invisible misunderstanding at its core.
The data itself refuses to be translated
So you localize the schema. Good. Now the harder truth: the data in the tables is whatever users typed. A product name entered as text by the Shanghai office is Chinese. The German salesperson opens the same record and sees Chinese. You can localize every label on the screen and the content is still in one language.
Some of this you solve with structure — translation tables for reference data like categories, units, currencies. Some of it you honestly cannot solve, and the platform's job is to say so: separate what is system text (translatable), what is master data (translatable with discipline), and what is user content (not translatable, and pretending otherwise creates a maintenance nightmare).
And then there is the layer nobody budgets for: formats. Dates, numbers, names. Does your date field store a timezone or not? Does "03/04" mean March 4th or April 3rd depending on who is looking? Is a customer name one string, or a family name and a given name — because the Japanese and Icelandic users will fight you on that. These sound like trivia until they are payroll amounts or delivery dates.
What a platform owes its builders
The uncomfortable part of this work was realizing that internationalization is not a feature you add to a low-code platform. It is a contract you make with everyone who builds on it.
The contract says: every piece of human-readable text you author — field labels, option names, workflow node names, validation messages, email templates, dashboard titles, automation notifications — is locale-aware from the moment you type it. You never see the machinery, but it is there. If we ship that contract late, every app built before it is silently in debt, and we cannot pay that debt for the customer. They have to pay it, record by record, option by option.
This is also where low-code platforms differ from frameworks. A web framework hands i18n to the developer, who can adopt it per project. A platform like ours owns the metadata model for every project ever built. We do not get to opt in per app. The architecture decision is platform-wide, permanent, and its cost lands on customers who trusted us.
There is a second-order effect I did not anticipate: workflows and automations. A scheduled notification that says "您的订单已审批" is generated by a workflow definition. The report header that prints the wrong quarter because it formats dates with a hardcoded pattern. The AI agent that answers in Chinese because its prompt template was written in Chinese. Every subsystem that generates human-readable output is a translation surface, and each one you forget becomes a support ticket from a very polite manager in another country.
The uncomfortable conclusion
I used to believe internationalization was a late-stage concern. Build the product first, prove the value, globalize later. That logic feels pragmatic. It is how almost every enterprise software company actually behaves.
But here is what the two months taught me: you cannot retrofit "where language lives." You can retrofit translations. You cannot retrofit the decision that a field label is a map instead of a string, that an option stores an ID, that a workflow condition never compares display text. Those are not translations. They are the shape of your metadata, and the shape was poured in concrete on day one.
The customer got their English interface. It works. It cost us far more than it would have cost as a design constraint nobody could feel at the time — because on day one, in one language, multi-language support looks like pure overhead with zero visible benefit.
That is the trap, and it generalizes. The architectural decisions that matter most are exactly the ones whose cost is invisible when you skip them and expensive when you discover them. A second language is just the most polite messenger. It does not argue. It waits until you have a customer abroad, and then it reads your metadata model out loud.
Top comments (0)