The Problem
Pantone operates 10 multilingual sites across 4 regions (North America, United Kingdom, Europe, Hong Kong) and 7 locales (en-US, en-GB, de-DE, fr-FR, es-ES, it-IT, zh-HK). Every locale is available in every region — a region/locale switcher allows any combination — producing 28 valid URL variants for every page on the site.
The existing platform had none of the SEO infrastructure needed for this scale. No hreflang tags — Google had no idea which version of a page to show to which audience. No canonical URLs — duplicate content across regions was diluting page authority. No dynamic sitemaps — Google Search Console had no structured feed of the site's URL inventory. BigCommerce's built-in SEO tools don't work in headless mode, so everything had to be built from scratch in the Next.js layer.
The result was predictable: wrong pages ranking in wrong markets, duplicate content penalties, and no visibility into how Google was crawling 28 versions of every page.
What I Built
site-config.ts — Single Source of Truth
Everything starts from one configuration file. It defines all 4 regions, all 7 locales, and programmatically generates all 28 combinations. It also defines the canonical region per locale (de-DE → EU, en-GB → UK, zh-HK → HK, etc.) and the x-default fallback (NA/en-US).
This one file drives the sitemap generator, the hreflang head component, the middleware routing, the language switcher UI, and locale validation. Adding a new region or locale means adding one entry to the config — every downstream system updates automatically.
HreflangHead.tsx — 29 Tags Per Page
A React server component injected into the document head on every page. For any given URL, it renders:
28 alternate tags — one link tag for every region-locale combination, telling Google exactly where each version lives.
1 x-default tag — pointing to NA/en-US as the fallback for users whose browser locale doesn't match any of the 28 combinations.
1 canonical tag — pointing to the "home" region for the current locale. If a user visits /na/de-de/products/widget, the canonical points to /eu/de-de/products/widget because EU is the canonical region for German content.

The bidirectionality requirement was critical — every hreflang annotation must be reciprocal. If page A lists page B as an alternate, page B must list page A. With 28 combinations, that's 29 link tags (28 alternates + x-default) on every page, all of which must be consistent. A single broken link in the chain can invalidate the entire set for Google.
Dynamic Sitemaps — Per-Locale, Per-Content-Type
A sitemap index that generates child sitemaps organized by locale and content type. Each locale gets its own set of sitemaps covering products, categories, articles, pages, and Color Finder results:
/sitemaps/en-us/products.xml
/sitemaps/en-us/categories.xml
/sitemaps/en-us/articles.xml
/sitemaps/en-us/pages-ms.xml
/sitemaps/en-us/pages-svr.xml
/sitemaps/en-us/color-finder-1.xml
/sitemaps/en-us/color-finder-2.xml
...
/sitemaps/en-gb/products.xml
/sitemaps/en-gb/categories.xml
...
This structure repeats for every locale, producing a comprehensive sitemap index that gives Google Search Console granular visibility into each market's URL inventory by content type.

Each URL entry inside a child sitemap includes xhtml:link alternates pointing to all 28 versions of that page — mirroring exactly what HreflangHead renders in the HTML.
Canonical Strategy
Each locale has a canonical "home" region:
- en-US → NA (canonical)
- en-GB → UK (canonical)
- de-DE → EU (canonical)
- fr-FR → EU (canonical)
- es-ES → EU (canonical)
- it-IT → EU (canonical)
- zh-HK → HK (canonical)
Non-canonical pages carry a canonical tag pointing to the primary version. Google surfaces the canonical in search results; non-canonical URLs still work for users who select them via the region switcher.
Technical Complexity
Sitemap-head consistency. The hreflang alternates in the sitemap XML and the HTML head must be identical. Any mismatch between what the sitemap declares and what the page's head renders confuses Google and can result in wrong pages appearing in search results. Both systems read from the same SITE_CONFIG array, guaranteeing consistency.
Content-type segmentation. The sitemaps are split not just by locale but by content type — products, categories, articles, Makeswift pages, server-rendered pages, and Color Finder results. Color Finder alone generates enough URLs to require multiple sitemap files per locale. This gives Google fine-grained crawl signals and makes Search Console reporting actionable.
28 versions per page. Every page on the site exists 28 times. The system can't be maintained manually — it has to be fully automated from configuration. Adding a new locale means adding one entry to LOCALES in site-config.ts, one CANONICAL_REGION mapping, and one label. The sitemaps, hreflang tags, middleware routing, and switcher options all regenerate.
BigCommerce has no headless SEO tools. The native redirect manager, sitemap generator, and URL management tools only work with Stencil storefronts. Going headless with Next.js means building the entire SEO infrastructure yourself — hreflang, canonical, sitemaps, robots.txt, structured data. This project filled that gap completely.
Server-rendered for crawlers. All hreflang and canonical tags render server-side in the initial HTML response. Google's crawler sees them without executing JavaScript. The HreflangHead component runs as a React Server Component — no client-side hydration overhead for tags that only crawlers need.
Results
Complete international SEO infrastructure for 28 region-locale combinations, generated from a single configuration file. Every page on the site carries the correct hreflang alternates, canonical URL, and appears in the right locale-specific sitemap. Google Search Console now has structured visibility into the full URL inventory segmented by locale and content type.
The architecture is zero-maintenance for the existing site and one-line extensible for new markets.
Tech Stack
Next.js 15, TypeScript, React Server Components, next-intl, BCP47, Dynamic Sitemaps, Hreflang, Canonical Strategy, Google Search Console