i18n
publié le , mis à jourLong title : i18n and t9n : internationalised and english / other languages / version
There won't be a i18n version of Cartes in the medium term. There are a number of reasons.
First, the complexity it inflicts on the project, while dev resources are super-constrained. There are many talented devs in France and other French-speaking countries, that we for now haven't been able to mobilise.
i18n without a team (that can be benevolent) doesn't work : at work on a paid state project, we i18ned a project for nothing : without local communication in each country, it didn't take off. Three months of translation, a code base 2x as complex (yes, having to change a UI that is now in a language you don't master / with translation keys everywhere / with CI that breaks when you forgot to translate, with translation taking 50 % of PRs), for... still 99% French-speaking users.
I also like the idea of devoting 100% of the initial dev time to the French version in the early phases of the project. It's a rare thing. The people around me are 99% French-speaking, and they motivate me. In France, apart from well funded projects, translations in French are often bad. Look at this platform where we're developing : the github team is for political reasons not introducing translation, despite their wealth. This needs to be counterbalanced.
Also keep in mind that It's possible that in 6 months' time, the use of Cartes won't be wide, that the assumptions about the ingredients for success weren't the right ones. I prefer to test a roll-out in France and expand only if there is initial success. As I write these lines, 8 months after the start, we have no more than 20 000 users per month. It's not enough to think international :rocket:.
Of course, if someone is willing to devote 3 months at 2 days a week, plus a maintenance effort over time of multiple days per month (a rough estimate), we'll be happy to discuss translation.
Of course, something that doesn't work in France, for various reasons, could work abroad if e.g. backed by an organisation that has the will, the money and / or the firepower to promote a translated version of Cartes.
We'll then have to discuss with limited time about the state of the art frameworks for translation, that should not dramatically impair dev time. We don't want yet to slow down.
Last but not least, on top of t9n, i18n is hard. In France, we haven't yet been able to correctly display the local language translation of places, only the breton language is. We haven't yet been able to integrate the transit data of all of the french hexagone. Etc.
For example, the transitous project, quite similar to laem/gtfs+laem/motis, went all-in on international coverage, instead of starting small and being sure that transit works in all of e.g. France before trying germany. They've got world coverage, but last time I tried my regional capital city of Rennes didn't work. Well maybe they just undesrestimated France's digial illiteracy ^^ : lots of GTFS data in France have to be retreated to work. Could be way simpler in Switzerland or Germany (and probably way more complex in other countries).
laem
Damn, we should really expose most issues on the website. It's unfair that github.com gets this content's search karma, and gets drown in billions of similar content :/
GhostThanks for opening the issue, totally understand not wanting to dedicate resources to it, especially when the effort to get it into a state that's ready for taking in translations would be that big. I hope one day that'll change! ❤️
laem
Very interesting project https://github.com/tolgee/tolgee-platform In situ translation is a very promising feature + a JS api.
laem
With @colinmaudry we've tested Tolgee quickly. It's interesting but we have to look the possibility of using Tolgee without switching to an HTML that only contains ids instead of real human text. I want the HTML code to still work without the t9n tool.
E.g. this code block obfuscate the real intent of this component : we're missing the essentiel part in the HTML, the innerText of the h1 tag.
<header><h1 key="osmViewer.title"/></header>The React introductory video shows what a component looks like : https://www.youtube.com/watch?v=-oBuDsKoJWU
GhostHow it works with inline tags in React (from Tolgee docs):
const Component = () => { return ( <div> <T keyName="translation_key" params={{ i: <i /> }} defaultValue="This is <i>formatted</i>" /> </div> ); };
GhostFor reference, how Transifex does it in next.js. The setup looks tedious. There is also the possibly to hook Transifex with i18next extension.
laem
Lingui seems interesting, using either explicit or generated ids https://lingui.dev/guides/explicit-vs-generated-ids
GhostI've read the blog article "Cartes, a free european alternative to Google Maps" and I have to be honest, internationalization is also not needed imho. There are other initiatives for a global GMaps Online alternatives like osmapp.org or OSM NG.
FOSS projects unfortunately often suffer from insufficient coordination. If Cartes would go international it would compete with other FOSS initiatives which would be a waste of resources.
laem
There are other initiatives for a global GMaps Online alternatives like osmapp.org or OSM NG.
OSM NG is not an end-user interface project, but a rewrite of OSM-the-database and collaboration infrastructure. We'll use it if it makes it to production.
Osmapp is a direct competitor, but we're using the same technologies, and sharing code is easy and already done multiple times. But its scope is not as large as we ambition here, for instance public transit.
We will happily let other projects join our initiative, or vice-versa, or more pragmatically share bricks of code, once we've gone international. Osmapp, Organic, NG are all aware of our initiative but legitimately don't bother spending time on the matter as long as we're staying French-only.
FOSS projects unfortunately often suffer from insufficient coordination. If Cartes would go international it would compete with other FOSS initiatives which would be a waste of resources.
In the long term, we believe the error would be the other way : not letting German, Spanish people us what we're working instead of letting them recode everything.
laem
We've published a new article in English too https://cartes.app/blog/digital-relocation. Our blog now supports writing fr and en.
laem
Things to do to have an internationalised version of cartes.app.
Needed
- translate the interface in english as per the principles and using the tools listed above
I'd say ⌚️5 days of work for a first version, and ⌚️5 days more to communicate to abroad communities and get the first native translation corrections and make the contribution process fluid. It would of course use a LLM to produce the first exhaustive translation to be iterated on.
- make sure the international tiles that we use (built by Panoramax) out of the scope of France render correctly despite our style customisation for our tile customisations. E.g. "maxspeed->road color" can be displayed on our custom tiles.
⌚️1 day
- handle proper translation of Wikipedia extracts, remove French specific things like "gare SNCF"
⌚️0.5 day
Good to have
- use Transitous as a Motis server backup for the rest of the world. Our server covers France with some things on top of Motis (e.g. maps of transit lines) but a degraded functionnality would still be largely worthwile. We'd have to switch ours to Motis v2 as a prerequirement. I believe the Transitous community would be very happy to see this integrated.
⌚️1 day (most work going into v2 transition)
- compute tiles of Europe and then the world in our enhanced OMT tile format. It's important to give a harmonized and enhance map experience worlwide
This is quite a challenge : computing our France/part of Europe tiles is already high on our server's resources. We need more RAM to do this with Tilemaker. Ideally, we'd spawn a dedicated and strong instance on Scaleway's network just for this, download it and shut the instance.
⌚️3 days for Europe, should scale to the world quite easily then.
- translate the interface to the other european languages
Once the framework is in place, LLM translations should be able to provide usable translations to be augmented by native corrections in the medium run.
⌚️3 days (work + some communication).
Total : 18.5 days.
GhostFYI I considered adding cartes.app as an unlockable link in StreetComplete. It ticks all the boxes: International coverage, FOSS software, based on OSM, great integration of neighbouring projects such as Panoramax, indoor=, wikimedia and many features one would expect from a end user map app. Ultimately, I deferred it, for its missing localization, i.e. at least to English.
(StreetComplete is the most popular on-the-go editor for OSM with a little bit of gamification. Users that contribute regularly will get achievements that unlock a collection of useful or interesting links that have some relation to the OSM ecosystem.)
laem
Hi @westnordost thanks for the messsage ! StreetComplete is awesome :) i18n and especially the english version is coming soon, I'll let you know.
laem
Interesting article https://vitonsky.net/blog/2025/05/17/language-detection
laem
Super intéressant. À tester.
zyphlar
We're considering an improvement to CoMaps.at (the geo link sharing / web companion to CoMaps.app) that may involve self hosting or linking to cartes.app or osmapp.org however i18n would be required.
CoMaps has a wide reach of users from other countries contributing to our Codeberg Translate project, and would be happy to share that work, but obviously are just starting out and can't be the leaders of such an initiative just yet.
Still, the point is that opening the i18n door could have a massively positive effect on the project.
laem
Thanks ! That's an important note. If you want to do it now, go for osmapp.org, I think it's internationalised in 13 languages. Their project is cool, we're following the same path and sharing the same techs.
Cartes's i18n could be available this fall. We have lots of things to fix first to serve French users properly, also including some server scaling improvements without which the website could crash with a 10x in uers :)
gedankenstuecke
I just wanted to see if there's been any progress on this, as it's been a while since the last update 🙂
laem
Hi, no ! The only progress, in parallel, is that we now create our own planet tiles automatically every week :) But on the translation side, no progress. It's on my list for the first months of 2026.
laem
Lingo ne marche pas, car on importe des yaml par exemple. C'est nul, tout projet importe du YAML ou mdx ou autre. Ça semble pas les inquiéter, j'y crois plus, donc.
Par contre j'ai trouvé ça : https://intlayer.org/blog/compiler-vs-declarative-i18n. Ça parle de Wuchale qui a l'air super, mais pas fait pour Next, seulement React.
À creuser.
Je suis tenté de tester https://generaltranslation.com/en-US/docs/next/api/components/t ou Lingui.
laem
N'oublions pas que l'interface en elle-même, est réduite en chaines de caractères, beaucoup de choses sont dans les tags osm externalisés, dans categories.yaml, dans les tuiles.
n4n5
Qu'elle est l'état du ticket ?
On peut juste utiliser https://github.com/aralroca/next-translate non ?
Ou
- https://next-intl.dev/
- https://github.com/QuiiBz/next-international
- https://github.com/i18nexus/next-i18n-router
https://nextjs.org/docs/app/guides/internationalization
PoC avec
next-international: https://codeberg.org/cartes/web/src/branch/poc-next-internationallaem
J'essaie de trouver la meilleur bibliothèque pour faire ça. C'est sûrement pas next-international, pas maintenu depuis 2 ans 😅
La traduction d'un site rend en général le site très désagréable à faire évoluer. Il faut qu'on fasse ça très soigneusement.
laem
Comme dit peut-être pas assez explicitement plus haut, l'idée c'est de minimiser la nécessité d'annoter le code pour le traduire. On est en 2026, on devrait pouvoir faire mieux que d'encapsuler tous les textes du JSX par des <Trans>. Mais pour l'instant j'ai pas trouvé mon bonheur, j'ai posé des questions à Lingo et Wuchale, à voir les retours.
Sinon tant pis, comme je le dis plus haut, on ira vers Lingo ou GeneralTranslation.
Dans tous les cas, c'est un de mes gros chantiers pour fevrier :)
aymericzip
Bonjour,
Je suis le créateur de Intlayer ( un Nantais ). Je me permet d'intervenir ici car les problématiques auxquels vous faites face sont exactement celles que je tente d'adresser à travers Intlayer.
Je serais intéressé par le fait de proposer l'i18n de votre app. Ca me permettrait de tester en situation reel notre suite d'outil, et aussi de mieux comprendre les subtilités liées a votre besoin.
Si intéressé, voila mon linkedin
n4n5
@aymericzip wrote in https://codeberg.org/cartes/web/issues/574#issuecomment-10848035:
Je suis le créateur de Intlayer ( un Nantais ). Je me permet d'intervenir ici car les problématiques auxquels vous faites face sont exactement celles que je tente d'adresser à travers Intlayer.
Hello, petite question, c'est quoi la différence avec, par exemple, next-international https://codeberg.org/cartes/web/commit/474dee1f571d02d06e26d9cf56c404dd89df94ae ?
Globalement dans les deux cas j'ai l'impression qu'il y a une fonction qui fait la traduction non ?
aymericzip
Oui en effet les deux solutions proposent une fonction permettant d'accéder au contenu, tout comme le fait i18next, next-intl etc.
La principale difference est liée a l'architecture. Centraliser le contenu dans un dossier a la racine du projet, ou dispatcher le contenu dans l'app. Intlayer permet les deux, là ou i18next, next-intl ou next-international offrent une approche centralisée. Centraliser rend plus simple l'integration de TMS, et l'ajout de nouvelles langues apres coup, là ou dispatcher les fichiers de contenu facilite le travail des devs, l'évolutivité du code, et limite les conflicts entre dev.
Un second point est une limitation technique correspondant a la manière dont on charge le contenu dans l'application. Le risque c'est de faire charger le contenu dans toutes les langues, et de toutes les pages pour une seule page consultée.
techno i18next next-intl next-international intlayer optimize loading par page via namespace via namespace pas possible via post-processing optimize loading par locale dyn loading dyn loading dyn loading dyn loading Note: Pour une SPA, il n'y a pas de difference, mais pour des applications ayant des dizaines de pages, intlayer simplifie le management du contenu.
Pour les autre solution se basant sur une approche par compiler comme lingui, general translation, lingodev: On gagne du temps et automatise le process, mais gerer la plurialisation, l'insertion de variable dans une string est rendu plus compliqué. Les optimisations du contenu loadé par solutions sont aussi leur point noir, et certaines de ces solutions vous vendor lock. Note: Intlayer propose aussi un compiler insérant la fonction de traduction dynamiquement.
Ensuite les differences sont lié au tooling, CLI pour tester les traduction manquante, integration CI / CD, formatter des listes, dates, currencies etc, ou encore a la DX (clée / contenu type-safe), extension vscode etc
n4n5
Okay merci de l'explication plus détaillé
On verra ce que @laem va choisir, il me semble qu'il a commencé cette tâche en Février
laem
Merci pour ton aide @aymericzip ! J'étais en effet tombé sur Intlayer, mais je t'avoue que l'approche consistant à créer un fichier compagnon de chaque composant dans lequel on met en gros une map clef -> contenu pour chaque tag à traduire du composant, ne me parle pas. J'ai justement envie d'éviter de devoir créer des nouveaux fichiers ou des structures de données à côté de chaque composant, et devoir ainsi inventer des clefs de contenu : title, content, listAfter, sectionheadersubtitle, etc.
J'ai justement pour objectif d'avoir un JSX qui garde le contenu en français, avec une gestion de la traduction ailleurs avec création d'id seulement quand il y a désambiguation nécessaire. J'aurais bien aimé me passer de composants <T, mais ça me semble compliqué vu l'état des compilateurs dispo, tant pis.
aymericzip
Hey @laem
Quelques précision:
- Intlayer supporte aussi la gestion d'un seul gros json, d'un json par page, ou section
- pour la création des clées, intlayer propose aussi un extracteur simplifiant le process
Et oui je saisi la contrainte de la fonction <T> ou t`` comme le propose general translation ou lingui.
Je viens de push une PR pour demo du compiler d'intlayer. Je pense que ca peut coller avec votre besoin https://codeberg.org/cartes/web/pulls/1690
Note: La contrepartie du compiler c'est de ralentir le dev / build, car chaque component doit être processé
Peu importe la solution choisie, je serais content d'obtenir votre retour.
laem
Lingui sort en v6 bientôt, mon programme pour les prochains jours est d'étudier leurs guides.
https://js-lingui-git-next-crowdin.vercel.app/guides/message-extraction
laem
The first elements of an international version of cartes.app are online. Basic support for English, German, Breton are there :)
laem
Cartes.app is available in English ! Quite a stretch from the initial "There won't be a i18n version of Cartes in the medium term" written in the corresponding issue !
We obviously could not afford to have a perfectly translated version as a first release. The initial objective was to make the app usable as an English-speaker : map names obviously, basic interactions, place pages (OpenStreetMap tag translation), category translations (coffee, bakery, etc.) and finally, some blog pages.
We also chose to provide other languages instead of perfecting the English version : providing a local european language, Breton, was important. Contributions followed : we now have drafts for 7 languages in just a few weeks ! The italian, german versions were auto-translated with Mistral and then contributors came to make them sound more native.
We've used widely used libraries : LinguiJS, based on simple .po Gettext files. We chose a localisation design that avoid /[lang] prefixes in the URL. It's quite a success, but the subject of SEO needs to be reviewed after the initial implementation to make sure that content will be indexed properly by search engines.
See this issue for translation completeness.
Of course now we need to communicated about these new translations. We've used Bluesky as a first step, but communication is not part of the NLNet grant, and getting a product to be known is a long-lasting task.