Edge Integration
Run PerfLocale behind a Cloudflare Worker, Vercel Edge function, or Netlify Edge function, and route visitors to the correct language before the request reaches PHP. Two pieces: a public JSON endpoint the edge reads once, and a header/cookie contract so edge decisions flow into WordPress.
Disabled by default. Enable via PerfLocale → Settings → Advanced → Edge Worker Integration, or programmatically with add_filter( 'perflocale/edge/enabled', '__return_true' ). When off, no REST route is registered and the edge_hint detection method is inert.
Config endpoint
URL: GET /wp-json/perflocale/v1/config
Auth: Public (no authentication). The payload contains only data already visible in the site’s rendered HTML - hreflang tags, switcher labels, etc.
Cache headers: Cache-Control: public, max-age=300, s-maxage=3600, stale-while-revalidate=86400 and an ETag so edges can revalidate with a cheap 304.
{
"version": "1.0.0",
"url_mode": "subdirectory",
"url_prefix_type": "slug",
"default_slug": "en",
"hide_default_prefix": true,
"excluded_paths": [ "/wp-json/", "/wp-admin/", "/wp-login.php" ],
"detection_order": [ "url", "cookie", "browser", "default" ],
"edge_hint_header": "X-PerfLocale-Lang",
"edge_hint_cookie": "perflocale_edge_lang",
"languages": [
{
"slug": "en",
"locale": "en_US",
"hreflang": "en-us",
"prefix": "en",
"domain": "",
"text_direction": "ltr",
"is_default": true
}
]
}
The payload is cached internally (3-layer cache, 15-minute TTL) and invalidated automatically whenever a language is added, updated, or removed, or when settings are saved.
Hint header + cookie
To have the edge’s decision honoured by PHP, add edge_hint to your detection order (Settings → URL & Routing → Language Detection Order) and send one of:
- Header:
X-PerfLocale-Lang: fr- header wins over cookie - Cookie:
perflocale_edge_lang=fr- fallback
Both names are filterable:
add_filter( 'perflocale/edge/hint_header', fn() => 'X-Vercel-Lang' );
add_filter( 'perflocale/edge/hint_cookie', fn() => 'my_lang_cookie' );
Per-request veto:
add_filter( 'perflocale/edge/accept_hint', function ( bool $accept, string $slug ): bool {
// Reject hints from probes that don't come through our CDN.
return ! empty( $_SERVER['HTTP_CF_RAY'] ) ? $accept : false;
}, 10, 2 );
Trust model
The hint is trusted at the same level as a visitor-set cookie: at worst it lets a visitor preselect a language they could have chosen themselves. URL-based detection always wins when a prefix is present in the request path, so a spoofed hint can never override a canonical translated URL.
Reference Cloudflare Worker
A complete example ships with the plugin at assets/js/edge-helper.js. It demonstrates both deployment strategies:
- URL rewrite (recommended) - edge adds the language prefix and forwards; rewritten URL becomes the CDN cache key
- Header hint - edge forwards unchanged with
X-PerfLocale-Langset; WordPress detects viaedge_hint
const CONFIG_URL = 'https://example.com/wp-json/perflocale/v1/config';
const CACHE_TTL_MS = 10 * 60 * 1000;
let cachedConfig = null;
let cachedConfigExp = 0;
async function loadConfig() {
if ( cachedConfig && Date.now() < cachedConfigExp ) return cachedConfig;
const res = await fetch( CONFIG_URL, {
cf: { cacheEverything: true, cacheTtl: 600 }
} );
cachedConfig = await res.json();
cachedConfigExp = Date.now() + CACHE_TTL_MS;
return cachedConfig;
}
addEventListener( 'fetch', event => event.respondWith( handle( event.request ) ) );
async function handle( request ) {
const config = await loadConfig();
const country = ( request.cf && request.cf.country ) || '';
const slug = pickLanguage( country, config ); // your logic
if ( slug && slug !== config.default_slug ) {
const url = new URL( request.url );
url.pathname = '/' + slug + url.pathname;
return fetch( new Request( url.toString(), request ) );
}
return fetch( request );
}
See the plugin file for the full version with Accept-Language fallback, excluded-path handling, and the header-hint alternative strategy.
Related
- REST reference - full endpoint documentation
- Hooks reference - all four
perflocale/edge/*filters - Cache-Tag headers - complements edge routing with language-scoped CDN purges