
Edge Commerce
- 59 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Run geo-routing, A/B tests, and personalization at the CDN edge with Cloudflare Workers or Vercel to cut international latency.
About
Executes commerce logic in the nearest CDN PoP for geo-routing, edge personalization, and origin-free A/B testing. A developer uses it when international TTFB is high or users need region-specific storefronts.
- Per-platform edge capability table (Shopify Markets, Cloudflare, Vercel Edge)
- Geo-routing, edge personalization, and A/B testing without origin round-trips
Edge Commerce by the numbers
- 59 all-time installs (skills.sh)
- Ranked #688 of 1,039 Cloud & Infrastructure skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill edge-commerceAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 59 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Run geo-routing, A/B tests, and personalization at the CDN edge with Cloudflare Workers or Vercel to cut international latency.
Files
Edge Commerce
Overview
Edge computing executes code in the CDN PoP closest to each user, reducing latency from hundreds of milliseconds (round-trip to a central origin) to under 50ms. For e-commerce, this enables geo-routing (redirect UK users to a UK storefront), edge-side personalization (inject user tier into cached pages), instant A/B testing without origin round-trips, and distributed inventory caching via edge KV stores.
When to Use This Skill
- When pages routed through a central origin have high TTFB (>300ms) for international users
- When you need to redirect users to region-specific storefronts or localized product catalogs
- When you want to run A/B tests without adding JavaScript that delays page rendering
- When building a multi-region deployment where each region needs its own origin but shares a single domain
Core Instructions
Step 1: Determine your platform and what edge computing can do for you
| Platform | Edge Capabilities | How to Use Them |
|---|---|---|
| Shopify | Shopify's CDN (Fastly) already serves stores from global edge locations | Use Shopify Markets for geo-routing and multi-currency without custom edge code; Markets handles currency, language, and domain routing natively |
| WooCommerce | Add Cloudflare as your CDN/proxy to get edge capabilities | Cloudflare Workers (free tier: 100k requests/day) adds edge logic; configure in Cloudflare dashboard after adding your domain |
| BigCommerce | BigCommerce uses Fastly CDN globally | Use BigCommerce's built-in multi-storefront feature for geo-routing; for custom edge logic add Cloudflare in front |
| Custom / Headless | Full control — choose Cloudflare Workers, Vercel Edge Middleware, or Fastly Compute | Build custom geo-routing, A/B testing, and personalization at the edge; see implementation below |
Step 2: Configure geo-routing on your platform
---
Shopify: Use Shopify Markets
1. Go to Settings → Markets in your Shopify admin 2. Click Add market and select the countries/regions for your new market 3. Configure per-market settings:
- Currency: set the local currency (Shopify handles conversion automatically)
- Language: assign a translated theme version
- Domain/subdomain: e.g.,
uk.yourstore.comroutes UK visitors automatically
4. Shopify automatically redirects users to their market based on IP geolocation — no custom code needed 5. For manual market URL overrides: Shopify's cookie-based market selector handles users who want to change their market
---
WooCommerce: Cloudflare Workers geo-routing
1. Add your domain to Cloudflare (free plan is sufficient for geo-routing) 2. Go to Workers & Pages → Create Worker in the Cloudflare dashboard 3. Add a simple geo-redirect rule:
// Cloudflare Worker — deploy via Cloudflare dashboard
export default {
async fetch(request) {
const country = request.headers.get('CF-IPCountry') ?? 'US';
const url = new URL(request.url);
// Redirect UK users to UK store variant
if (country === 'GB' && !url.pathname.startsWith('/uk')) {
return Response.redirect(`https://${url.hostname}/uk${url.pathname}`, 302);
}
return fetch(request);
}
};4. In Worker settings, add a Route that matches your domain: *yourstore.com/* 5. For currency/language: use a WooCommerce multi-currency plugin (WPML + WooCommerce Multilingual, or Aelia Currency Switcher) that reads the URL path or a cookie set by the Worker
---
Custom / Headless
Vercel Edge Middleware (Next.js) for geo-routing:
// middleware.ts — runs at the edge globally, <5ms
import { NextRequest, NextResponse } from 'next/server';
import { geolocation } from '@vercel/functions';
const REGION_MAP: Record<string, string> = {
GB: 'uk', DE: 'de', FR: 'fr', CA: 'ca', AU: 'au',
};
export function middleware(request: NextRequest) {
const { country } = geolocation(request);
const region = country ? REGION_MAP[country] : null;
// Redirect root to regional store
if (region && request.nextUrl.pathname === '/') {
const url = request.nextUrl.clone();
url.pathname = `/${region}`;
return NextResponse.redirect(url, { status: 302 });
}
// Pass country to origin for catalog/pricing logic
const response = NextResponse.next();
if (country) response.headers.set('x-user-country', country);
return response;
}
export const config = { matcher: ['/', '/products/:path*', '/collections/:path*'] };Edge A/B testing (assign variant once, persist in cookie):
// In middleware.ts — no origin round-trip needed
const EXPERIMENTS = [
{ id: 'checkout-cta', buckets: [{ name: 'control', weight: 0.5 }, { name: 'variant-a', weight: 0.5 }] },
];
function assignVariant(buckets: Array<{name: string; weight: number}>) {
let r = Math.random(), cumulative = 0;
for (const b of buckets) {
cumulative += b.weight;
if (r < cumulative) return b.name;
}
return buckets[0].name;
}
// Add to existing middleware function:
for (const exp of EXPERIMENTS) {
const cookieName = `ab_${exp.id}`;
let variant = request.cookies.get(cookieName)?.value;
if (!variant) {
variant = assignVariant(exp.buckets);
response.cookies.set(cookieName, variant, { maxAge: 30 * 24 * 3600, httpOnly: true });
}
response.headers.set(`x-ab-${exp.id}`, variant); // available in your app for rendering
}Cloudflare Workers KV for edge inventory caching:
// cloudflare-worker.ts — inventory cached at every Cloudflare PoP globally
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname.startsWith('/api/inventory/')) {
const productId = url.pathname.replace('/api/inventory/', '');
const cached = await env.INVENTORY_KV.get(productId, 'json');
if (cached) {
return new Response(JSON.stringify(cached), {
headers: { 'Content-Type': 'application/json', 'X-Edge-Cache': 'HIT' },
});
}
// Cache miss — fetch from origin and store for 60 seconds
const data = await fetch(`${env.ORIGIN_URL}/api/inventory/${productId}`).then(r => r.json());
await env.INVENTORY_KV.put(productId, JSON.stringify(data), { expirationTtl: 60 });
return new Response(JSON.stringify(data), {
headers: { 'Content-Type': 'application/json', 'X-Edge-Cache': 'MISS' },
});
}
return fetch(request);
},
};KV namespace wrangler.toml:
name = "commerce-edge"
main = "src/index.ts"
compatibility_date = "2025-01-01"
[[kv_namespaces]]
binding = "INVENTORY_KV"
id = "your-kv-namespace-id"Vercel Edge Config for instant feature flags:
// Read feature flags at edge — ~0ms latency (stored in PoP)
import { get } from '@vercel/edge-config';
export async function middleware(request: NextRequest) {
const maintenanceMode = await get<boolean>('maintenance_mode');
if (maintenanceMode) {
return NextResponse.rewrite(new URL('/maintenance', request.url));
}
return NextResponse.next();
}Step 3: Monitor edge performance
Regardless of platform, measure these metrics:
1. TTFB from multiple regions — use tools like WebPageTest.org with test locations in US, EU, and Asia; target under 200ms TTFB from each region 2. CDN cache hit rate — Cloudflare: Analytics → Performance → Cache hit rate (target 90%+); Shopify: check Lighthouse via Online Store → Themes → View report 3. Edge error rate — Cloudflare: Workers → Metrics; Vercel: Deployments → Functions tab 4. Geographic latency breakdown — Cloudflare Analytics shows latency by country; use this to identify regions that would benefit from an additional origin
Best Practices
- Use edge for routing decisions, not business logic — edge functions are best for fast decisions based on request metadata (country, cookie, header); complex business logic (pricing, inventory) belongs at the origin with a result cached at the edge
- Keep edge functions fast — Cloudflare Workers have 10ms CPU limit on free plan, 30ms on paid; avoid synchronous external API calls from edge middleware on the critical path
- Pre-populate KV before product launches — Workers KV has eventual consistency; pre-populate edge inventory cache before a flash sale via the KV REST API
- Test geo-routing from multiple locations — use a VPN to verify redirect logic; production geo-routing mistakes affect all users in a region
Common Pitfalls
| Problem | Solution |
|---|---|
| Edge making external API calls on every request | Cache external data in Edge Config or Workers KV; never make synchronous third-party API calls from edge middleware on the critical path |
Personalized responses cached without Vary header | Set Vary: Cookie or a custom header that differentiates personalized responses; without it, one user's content can be served to others |
| Workers KV stale inventory causing oversells | Use edge KV only for displaying inventory status; always validate against the authoritative inventory source at checkout time |
| A/B variant flickering on first load | Set the variant cookie in the response before the page renders; on first visit, set the cookie and redirect to ensure consistent rendering |
Related Skills
- @ecommerce-caching
- @flash-sale-scaling
- @monitoring-alerting-commerce
- @image-optimization-cdn
{
"context": "Tests whether the agent correctly implements a Cloudflare Worker for edge inventory caching and regional pricing, including correct KV access patterns, wrangler.toml configuration, cache header conventions, pricing header names, and Analytics Engine telemetry with the correct data point structure.",
"type": "weighted_checklist",
"checklist": [
{
"name": "CF-IPCountry header",
"max_score": 8,
"description": "Reads country from the `CF-IPCountry` request header (not a geolocation API or IP lookup library)"
},
{
"name": "KV get with json type",
"max_score": 8,
"description": "KV reads use `.get(key, 'json')` (second argument is `'json'`) for typed deserialization"
},
{
"name": "KV TTL on inventory puts",
"max_score": 8,
"description": "KV inventory writes use `expirationTtl: 60` (60-second expiry on put calls)"
},
{
"name": "X-Edge-Cache HIT header",
"max_score": 7,
"description": "Response includes `X-Edge-Cache: HIT` when inventory is served from KV cache"
},
{
"name": "X-Edge-Cache MISS header",
"max_score": 5,
"description": "Response includes `X-Edge-Cache: MISS` when inventory is fetched from origin"
},
{
"name": "wrangler.toml kv_namespaces",
"max_score": 8,
"description": "`wrangler.toml` contains at least one `[[kv_namespaces]]` section with a `binding` field"
},
{
"name": "wrangler.toml compatibility_date",
"max_score": 8,
"description": "`wrangler.toml` sets `compatibility_date = \"2025-01-01\"`"
},
{
"name": "wrangler.toml cron trigger",
"max_score": 7,
"description": "`wrangler.toml` includes a `[triggers]` section with `crons = [\"*/1 * * * *\"]`"
},
{
"name": "Pricing headers to origin",
"max_score": 10,
"description": "Regional pricing is forwarded to the origin via request headers named `x-currency`, `x-tax-rate`, and `x-duty-rate`"
},
{
"name": "Stale inventory acknowledgment",
"max_score": 10,
"description": "Code or comments indicate that edge KV inventory is NOT the authoritative count, and that final validation happens at checkout (not at the edge)"
},
{
"name": "Analytics Engine writeDataPoint blobs",
"max_score": 9,
"description": "Calls `env.ANALYTICS.writeDataPoint()` with a `blobs` array containing at minimum: request path, country/region, and cache status"
},
{
"name": "Analytics Engine writeDataPoint doubles",
"max_score": 12,
"description": "The `writeDataPoint` call includes a `doubles` array with at minimum: request duration and response status code"
}
]
}
Edge Inventory and Pricing Layer for a Global Electronics Retailer
Problem/Feature Description
Volta Electronics sells consumer electronics globally through a single Cloudflare-fronted domain. Their product pages currently display inventory counts and pricing that are fetched synchronously from a US-based origin API on every request. For shoppers in Europe and Asia-Pacific this adds 400–600ms of latency, and during product launches the origin becomes a bottleneck when thousands of users simultaneously check the same product.
The platform team wants to move to a Cloudflare Worker that intercepts inventory requests and serves them from an edge KV store (refreshed automatically every minute), and that enriches product API requests with region-specific pricing data (currency, local tax rate, import duty rate) before forwarding them to the origin. They also need end-to-end visibility into how the edge layer is performing — specifically, which requests are cache hits vs. misses, how long each request takes, and what HTTP status codes are being returned — so they can feed this data into their observability platform via Cloudflare's native telemetry.
Output Specification
Produce the following files:
src/index.ts— the Cloudflare Worker implementation handling inventory cache reads/writes and regional pricing header injectionwrangler.toml— the Cloudflare Worker project configuration, including all necessary KV namespace bindings, the compatibility date, and a scheduled trigger for inventory refreshimplementation-notes.md— a short document explaining the caching strategy, how regional pricing data flows from the edge to the origin, and any important caveats about inventory accuracy at checkout time
The implementation should handle both the cache hit and miss paths for inventory requests and include telemetry instrumentation for request performance.
{
"context": "Tests whether the agent correctly implements edge-side personalization using the shell-caching pattern with Cloudflare's cache API, sets appropriate Vary headers to prevent cache pollution, avoids large library dependencies, and ensures edge writes are idempotent.",
"type": "weighted_checklist",
"checklist": [
{
"name": "caches.default usage",
"max_score": 12,
"description": "Uses `caches.default` (the Cloudflare Cache API) to store and retrieve the page shell, not a KV namespace or in-memory Map"
},
{
"name": "waitUntil for cache put",
"max_score": 12,
"description": "Cache writes are done via `ctx.waitUntil(cache.put(...))` or `env.ctx?.waitUntil(cache.put(...))` (background, non-blocking)"
},
{
"name": "Impersonal cache key",
"max_score": 10,
"description": "The cache key used for `cache.match()` and `cache.put()` is based only on the URL (NOT including customer ID, cookies, or other personalization data)"
},
{
"name": "Vary header on personalized responses",
"max_score": 12,
"description": "Personalized responses include a `Vary` header set to the customer identifier header (e.g. `Vary: x-customer-id` or equivalent)"
},
{
"name": "No broad Vary: Cookie",
"max_score": 8,
"description": "Does NOT set `Vary: Cookie` broadly on all responses (only sets Vary on the personalization-specific header that differentiates variants)"
},
{
"name": "Placeholder injection pattern",
"max_score": 10,
"description": "Personalization is injected by replacing a placeholder string in the cached HTML shell (e.g. `html.replace('<!--CUSTOMER_TIER-->', ...)`) rather than fetching a unique page from origin per customer"
},
{
"name": "Anonymous path returns cached shell",
"max_score": 8,
"description": "Requests without a customer identifier (unauthenticated users) are served the cached shell directly without triggering any personalization logic"
},
{
"name": "No large library imports",
"max_score": 8,
"description": "Does NOT import lodash, moment, or other large utility libraries; uses native Web APIs (e.g. native string methods, `URL`, `Response`, `Request`) throughout"
},
{
"name": "Idempotent edge writes",
"max_score": 10,
"description": "Any write operations (analytics events, cookie setting) are safe to execute more than once — either by design or with an explicit guard — to handle Worker retry scenarios"
},
{
"name": "Prefs from KV not external fetch",
"max_score": 10,
"description": "Customer personalization data (tier, preferences) is read from an edge KV store, NOT via an inline synchronous fetch to an external API"
}
]
}
Loyalty Tier Personalization at the Edge for a Home Goods Platform
Problem/Feature Description
Hearth & Home is a direct-to-consumer home goods brand with a growing loyalty program. Members are assigned one of three tiers (Silver, Gold, Platinum) and should see a tier badge on product pages along with tier-specific messaging. Currently, the origin server renders a unique page per customer, which means the CDN cache is essentially useless — every logged-in customer bypasses the cache entirely, driving up origin load and worsening page load times globally.
The infrastructure team believes they can dramatically improve cache efficiency by having the origin serve a single cached HTML "shell" for each product page, and then injecting the customer-specific tier badge at the edge using a Cloudflare Worker. Customer tier preferences are already stored in an edge-accessible data store keyed by a customer ID that is passed in a request header by the storefront. The Worker also needs to be safe to deploy in an environment where Cloudflare may retry requests due to transient failures — so any side effects the Worker performs must handle being executed more than once gracefully.
Output Specification
Produce the following files:
worker.ts— the Cloudflare Worker that implements shell caching for product pages and injects personalization for identified loyalty membersdesign-notes.md— a document explaining the cache architecture: how the shell is stored and retrieved, how personalized vs. anonymous responses differ in their cache headers, and why this approach avoids serving one customer's page to another
The implementation should handle both the authenticated (loyalty member) and anonymous (guest) request paths.
{
"context": "Tests whether the agent correctly implements Vercel Edge Middleware for a multi-region e-commerce site using the prescribed geolocation API, cookie conventions, header patterns for A/B testing, and Edge Config for feature flags — without making synchronous external API calls on the critical path.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Geolocation import source",
"max_score": 12,
"description": "Imports `geolocation` from `@vercel/functions` (not from any other package or custom implementation)"
},
{
"name": "Next.js server imports",
"max_score": 5,
"description": "Imports `NextRequest` and `NextResponse` from `next/server`"
},
{
"name": "Geo-redirect status code",
"max_score": 8,
"description": "Geo-routing redirect uses HTTP 302 (not 301 or other codes)"
},
{
"name": "Country header forwarding",
"max_score": 7,
"description": "Sets `x-user-country` header on the response (passing country to downstream handlers)"
},
{
"name": "Middleware matcher paths",
"max_score": 8,
"description": "Exported `config.matcher` includes all three of: `'/'`, `'/products/:path*'`, and `'/collections/:path*'`"
},
{
"name": "A/B cookie name format",
"max_score": 8,
"description": "A/B variant cookie is named using the pattern `ab_{experimentId}` (e.g., `ab_checkout-button-color`)"
},
{
"name": "A/B cookie attributes",
"max_score": 10,
"description": "A/B cookie is set with maxAge equivalent to 30 days (2592000 seconds), `sameSite: 'lax'`, and `httpOnly: true`"
},
{
"name": "A/B variant response header",
"max_score": 8,
"description": "Sets `x-ab-{experimentId}` response header with the assigned variant value"
},
{
"name": "Edge Config for feature flags",
"max_score": 12,
"description": "Uses `get()` from `@vercel/edge-config` to read feature flag values (not an external fetch/axios call)"
},
{
"name": "No synchronous external API calls",
"max_score": 12,
"description": "Middleware does NOT make synchronous `fetch()` calls to third-party or external APIs (all configuration is read from Edge Config or request metadata)"
},
{
"name": "Existing variant respected",
"max_score": 10,
"description": "Before assigning a new A/B variant, the middleware checks for an existing variant cookie and reuses it if present"
}
]
}
Regional Storefront Routing and Checkout Experiments for a Fashion Platform
Problem/Feature Description
Kova Fashion is a mid-sized apparel brand with dedicated storefronts for shoppers in the UK, Germany, France, Canada, and Australia. Currently, all traffic hits the same US-based Next.js origin regardless of where the shopper is located, causing frustrating experiences: UK shoppers see USD prices and US sizing, German shoppers see content in the wrong language, and load times for European users are noticeably slower.
The engineering team wants to implement middleware that automatically sends international visitors to their regional storefront on the first page visit, passes country context to the origin for any requests that aren't redirected, and runs a checkout button color experiment without adding client-side JavaScript that would delay page rendering. They also need the ability to toggle a maintenance mode and disable checkout via fast-reading configuration flags, without making any slow network calls in the middleware itself.
Output Specification
Produce a middleware.ts file (suitable for a Next.js project) that:
- Handles geo-based routing: visitors from supported regions are redirected to the appropriate regional path on the homepage; all requests include the resolved country on a request/response header for downstream use
- Runs a checkout button color A/B experiment: each new visitor is assigned a variant and that assignment is persisted; the current variant is always surfaced as a response header
- Reads at least two feature flags (maintenance mode and checkout availability) from a fast edge-side configuration store and applies the corresponding rewrites/redirects
- Applies only to the paths relevant to product browsing and collection pages
Also produce a brief implementation-notes.md explaining any key design decisions, especially around how configuration is read at the edge and what the middleware does vs. what is left to the origin.
{
"name": "finsi/edge-commerce",
"version": "0.1.0",
"summary": "Edge computing for commerce — geo-routing, edge-side personalization, KV stores",
"skills": {
"edge-commerce": {
"path": "SKILL.md"
}
}
}