For discussion
Draft for review · PADI-536
One place decides a visitor's region and language, and every PADI site reads that answer instead of working it out for itself. Here is what we propose, what we need you to decide, and what we need to know.
Every PADI site currently decides on its own what language and region to show. This replaces that with one answer, worked out once.
Today the store sets currency its own way, Chinese, Japanese, Korean and Taiwanese visitors get sent to separate sites, and padi.com has its own selector. Those answers drift further apart over time because nothing holds them together.
Instead, a small piece of code runs at Cloudflare — which already sits in front of most PADI sites — and works out two things from the visitor's country: which region's content they should see, and which language to show it in. It attaches that answer to the request, and each site simply reads it.
decide() is pure — it reads signals and config and returns an answer; it calls nothing. Note what does not happen: classified traffic skips the decision entirely, a served page is answered from the edge cache without reaching the origin, and a redirect never enters the cache. The origin only ever receives an answer, never a question.| Principle | What it means in practice |
|---|---|
| Detection is never saved | A region we work out from someone's location is never saved. We work it out again on every request. What we do remember is a region someone actually chose — a member's account setting, or a pick from the menu. If the address ends up naming the country, a chosen region becomes part of the URL rather than something we store — which would remove even that. |
| Country-level, not just EMEA / Americas / AP | We resolve the visitor's actual country, even though only five content sets sit behind them. |
| Language is a choice that wins | A region suggests a language; the visitor's own choice beats it and travels with them. |
Their request arrives like anyone else's, with their session alongside it.
| What happens | |
|---|---|
| At the homepage | Their stored language wins, above their browser and their country. |
| At any other address | The address still decides. padi.com/fr/fr/courses is France in French for everyone. |
| Which region | Their stored region beats where they are, read once at sign-in and carried the same way a manual pick is. |
| The page itself | The same page everyone gets at that address. Personalised parts are layered on in the browser, on top of it. |
Someone in France opens a link to padi.com/jp/ja/about. They land on that page and see it — Japan's content, in Japanese, because the address decides. A small bar appears at the top: "You're viewing Japan. Switch to France?" It names their country, not the region behind it — that is our plumbing, not theirs. One click takes them to padi.com/fr/fr/about — the same page for their own country; ignore it and they carry on reading. Dismiss it and we do not ask again that visit. Anything else, they use the region selector. The same bar covers a signed-in member whose account region differs from the address.
This cannot be changed quietly once the site is live, because it is what search engines index and what people share. It is still open, and it needs product, SEO and engineering to land in one place.
What should a page's web address look like? The vanity domain redirecting to the SEO URL is agreed — padi.ar → padi.com/ar. What that second address looks like is not. Three shapes are in play.
Country only
padi.com/ar/…
padi.com/ar is ambiguous: ar is Argentina, and also the language code for Arabic.Country, then language
padi.com/ar/es/…
/ca/fr, /de/de, /jp/ja.Language and country together
padi.com/es-ar/…
Every shape except Option A removes the padi.com/ar ambiguity, which is the part we would not want to discover after launch. Between B and C we have no strong preference — B matches what the sheet already says, C is the wider convention.
Worked examples elsewhere in this document use Option B so they read consistently. That is for legibility, not a decision.
Eight decisions about countries, languages, regions and URLs. Most are product calls; Q7 also wants the SEO team and Q8 is about who owns the data. Each one blocks a specific line of what we build. Answers go in the Localisation Q&A tab of the country sheet, keyed to the IDs.
When a country’s default language is not one PADI supports, what language should we serve?
This affects 50 of the 231 countries. Armenia is served UK content with Armenian as its default; Bulgaria is UK content with Bulgarian; Bhutan is Australia content with Dzongkha. None of those three exist in the CMS.
What is the expected behaviour for visitors from a blocked or restricted country?
Five countries are marked Blocked and carry no content region: Cuba, Iran, North Korea, Sudan and Syria. We need to know what those visitors should be shown — a message, a redirect, or something else.
Ukraine is a different case, marked “Restrictions for Crimea” — we need the expected behaviour for visitors from Crimea, and whether the rest of Ukraine is unaffected.
Hong Kong and Taiwan have no RHQ and no content region — should both be China, as Macao is?
They are the only two non-blocked countries missing both. Macao, grouped with them historically, is RHQ China and serves China content.
What is the expected behaviour for visitors from the 73 countries where “Supported today” is blank?
73 of the 231 rows have this column empty — Bhutan, for example.
Can you confirm Canada is no longer its own content region?
In the 10 September sheet Canada’s content region is United States, and no country lists Canada — which takes the model from six content regions to five: UK, United States, Australia, China and Japan. We read that as intentional and would just like it confirmed.
When someone picks a region from the menu and we have no stored preference or device signal, what language should they get?
The sheet has a default language per country and nothing per region. If the answer is the region’s own default, we need one value per content region and none exist today. Keeping the language they were already reading needs nothing added, which is what we would propose.
Which URL structure should we build to?
Three shapes are in play — padi.com/ar, padi.com/ar/es and padi.com/es-ar, set out in section 02. The sheet itself is not consistent: column D shows the first, column F the second, and the UK row shows padi.com/gb with no language at all. We also need to know whether padi.com/{country} is ever served on its own, or always redirects on.
This is the one that blocks the most: redirects, caching and every address search engines index all follow from it, and it is the hardest to change afterwards.
Can the country mapping sheet move into the reference API?
api.padi.com/r/references/countries/ already publishes 226 countries, but only names and ISO codes — none of the fields this service needs. If those fields were added to the endpoint, we would check it weekly and ship any change the way we ship code. If that is not realistic before November we will work from the sheet — but then we need to know who maintains it and how we hear about a change.
In stages, and nothing changes for a visitor until late.
First the contract between Cloudflare, the sites and their content APIs, so the teams can work in parallel. Then it runs at Cloudflare in silent mode — working out the answer and recording it, changing nothing for anyone. That is the cheapest place to find a wrong mapping. The sites and their content APIs start using the answer next. Redirects come last, one region at a time, with a go or no-go each time.
Cloudflare bills per request, not per page view — which is the only thing that makes this worth a section.
A page load is one request for the page plus its scripts, fonts and images — around 21 in total. If the service sits in front of all of them it runs 21 times per page view. Scoped to the page itself, it runs once.
Scoping is a simple Cloudflare configuration, and set correctly it is the whole difference:
| Page views / month | Scoped to pages | In front of everything |
|---|---|---|
| 1 million | $5 | $8 |
| 5 million | $5 | $35 |
| 10 million | $5 | $69 |
| 25 million | $10 | $174 |
PADI runs on Acquia Edge, which is managed Cloudflare. These are Cloudflare’s public rates, so if this usage is already covered by that contract they may not apply at all. Worth confirming before anyone plans around the figures.
This document is deliberately short. The full architecture — the request flow step by step, the redirect rules, how each PADI property consumes the answer, and the reasoning behind every recommendation — is kept separately so it does not crowd out the discussion.