June 2026
The editor (mes-adresses) is the input side — the tool municipalities use to
create and maintain a Local Address Base (BAL/LAB). The platform's actual output is:
| Output | Description | Update freq. |
|---|---|---|
| Geocoding API | HTTP endpoint /search?q=address → coordinates + structured result.
The primary product consumed by downstream apps, GIS tools, emergency services. |
Real-time |
| National CSV download | ~25 M address rows (France). One position per address, open license. The canonical bulk dataset. | Daily |
| Vector tiles (MVT) | Address tile layer for embedding in any MapLibre/Mapbox map. | Real-time |
| WFS / WMS | OGC services for traditional GIS tooling. | Monthly |
A BAL created in the editor flows through the pipeline and eventually appears in geocoding
responses and in the national CSV. That's the visible result.
The public portal (adresse.data.gouv.fr) is a GUI over the geocoder and
download files specific to the French deployment — see the Portal section.
The full pipeline from address editing to geocodable output spans six components:
/search queries on :7878adresse.data.gouv.fr is out of scope.
It is built on the French government DSFR design system — porting it requires a full reskin, not just translation.
Downstream consumers (GIS tools, routing apps, emergency services) integrate the geocoder API directly.
Suggested demo replacement: a MapLibre GL page (1–2 days) querying the geocoder. No localization required.
| Component | Has UI? | i18n needed? | Rationale |
|---|---|---|---|
mes-adresses |
Yes — full editor | Yes — ~260 strings | The only user-facing app in the stack. next-intl wired; EN + ES catalogs available. |
mes-adresses-api |
No — REST API only | No | API error messages stay in technical English. Frontend does the display translation. |
api-depot |
No — REST API only | No | ~24 strings, technical. Keep in English. |
ban-plateforme |
No — aggregation engine | No | No user-facing surface. |
addok-docker |
No — geocoder API | No | Returns structured JSON. Language-neutral. |
adresse.data.gouv.fr |
Yes — public portal | Skipped | Out of scope. Would require i18n + full reskin. |
mes-adresses, ~260 strings.
Wire next-intl and extract all ~260 strings into messages/fr.json.
Adding a language later means creating a new JSON file — no code changes. Estimated effort: 16–24 h.
| Category | Strings | Notes |
|---|---|---|
| App-flow UI strings | ~260 | Labels, toasts, validation messages, status text — what users see in the editor |
components/help | ~150 lines | Long-form instructional prose — low priority, ship last |
| Legal / accessibility pages | ~100 lines | French gov institutional content — rewritten per country, not translated |
accent-tool.tsx | 43 | Not strings to translate — these ARE the accent characters (keyboard tool for street names) |
The correct methodology is to grep for lines containing French accented characters, exclude non-UI categories (help prose, institutional pages, the accent keyboard tool), extract only quoted string literals, and deduplicate. A broader regex pass over all string literals yields a misleading count by capturing English technical strings, API paths, and TypeScript constants.
Six position type values are stored as French strings in the database:
'entrée', 'bâtiment', 'délivrance postale', 'montée',
'formation spéciale', 'présentation'. This is what shows as "entrée"
on map pins. It cannot be fixed with next-intl alone — it requires a TypeORM migration
to language-neutral DB keys (entrance, building, …), then display-translation
via the i18n catalog.
Eight France-specific pieces need to be generalized. Priority order:
| # | What | Where | Abstraction | Effort |
|---|---|---|---|---|
| 1 | Administrative unit identifier INSEE commune code everywhere |
mes-adresses-apiapi-depotban-plateforme |
Replace commune: string with generic locality_id: string. Define LocalityService interface; FR COG = default impl. |
High |
| 2 | Bundled FR administrative database@etalab/decoupage-administratif compiled into API |
mes-adresses-api/libs/shared/src/utils/cog.utils.ts |
Abstract getLocality(id); FR COG becomes one pluggable data source. Modeled on existing yarn update-cog pipeline. |
High |
| 3 | Map tile sources Hardcoded FR govt URLs in 3 JSON style files |
mes-adresses/src/components/map/styles/*.jsonstyles/index.ts |
Convert static JSON to env-templated objects. Add NEXT_PUBLIC_MAP_TILES_URL, NEXT_PUBLIC_MAP_GLYPHS_URL, NEXT_PUBLIC_MAP_SPRITES_URL. |
Medium |
| 4 | Locality search APIgeo.api.gouv.fr for commune autocomplete |
mes-adresses/src/lib/geo-api/index.ts |
URL already env-driven (NEXT_PUBLIC_GEO_API_URL). Reimplement ApiGeoService.searchLocalities() + getLocality(). Two methods; rest of app unchanged. |
Low |
| 5 | i18n framework in editor ~260 hardcoded French strings |
mes-adresses/src/** |
Wire next-intl, extract all strings to messages/fr.json. Adding a language = new JSON file. |
High |
| 6 | Position type enum French strings stored in DB: 'entrée', 'bâtiment'… |
mes-adresses-api entity + DB column |
Store language-neutral keys in DB ('entrance', 'building'…); translate display values in the frontend. Requires one TypeORM migration. |
Low |
| 7 | FR identifier column widthscommune_deleguee varchar(5), code_voie varchar(4) |
mes-adresses-api/libs/shared/src/entities/ |
Generalize column lengths; rename to sub_locality_id, street_id. Migration required. |
Low |
| 8 | Authorization / habilitation ProConnect (French govt SSO) |
api-depot habilitation flow |
Make auth provider configurable. Phase 1: email-based pin only (already exists as fallback). ProConnect = optional plugin. | Medium |
Wire next-intl into mes-adresses and extract all ~260 French strings
into translation catalogs. Strings stay in French in fr.json; adding a language
means adding a new JSON file with no code changes.
next-intl — key/namespace strategy, pluralization, date/number formattingmessages/fr.jsonImplement the eight abstractions from the Pluggability slide. Priority order: locality identifier + COG abstraction (items 1–2) → map tile env vars (item 3) → geo search service (item 4) → position enum migration (item 6). Items 7–8 are lower priority and can follow.
LocalityService interface; FR COG = default implementationcommune field and related column widths across all 3 backend reposWire the submission and geocoding pipeline using the env vars and service interfaces established in WS2. French public services are kept where they don't write to the real BAN; everything that does is self-hosted locally.
geo.api.gouv.fr (commune search), FR government map tilesapi-depot, ban-plateforme (with MongoDB), addok-dockerVerify the full pipeline end-to-end with French data. Seed dataset: a sample commune + BAL with voies and numéros. Build the lightweight geocoder demo page. Key flows to test:
| Workstream | Effort |
|---|---|
| WS1 String extraction + DB enum | 16–24 h |
| WS2 Pluggability layer (8 abstractions) | 60–100 h |
| WS3 Pipeline wiring for demo | 16–28 h |
| WS4 Manual testing + demo page | 8–14 h |
| Total | ~100–166 h |