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.
- Akamai
- Fastly
- Varnish
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
&
(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.
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.
- 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. - 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. - No
304for agents: dropIf-None-MatchandIf-Modified-Sincefrom agent requests, and send the agent response withoutETagorLast-Modifiedand withCache-Control: private, no-store(see the cache contract).
Configure your CDN
- Akamai
- Fastly
- Varnish
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.
