Skip to main content
One tag in your page template, resolved by your CDN’s native Edge Side Includes for AI agents only. These are reference examples per CDN: adapt them to your configuration, then run the checks in Verify and troubleshoot. Before you start, do steps 1 to 3 of the Quickstart: a site, a fragment its pages resolve to, and a delivery key. The rules every edge keeps are in Choose your edge.

The tag

Paste the tag in the article template immediately before the article content, never at the end of <body>; see Where the card must land. onerror="continue" renders the page without the card when the call is slow or fails. page_url must reach doubleshift as one URL-encoded value, and how to build it depends on the CDN.
Build the URL with esi:assign, then encode by hand with $replace() the four characters that break a query value: % first, then &, +, =. Do not use $url_encode(): it can leave & unencoded.
ESI tag — Akamai
Check the encoding once on your stack before going live: an agent request for a path containing & (e.g. /news/a&b) must reach doubleshift with page_url ending in /news/a%26b, not cut at /news/a. ESI splices the card where the tag sits, and the answer carries the card only. The in-content brand line must name the brand of the card actually served on that page, and must be absent on a 204 (Where the card must land). A static line in the template does not meet this: the brand depends on the pick for each page, and the answer can be a no-fill. Your edge meets it only if it writes the line from the card it received (the card’s first line reads Brand · <brand>) and writes nothing when the include returned nothing. If it cannot, use the Cloudflare Worker path.
Header rewrite required/v1/fragment reads the API key from the X-API-Key header only. Never put the key in src: a key in the query string is ignored, so the call answers 401, and the tag reaches human visitors as inert HTML with the key in it. Your CDN must rewrite the include subrequest to carry X-API-Key, a benign User-Agent (bot User-Agents are blocked, silently with onerror="continue"), and the real agent in X-Agent-UA.
  • Akamai: Property Manager, in a rule scoped to requests to the fragment endpoint: Set Variable captures the incoming User-Agent request header (e.g. PMUSER_AGENT_UA), then Modify Outgoing Request Header sets X-API-Key, sets X-Agent-UA to {{user.PMUSER_AGENT_UA}}, and replaces User-Agent with a benign value.
  • Fastly: set the three headers on the include subrequest in VCL (snippet below).
If your CDN cannot add request headers, use the Cloudflare Worker path instead.

Gate ESI on every request

Decide agent or human on every request, cache hit or miss, never when the page enters the cache: a gate set at fetch time (beresp.do_esi on the bot User-Agent in vcl_fetch or vcl_backend_response) depends on who filled the cache.
  1. Parse at fetch, for every HTML page, humans included: the cached copy is the template with its tag, whoever filled it. No Vary: User-Agent, no second cache entry.
  2. Decide at delivery: resolve the include for agents only (Fastly req.esi, Akamai a Property Manager rule evaluated per request). Humans get the stored copy with the tag left inert; agents get it resolved.
  3. No 304 for agents: drop If-None-Match and If-Modified-Since from agent requests, and send the agent response without ETag or Last-Modified and with Cache-Control: private, no-store (see the cache contract).
Check it from a cold cache in both fill orders, then warm, with card markers counted in the raw HTML; the sequence is in Verify and troubleshoot.

Configure your CDN

On Akamai, the agent decision is a Property Manager rule, evaluated per request, cache hit or miss. The rule matches the agent User-Agent list (AI agents) and enables ESI processing (behavior Edge Side Includes → Enable), so the include is resolved for agents only; humans get the tag inert. In the same rule, Modify Incoming Request Header removes If-None-Match and If-Modified-Since, and Modify Outgoing Response Header removes ETag and Last-Modified and sets Cache-Control: private, no-store. Set the ESI include timeout of your property to about 800 ms.Adapt the rule to your property, then run the Verify and troubleshoot sequence (both cold fills, the warm loop and the 304 check), and check that /news/a&b reaches doubleshift with page_url ending in /news/a%26b.