[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-netlify-netlify-caching":3,"mdc--lv5vnt-key":33,"related-repo-netlify-netlify-caching":2313,"related-org-netlify-netlify-caching":2415},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":31,"mdContent":32},"netlify-caching","configure CDN caching on Netlify","Guide for controlling caching on Netlify's CDN. Use when configuring cache headers, setting up stale-while-revalidate, implementing on-demand cache purge, or understanding Netlify's CDN caching behavior. Covers Cache-Control, Netlify-CDN-Cache-Control, cache tags, durable cache, and framework-specific caching patterns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"netlify","Netlify","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fnetlify.png",[12,16,17,20],{"name":13,"slug":14,"type":15},"Performance","performance","tag",{"name":9,"slug":8,"type":15},{"name":18,"slug":19,"type":15},"Deployment","deployment",{"name":21,"slug":22,"type":15},"Caching","caching",24,"https:\u002F\u002Fgithub.com\u002Fnetlify\u002Fcontext-and-tools","2026-07-14T05:40:20.066717",null,5,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":26},[],"https:\u002F\u002Fgithub.com\u002Fnetlify\u002Fcontext-and-tools\u002Ftree\u002FHEAD\u002Fskills\u002Fnetlify-caching","---\nname: netlify-caching\ndescription: Guide for controlling caching on Netlify's CDN. Use when configuring cache headers, setting up stale-while-revalidate, implementing on-demand cache purge, or understanding Netlify's CDN caching behavior. Covers Cache-Control, Netlify-CDN-Cache-Control, cache tags, durable cache, and framework-specific caching patterns.\n---\n\n# Caching on Netlify\n\n## Default Behavior\n\n**Static assets** are cached automatically:\n- CDN: cached for 1 year, invalidated on every deploy\n- Browser: always revalidates (`max-age=0, must-revalidate`)\n- No configuration needed\n\n**Dynamic responses** (functions, edge functions, proxied) are **not cached by default**. Add cache headers explicitly.\n\n**Only `GET` requests are cached.** Netlify's CDN caches responses to `GET` requests only. Responses to `POST`, `PUT`, `PATCH`, `DELETE`, and other non-`GET` methods are never cached, no matter what cache headers you set on them. If a response needs to be CDN-cacheable, expose it on a `GET` route (put the inputs in the URL\u002Fquery string) — you cannot make the CDN cache a mutating `POST` endpoint by adding cache headers.\n\n## Cache-Control Headers\n\nThree headers control caching, from most to least specific:\n\n| Header | Who sees it | Use case |\n|---|---|---|\n| `Netlify-CDN-Cache-Control` | Netlify CDN only (stripped before browser) | CDN-only caching |\n| `CDN-Cache-Control` | All CDN caches (stripped before browser) | Multi-CDN setups |\n| `Cache-Control` | Browser and all caches | General caching |\n\n### Common Patterns\n\n```typescript\n\u002F\u002F Cache at CDN for 1 hour, browser always revalidates\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=3600, must-revalidate\",\n    \"Cache-Control\": \"public, max-age=0, must-revalidate\",\n  },\n});\n\n\u002F\u002F Stale-while-revalidate (serve stale for 2 min while refreshing)\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, max-age=60, stale-while-revalidate=120\",\n  },\n});\n\n\u002F\u002F Durable cache (shared across edge nodes, serverless functions only)\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, durable, max-age=60, stale-while-revalidate=120\",\n  },\n});\n```\n\n### Immutable Assets\n\nFor fingerprinted files (hash in filename):\n\n```toml\n# netlify.toml\n[[headers]]\nfor = \"\u002Fassets\u002F*\"\n[headers.values]\nCache-Control = \"public, max-age=31536000, immutable\"\n```\n\n## Cache Tags and On-Demand Purge\n\nTag responses for selective cache invalidation:\n\n```typescript\nreturn new Response(body, {\n  headers: {\n    \"Netlify-Cache-Tag\": \"product,listing\",\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=86400\",\n  },\n});\n```\n\nPurge by tag:\n\n```typescript\nimport { purgeCache } from \"@netlify\u002Ffunctions\";\n\nexport default async () => {\n  await purgeCache({ tags: [\"product\"] });\n  return new Response(\"Purged\", { status: 202 });\n};\n```\n\nPurge entire site:\n\n```typescript\nawait purgeCache();\n```\n\n`purgeCache()` picks up the site ID and credentials automatically **only when it runs inside a deployed Netlify Function**. Called from anywhere else — a local script, a CI job, a build step, or any code outside the Netlify Functions runtime — it has no ambient credentials, and you must pass a Netlify personal access token (and the site ID). Read the token from an environment variable; never hardcode it:\n\n```typescript\nawait purgeCache({\n  token: process.env.NETLIFY_PURGE_TOKEN, \u002F\u002F a Netlify personal access token, from env\n  siteID: process.env.NETLIFY_SITE_ID,\n  tags: [\"product\"],\n});\n```\n\n`Netlify-Cache-Tag` is **purge-only**: tagged responses are still cleared by automatic deploy-based invalidation like everything else. The tag only lets you purge them on demand between deploys.\n\n### Surviving deploys with `Netlify-Cache-ID`\n\nTo keep a cached response *across* deploys, set a `Netlify-Cache-ID` header. A response carrying it is **excluded from automatic deploy-based invalidation** — it persists across deploys and clears only on explicit purge. The `Netlify-Cache-ID` value also auto-registers as a purge tag, so you purge it by that same id:\n\n```typescript\nreturn new Response(body, {\n  headers: {\n    \"Netlify-Cache-ID\": \"catalog\",\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=86400\",\n  },\n});\n```\n\n```typescript\nimport { purgeCache } from \"@netlify\u002Ffunctions\";\n\n\u002F\u002F Purge by the same id — it doubles as a purge tag.\nawait purgeCache({ tags: [\"catalog\"] });\n```\n\n## Cache Key Variation\n\n`Netlify-Vary` controls what creates separate cache entries. Each directive names a dimension — `query`, `header`, `cookie`, `country`, or `language` — followed by an enumerated, pipe-separated list of the values to key on:\n\n```typescript\nreturn new Response(body, {\n  headers: {\n    \"Netlify-Vary\": \"cookie=ab_test|is_logged_in\",\n  },\n});\n```\n\n- `query=param1|param2` — key on the named query parameters\n- `header=X-Custom` — key on the named request header\n- `cookie=ab_test|is_logged_in` — key on the named cookies\n- `country=us|de` — serve a distinct cached entry to visitors from the listed countries (two-letter, lowercase ISO country codes)\n- `language=en|fr` — key on the listed `Accept-Language` values\n\nCombine dimensions by separating directives with commas — e.g. `Netlify-Vary: query=theme, cookie=plan` keys the cache on both the `theme` query parameter and the `plan` cookie. Always enumerate the specific values; keying on an entire dimension (for example a bare `Vary: Cookie`) fragments the cache into a separate entry per unique visitor.\n\n## Framework-Specific Caching\n\n### Next.js\nISR uses Netlify's durable cache automatically (runtime 5.5.0+). `revalidatePath` and `revalidateTag` trigger cache purge.\n\n### Astro \u002F Remix\nFull control over cache headers in server routes. Set `Netlify-CDN-Cache-Control` in responses for CDN caching.\n\n### Nuxt\nDefault Nitro preset handles caching. ISR-style patterns use `routeRules` with `swr` or `isr` options.\n\n### Vite SPA\nStatic assets are cached by default. API responses from Netlify Functions need explicit cache headers.\n\n**The full query string is part of the cache key by default.** With no `Netlify-Vary: query=` directive, every distinct query string is cached as a separate entry — so appending tracking or marketing params (`?utm_source=…`, `fbclid`, and the like) silently fragments the cache into many near-duplicate entries and lowers the hit rate, even when those params don't change the response. Add `Netlify-Vary: query=\u003Cnames>` listing only the parameters that actually affect the output; the CDN then keys on just those and ignores all other query params, collapsing the variants onto one cache entry.\n\n## Local Development\n\n`netlify dev` does not emulate the CDN cache. Header-based CDN caching is only observable on a deployed site: locally, cache headers pass through untouched, nothing is stored in or served from the CDN cache, Cache-API reads return no persisted entries, and the `Cache-Status` response header is absent. A \"cache miss every time\" on `localhost` is expected, not a bug — you cannot validate `Netlify-Vary` keying, cache tags, durable cache, or purge behavior locally. Verify caching on a deployed URL instead (a Deploy Preview or production) and read its `Cache-Status` header.\n\n## Debugging\n\nCheck the `Cache-Status` response header. Netlify emits it in the RFC 9211 format — one entry per named cache layer the request passed through, not a bare `HIT`\u002F`MISS`:\n\n```\nCache-Status: \"Netlify Edge\"; fwd=miss, \"Netlify Durable\"; hit; ttl=3600\n```\n\n- A named layer (`\"Netlify Edge\"`, `\"Netlify Durable\"`) with `hit` — served from that cache\n- `fwd=miss` — the entry was not in that layer, so the request was forwarded onward\n- `ttl=…` — remaining freshness (seconds) for a hit\n\n## Constraints\n\n- Basic auth disables caching for the entire site\n- Durable cache is serverless functions only (not edge functions)\n- Same URL must return identical `Netlify-Vary` headers across responses\n- Deploy invalidation is scoped to deploy context (production vs preview)\n",{"data":34,"body":35},{"name":4,"description":6},{"type":36,"children":37},"root",[38,47,54,66,95,112,188,194,199,298,305,736,742,747,796,802,807,951,956,1190,1195,1223,1241,1402,1419,1431,1465,1607,1727,1733,1781,1888,1953,1990,1996,2002,2023,2029,2041,2047,2076,2082,2087,2128,2134,2175,2181,2208,2218,2271,2277,2307],{"type":39,"tag":40,"props":41,"children":43},"element","h1",{"id":42},"caching-on-netlify",[44],{"type":45,"value":46},"text","Caching on Netlify",{"type":39,"tag":48,"props":49,"children":51},"h2",{"id":50},"default-behavior",[52],{"type":45,"value":53},"Default Behavior",{"type":39,"tag":55,"props":56,"children":57},"p",{},[58,64],{"type":39,"tag":59,"props":60,"children":61},"strong",{},[62],{"type":45,"value":63},"Static assets",{"type":45,"value":65}," are cached automatically:",{"type":39,"tag":67,"props":68,"children":69},"ul",{},[70,76,90],{"type":39,"tag":71,"props":72,"children":73},"li",{},[74],{"type":45,"value":75},"CDN: cached for 1 year, invalidated on every deploy",{"type":39,"tag":71,"props":77,"children":78},{},[79,81,88],{"type":45,"value":80},"Browser: always revalidates (",{"type":39,"tag":82,"props":83,"children":85},"code",{"className":84},[],[86],{"type":45,"value":87},"max-age=0, must-revalidate",{"type":45,"value":89},")",{"type":39,"tag":71,"props":91,"children":92},{},[93],{"type":45,"value":94},"No configuration needed",{"type":39,"tag":55,"props":96,"children":97},{},[98,103,105,110],{"type":39,"tag":59,"props":99,"children":100},{},[101],{"type":45,"value":102},"Dynamic responses",{"type":45,"value":104}," (functions, edge functions, proxied) are ",{"type":39,"tag":59,"props":106,"children":107},{},[108],{"type":45,"value":109},"not cached by default",{"type":45,"value":111},". Add cache headers explicitly.",{"type":39,"tag":55,"props":113,"children":114},{},[115,128,130,135,137,143,145,151,152,158,159,165,167,172,174,179,181,186],{"type":39,"tag":59,"props":116,"children":117},{},[118,120,126],{"type":45,"value":119},"Only ",{"type":39,"tag":82,"props":121,"children":123},{"className":122},[],[124],{"type":45,"value":125},"GET",{"type":45,"value":127}," requests are cached.",{"type":45,"value":129}," Netlify's CDN caches responses to ",{"type":39,"tag":82,"props":131,"children":133},{"className":132},[],[134],{"type":45,"value":125},{"type":45,"value":136}," requests only. Responses to ",{"type":39,"tag":82,"props":138,"children":140},{"className":139},[],[141],{"type":45,"value":142},"POST",{"type":45,"value":144},", ",{"type":39,"tag":82,"props":146,"children":148},{"className":147},[],[149],{"type":45,"value":150},"PUT",{"type":45,"value":144},{"type":39,"tag":82,"props":153,"children":155},{"className":154},[],[156],{"type":45,"value":157},"PATCH",{"type":45,"value":144},{"type":39,"tag":82,"props":160,"children":162},{"className":161},[],[163],{"type":45,"value":164},"DELETE",{"type":45,"value":166},", and other non-",{"type":39,"tag":82,"props":168,"children":170},{"className":169},[],[171],{"type":45,"value":125},{"type":45,"value":173}," methods are never cached, no matter what cache headers you set on them. If a response needs to be CDN-cacheable, expose it on a ",{"type":39,"tag":82,"props":175,"children":177},{"className":176},[],[178],{"type":45,"value":125},{"type":45,"value":180}," route (put the inputs in the URL\u002Fquery string) — you cannot make the CDN cache a mutating ",{"type":39,"tag":82,"props":182,"children":184},{"className":183},[],[185],{"type":45,"value":142},{"type":45,"value":187}," endpoint by adding cache headers.",{"type":39,"tag":48,"props":189,"children":191},{"id":190},"cache-control-headers",[192],{"type":45,"value":193},"Cache-Control Headers",{"type":39,"tag":55,"props":195,"children":196},{},[197],{"type":45,"value":198},"Three headers control caching, from most to least specific:",{"type":39,"tag":200,"props":201,"children":202},"table",{},[203,227],{"type":39,"tag":204,"props":205,"children":206},"thead",{},[207],{"type":39,"tag":208,"props":209,"children":210},"tr",{},[211,217,222],{"type":39,"tag":212,"props":213,"children":214},"th",{},[215],{"type":45,"value":216},"Header",{"type":39,"tag":212,"props":218,"children":219},{},[220],{"type":45,"value":221},"Who sees it",{"type":39,"tag":212,"props":223,"children":224},{},[225],{"type":45,"value":226},"Use case",{"type":39,"tag":228,"props":229,"children":230},"tbody",{},[231,254,276],{"type":39,"tag":208,"props":232,"children":233},{},[234,244,249],{"type":39,"tag":235,"props":236,"children":237},"td",{},[238],{"type":39,"tag":82,"props":239,"children":241},{"className":240},[],[242],{"type":45,"value":243},"Netlify-CDN-Cache-Control",{"type":39,"tag":235,"props":245,"children":246},{},[247],{"type":45,"value":248},"Netlify CDN only (stripped before browser)",{"type":39,"tag":235,"props":250,"children":251},{},[252],{"type":45,"value":253},"CDN-only caching",{"type":39,"tag":208,"props":255,"children":256},{},[257,266,271],{"type":39,"tag":235,"props":258,"children":259},{},[260],{"type":39,"tag":82,"props":261,"children":263},{"className":262},[],[264],{"type":45,"value":265},"CDN-Cache-Control",{"type":39,"tag":235,"props":267,"children":268},{},[269],{"type":45,"value":270},"All CDN caches (stripped before browser)",{"type":39,"tag":235,"props":272,"children":273},{},[274],{"type":45,"value":275},"Multi-CDN setups",{"type":39,"tag":208,"props":277,"children":278},{},[279,288,293],{"type":39,"tag":235,"props":280,"children":281},{},[282],{"type":39,"tag":82,"props":283,"children":285},{"className":284},[],[286],{"type":45,"value":287},"Cache-Control",{"type":39,"tag":235,"props":289,"children":290},{},[291],{"type":45,"value":292},"Browser and all caches",{"type":39,"tag":235,"props":294,"children":295},{},[296],{"type":45,"value":297},"General caching",{"type":39,"tag":299,"props":300,"children":302},"h3",{"id":301},"common-patterns",[303],{"type":45,"value":304},"Common Patterns",{"type":39,"tag":306,"props":307,"children":312},"pre",{"className":308,"code":309,"language":310,"meta":311,"style":311},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Cache at CDN for 1 hour, browser always revalidates\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=3600, must-revalidate\",\n    \"Cache-Control\": \"public, max-age=0, must-revalidate\",\n  },\n});\n\n\u002F\u002F Stale-while-revalidate (serve stale for 2 min while refreshing)\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, max-age=60, stale-while-revalidate=120\",\n  },\n});\n\n\u002F\u002F Durable cache (shared across edge nodes, serverless functions only)\nreturn new Response(body, {\n  headers: {\n    \"Netlify-CDN-Cache-Control\": \"public, durable, max-age=60, stale-while-revalidate=120\",\n  },\n});\n","typescript","",[313],{"type":39,"tag":82,"props":314,"children":315},{"__ignoreMap":311},[316,328,366,385,427,463,472,490,500,509,537,553,590,598,614,622,631,659,675,712,720],{"type":39,"tag":317,"props":318,"children":321},"span",{"class":319,"line":320},"line",1,[322],{"type":39,"tag":317,"props":323,"children":325},{"style":324},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[326],{"type":45,"value":327},"\u002F\u002F Cache at CDN for 1 hour, browser always revalidates\n",{"type":39,"tag":317,"props":329,"children":331},{"class":319,"line":330},2,[332,338,344,350,356,361],{"type":39,"tag":317,"props":333,"children":335},{"style":334},"--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic",[336],{"type":45,"value":337},"return",{"type":39,"tag":317,"props":339,"children":341},{"style":340},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[342],{"type":45,"value":343}," new",{"type":39,"tag":317,"props":345,"children":347},{"style":346},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[348],{"type":45,"value":349}," Response",{"type":39,"tag":317,"props":351,"children":353},{"style":352},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[354],{"type":45,"value":355},"(body",{"type":39,"tag":317,"props":357,"children":358},{"style":340},[359],{"type":45,"value":360},",",{"type":39,"tag":317,"props":362,"children":363},{"style":340},[364],{"type":45,"value":365}," {\n",{"type":39,"tag":317,"props":367,"children":369},{"class":319,"line":368},3,[370,376,381],{"type":39,"tag":317,"props":371,"children":373},{"style":372},"--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178",[374],{"type":45,"value":375},"  headers",{"type":39,"tag":317,"props":377,"children":378},{"style":340},[379],{"type":45,"value":380},":",{"type":39,"tag":317,"props":382,"children":383},{"style":340},[384],{"type":45,"value":365},{"type":39,"tag":317,"props":386,"children":388},{"class":319,"line":387},4,[389,394,398,403,407,412,418,422],{"type":39,"tag":317,"props":390,"children":391},{"style":340},[392],{"type":45,"value":393},"    \"",{"type":39,"tag":317,"props":395,"children":396},{"style":372},[397],{"type":45,"value":243},{"type":39,"tag":317,"props":399,"children":400},{"style":340},[401],{"type":45,"value":402},"\"",{"type":39,"tag":317,"props":404,"children":405},{"style":340},[406],{"type":45,"value":380},{"type":39,"tag":317,"props":408,"children":409},{"style":340},[410],{"type":45,"value":411}," \"",{"type":39,"tag":317,"props":413,"children":415},{"style":414},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[416],{"type":45,"value":417},"public, s-maxage=3600, must-revalidate",{"type":39,"tag":317,"props":419,"children":420},{"style":340},[421],{"type":45,"value":402},{"type":39,"tag":317,"props":423,"children":424},{"style":340},[425],{"type":45,"value":426},",\n",{"type":39,"tag":317,"props":428,"children":429},{"class":319,"line":27},[430,434,438,442,446,450,455,459],{"type":39,"tag":317,"props":431,"children":432},{"style":340},[433],{"type":45,"value":393},{"type":39,"tag":317,"props":435,"children":436},{"style":372},[437],{"type":45,"value":287},{"type":39,"tag":317,"props":439,"children":440},{"style":340},[441],{"type":45,"value":402},{"type":39,"tag":317,"props":443,"children":444},{"style":340},[445],{"type":45,"value":380},{"type":39,"tag":317,"props":447,"children":448},{"style":340},[449],{"type":45,"value":411},{"type":39,"tag":317,"props":451,"children":452},{"style":414},[453],{"type":45,"value":454},"public, max-age=0, must-revalidate",{"type":39,"tag":317,"props":456,"children":457},{"style":340},[458],{"type":45,"value":402},{"type":39,"tag":317,"props":460,"children":461},{"style":340},[462],{"type":45,"value":426},{"type":39,"tag":317,"props":464,"children":466},{"class":319,"line":465},6,[467],{"type":39,"tag":317,"props":468,"children":469},{"style":340},[470],{"type":45,"value":471},"  },\n",{"type":39,"tag":317,"props":473,"children":475},{"class":319,"line":474},7,[476,481,485],{"type":39,"tag":317,"props":477,"children":478},{"style":340},[479],{"type":45,"value":480},"}",{"type":39,"tag":317,"props":482,"children":483},{"style":352},[484],{"type":45,"value":89},{"type":39,"tag":317,"props":486,"children":487},{"style":340},[488],{"type":45,"value":489},";\n",{"type":39,"tag":317,"props":491,"children":493},{"class":319,"line":492},8,[494],{"type":39,"tag":317,"props":495,"children":497},{"emptyLinePlaceholder":496},true,[498],{"type":45,"value":499},"\n",{"type":39,"tag":317,"props":501,"children":503},{"class":319,"line":502},9,[504],{"type":39,"tag":317,"props":505,"children":506},{"style":324},[507],{"type":45,"value":508},"\u002F\u002F Stale-while-revalidate (serve stale for 2 min while refreshing)\n",{"type":39,"tag":317,"props":510,"children":512},{"class":319,"line":511},10,[513,517,521,525,529,533],{"type":39,"tag":317,"props":514,"children":515},{"style":334},[516],{"type":45,"value":337},{"type":39,"tag":317,"props":518,"children":519},{"style":340},[520],{"type":45,"value":343},{"type":39,"tag":317,"props":522,"children":523},{"style":346},[524],{"type":45,"value":349},{"type":39,"tag":317,"props":526,"children":527},{"style":352},[528],{"type":45,"value":355},{"type":39,"tag":317,"props":530,"children":531},{"style":340},[532],{"type":45,"value":360},{"type":39,"tag":317,"props":534,"children":535},{"style":340},[536],{"type":45,"value":365},{"type":39,"tag":317,"props":538,"children":540},{"class":319,"line":539},11,[541,545,549],{"type":39,"tag":317,"props":542,"children":543},{"style":372},[544],{"type":45,"value":375},{"type":39,"tag":317,"props":546,"children":547},{"style":340},[548],{"type":45,"value":380},{"type":39,"tag":317,"props":550,"children":551},{"style":340},[552],{"type":45,"value":365},{"type":39,"tag":317,"props":554,"children":556},{"class":319,"line":555},12,[557,561,565,569,573,577,582,586],{"type":39,"tag":317,"props":558,"children":559},{"style":340},[560],{"type":45,"value":393},{"type":39,"tag":317,"props":562,"children":563},{"style":372},[564],{"type":45,"value":243},{"type":39,"tag":317,"props":566,"children":567},{"style":340},[568],{"type":45,"value":402},{"type":39,"tag":317,"props":570,"children":571},{"style":340},[572],{"type":45,"value":380},{"type":39,"tag":317,"props":574,"children":575},{"style":340},[576],{"type":45,"value":411},{"type":39,"tag":317,"props":578,"children":579},{"style":414},[580],{"type":45,"value":581},"public, max-age=60, stale-while-revalidate=120",{"type":39,"tag":317,"props":583,"children":584},{"style":340},[585],{"type":45,"value":402},{"type":39,"tag":317,"props":587,"children":588},{"style":340},[589],{"type":45,"value":426},{"type":39,"tag":317,"props":591,"children":593},{"class":319,"line":592},13,[594],{"type":39,"tag":317,"props":595,"children":596},{"style":340},[597],{"type":45,"value":471},{"type":39,"tag":317,"props":599,"children":601},{"class":319,"line":600},14,[602,606,610],{"type":39,"tag":317,"props":603,"children":604},{"style":340},[605],{"type":45,"value":480},{"type":39,"tag":317,"props":607,"children":608},{"style":352},[609],{"type":45,"value":89},{"type":39,"tag":317,"props":611,"children":612},{"style":340},[613],{"type":45,"value":489},{"type":39,"tag":317,"props":615,"children":617},{"class":319,"line":616},15,[618],{"type":39,"tag":317,"props":619,"children":620},{"emptyLinePlaceholder":496},[621],{"type":45,"value":499},{"type":39,"tag":317,"props":623,"children":625},{"class":319,"line":624},16,[626],{"type":39,"tag":317,"props":627,"children":628},{"style":324},[629],{"type":45,"value":630},"\u002F\u002F Durable cache (shared across edge nodes, serverless functions only)\n",{"type":39,"tag":317,"props":632,"children":634},{"class":319,"line":633},17,[635,639,643,647,651,655],{"type":39,"tag":317,"props":636,"children":637},{"style":334},[638],{"type":45,"value":337},{"type":39,"tag":317,"props":640,"children":641},{"style":340},[642],{"type":45,"value":343},{"type":39,"tag":317,"props":644,"children":645},{"style":346},[646],{"type":45,"value":349},{"type":39,"tag":317,"props":648,"children":649},{"style":352},[650],{"type":45,"value":355},{"type":39,"tag":317,"props":652,"children":653},{"style":340},[654],{"type":45,"value":360},{"type":39,"tag":317,"props":656,"children":657},{"style":340},[658],{"type":45,"value":365},{"type":39,"tag":317,"props":660,"children":662},{"class":319,"line":661},18,[663,667,671],{"type":39,"tag":317,"props":664,"children":665},{"style":372},[666],{"type":45,"value":375},{"type":39,"tag":317,"props":668,"children":669},{"style":340},[670],{"type":45,"value":380},{"type":39,"tag":317,"props":672,"children":673},{"style":340},[674],{"type":45,"value":365},{"type":39,"tag":317,"props":676,"children":678},{"class":319,"line":677},19,[679,683,687,691,695,699,704,708],{"type":39,"tag":317,"props":680,"children":681},{"style":340},[682],{"type":45,"value":393},{"type":39,"tag":317,"props":684,"children":685},{"style":372},[686],{"type":45,"value":243},{"type":39,"tag":317,"props":688,"children":689},{"style":340},[690],{"type":45,"value":402},{"type":39,"tag":317,"props":692,"children":693},{"style":340},[694],{"type":45,"value":380},{"type":39,"tag":317,"props":696,"children":697},{"style":340},[698],{"type":45,"value":411},{"type":39,"tag":317,"props":700,"children":701},{"style":414},[702],{"type":45,"value":703},"public, durable, max-age=60, stale-while-revalidate=120",{"type":39,"tag":317,"props":705,"children":706},{"style":340},[707],{"type":45,"value":402},{"type":39,"tag":317,"props":709,"children":710},{"style":340},[711],{"type":45,"value":426},{"type":39,"tag":317,"props":713,"children":715},{"class":319,"line":714},20,[716],{"type":39,"tag":317,"props":717,"children":718},{"style":340},[719],{"type":45,"value":471},{"type":39,"tag":317,"props":721,"children":723},{"class":319,"line":722},21,[724,728,732],{"type":39,"tag":317,"props":725,"children":726},{"style":340},[727],{"type":45,"value":480},{"type":39,"tag":317,"props":729,"children":730},{"style":352},[731],{"type":45,"value":89},{"type":39,"tag":317,"props":733,"children":734},{"style":340},[735],{"type":45,"value":489},{"type":39,"tag":299,"props":737,"children":739},{"id":738},"immutable-assets",[740],{"type":45,"value":741},"Immutable Assets",{"type":39,"tag":55,"props":743,"children":744},{},[745],{"type":45,"value":746},"For fingerprinted files (hash in filename):",{"type":39,"tag":306,"props":748,"children":752},{"className":749,"code":750,"language":751,"meta":311,"style":311},"language-toml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# netlify.toml\n[[headers]]\nfor = \"\u002Fassets\u002F*\"\n[headers.values]\nCache-Control = \"public, max-age=31536000, immutable\"\n","toml",[753],{"type":39,"tag":82,"props":754,"children":755},{"__ignoreMap":311},[756,764,772,780,788],{"type":39,"tag":317,"props":757,"children":758},{"class":319,"line":320},[759],{"type":39,"tag":317,"props":760,"children":761},{},[762],{"type":45,"value":763},"# netlify.toml\n",{"type":39,"tag":317,"props":765,"children":766},{"class":319,"line":330},[767],{"type":39,"tag":317,"props":768,"children":769},{},[770],{"type":45,"value":771},"[[headers]]\n",{"type":39,"tag":317,"props":773,"children":774},{"class":319,"line":368},[775],{"type":39,"tag":317,"props":776,"children":777},{},[778],{"type":45,"value":779},"for = \"\u002Fassets\u002F*\"\n",{"type":39,"tag":317,"props":781,"children":782},{"class":319,"line":387},[783],{"type":39,"tag":317,"props":784,"children":785},{},[786],{"type":45,"value":787},"[headers.values]\n",{"type":39,"tag":317,"props":789,"children":790},{"class":319,"line":27},[791],{"type":39,"tag":317,"props":792,"children":793},{},[794],{"type":45,"value":795},"Cache-Control = \"public, max-age=31536000, immutable\"\n",{"type":39,"tag":48,"props":797,"children":799},{"id":798},"cache-tags-and-on-demand-purge",[800],{"type":45,"value":801},"Cache Tags and On-Demand Purge",{"type":39,"tag":55,"props":803,"children":804},{},[805],{"type":45,"value":806},"Tag responses for selective cache invalidation:",{"type":39,"tag":306,"props":808,"children":810},{"className":308,"code":809,"language":310,"meta":311,"style":311},"return new Response(body, {\n  headers: {\n    \"Netlify-Cache-Tag\": \"product,listing\",\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=86400\",\n  },\n});\n",[811],{"type":39,"tag":82,"props":812,"children":813},{"__ignoreMap":311},[814,841,856,893,929,936],{"type":39,"tag":317,"props":815,"children":816},{"class":319,"line":320},[817,821,825,829,833,837],{"type":39,"tag":317,"props":818,"children":819},{"style":334},[820],{"type":45,"value":337},{"type":39,"tag":317,"props":822,"children":823},{"style":340},[824],{"type":45,"value":343},{"type":39,"tag":317,"props":826,"children":827},{"style":346},[828],{"type":45,"value":349},{"type":39,"tag":317,"props":830,"children":831},{"style":352},[832],{"type":45,"value":355},{"type":39,"tag":317,"props":834,"children":835},{"style":340},[836],{"type":45,"value":360},{"type":39,"tag":317,"props":838,"children":839},{"style":340},[840],{"type":45,"value":365},{"type":39,"tag":317,"props":842,"children":843},{"class":319,"line":330},[844,848,852],{"type":39,"tag":317,"props":845,"children":846},{"style":372},[847],{"type":45,"value":375},{"type":39,"tag":317,"props":849,"children":850},{"style":340},[851],{"type":45,"value":380},{"type":39,"tag":317,"props":853,"children":854},{"style":340},[855],{"type":45,"value":365},{"type":39,"tag":317,"props":857,"children":858},{"class":319,"line":368},[859,863,868,872,876,880,885,889],{"type":39,"tag":317,"props":860,"children":861},{"style":340},[862],{"type":45,"value":393},{"type":39,"tag":317,"props":864,"children":865},{"style":372},[866],{"type":45,"value":867},"Netlify-Cache-Tag",{"type":39,"tag":317,"props":869,"children":870},{"style":340},[871],{"type":45,"value":402},{"type":39,"tag":317,"props":873,"children":874},{"style":340},[875],{"type":45,"value":380},{"type":39,"tag":317,"props":877,"children":878},{"style":340},[879],{"type":45,"value":411},{"type":39,"tag":317,"props":881,"children":882},{"style":414},[883],{"type":45,"value":884},"product,listing",{"type":39,"tag":317,"props":886,"children":887},{"style":340},[888],{"type":45,"value":402},{"type":39,"tag":317,"props":890,"children":891},{"style":340},[892],{"type":45,"value":426},{"type":39,"tag":317,"props":894,"children":895},{"class":319,"line":387},[896,900,904,908,912,916,921,925],{"type":39,"tag":317,"props":897,"children":898},{"style":340},[899],{"type":45,"value":393},{"type":39,"tag":317,"props":901,"children":902},{"style":372},[903],{"type":45,"value":243},{"type":39,"tag":317,"props":905,"children":906},{"style":340},[907],{"type":45,"value":402},{"type":39,"tag":317,"props":909,"children":910},{"style":340},[911],{"type":45,"value":380},{"type":39,"tag":317,"props":913,"children":914},{"style":340},[915],{"type":45,"value":411},{"type":39,"tag":317,"props":917,"children":918},{"style":414},[919],{"type":45,"value":920},"public, s-maxage=86400",{"type":39,"tag":317,"props":922,"children":923},{"style":340},[924],{"type":45,"value":402},{"type":39,"tag":317,"props":926,"children":927},{"style":340},[928],{"type":45,"value":426},{"type":39,"tag":317,"props":930,"children":931},{"class":319,"line":27},[932],{"type":39,"tag":317,"props":933,"children":934},{"style":340},[935],{"type":45,"value":471},{"type":39,"tag":317,"props":937,"children":938},{"class":319,"line":465},[939,943,947],{"type":39,"tag":317,"props":940,"children":941},{"style":340},[942],{"type":45,"value":480},{"type":39,"tag":317,"props":944,"children":945},{"style":352},[946],{"type":45,"value":89},{"type":39,"tag":317,"props":948,"children":949},{"style":340},[950],{"type":45,"value":489},{"type":39,"tag":55,"props":952,"children":953},{},[954],{"type":45,"value":955},"Purge by tag:",{"type":39,"tag":306,"props":957,"children":959},{"className":308,"code":958,"language":310,"meta":311,"style":311},"import { purgeCache } from \"@netlify\u002Ffunctions\";\n\nexport default async () => {\n  await purgeCache({ tags: [\"product\"] });\n  return new Response(\"Purged\", { status: 202 });\n};\n",[960],{"type":39,"tag":82,"props":961,"children":962},{"__ignoreMap":311},[963,1008,1015,1048,1114,1182],{"type":39,"tag":317,"props":964,"children":965},{"class":319,"line":320},[966,971,976,981,986,991,995,1000,1004],{"type":39,"tag":317,"props":967,"children":968},{"style":334},[969],{"type":45,"value":970},"import",{"type":39,"tag":317,"props":972,"children":973},{"style":340},[974],{"type":45,"value":975}," {",{"type":39,"tag":317,"props":977,"children":978},{"style":352},[979],{"type":45,"value":980}," purgeCache",{"type":39,"tag":317,"props":982,"children":983},{"style":340},[984],{"type":45,"value":985}," }",{"type":39,"tag":317,"props":987,"children":988},{"style":334},[989],{"type":45,"value":990}," from",{"type":39,"tag":317,"props":992,"children":993},{"style":340},[994],{"type":45,"value":411},{"type":39,"tag":317,"props":996,"children":997},{"style":414},[998],{"type":45,"value":999},"@netlify\u002Ffunctions",{"type":39,"tag":317,"props":1001,"children":1002},{"style":340},[1003],{"type":45,"value":402},{"type":39,"tag":317,"props":1005,"children":1006},{"style":340},[1007],{"type":45,"value":489},{"type":39,"tag":317,"props":1009,"children":1010},{"class":319,"line":330},[1011],{"type":39,"tag":317,"props":1012,"children":1013},{"emptyLinePlaceholder":496},[1014],{"type":45,"value":499},{"type":39,"tag":317,"props":1016,"children":1017},{"class":319,"line":368},[1018,1023,1028,1034,1039,1044],{"type":39,"tag":317,"props":1019,"children":1020},{"style":334},[1021],{"type":45,"value":1022},"export",{"type":39,"tag":317,"props":1024,"children":1025},{"style":334},[1026],{"type":45,"value":1027}," default",{"type":39,"tag":317,"props":1029,"children":1031},{"style":1030},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1032],{"type":45,"value":1033}," async",{"type":39,"tag":317,"props":1035,"children":1036},{"style":340},[1037],{"type":45,"value":1038}," ()",{"type":39,"tag":317,"props":1040,"children":1041},{"style":1030},[1042],{"type":45,"value":1043}," =>",{"type":39,"tag":317,"props":1045,"children":1046},{"style":340},[1047],{"type":45,"value":365},{"type":39,"tag":317,"props":1049,"children":1050},{"class":319,"line":387},[1051,1056,1060,1065,1070,1075,1079,1084,1088,1093,1097,1102,1106,1110],{"type":39,"tag":317,"props":1052,"children":1053},{"style":334},[1054],{"type":45,"value":1055},"  await",{"type":39,"tag":317,"props":1057,"children":1058},{"style":346},[1059],{"type":45,"value":980},{"type":39,"tag":317,"props":1061,"children":1062},{"style":372},[1063],{"type":45,"value":1064},"(",{"type":39,"tag":317,"props":1066,"children":1067},{"style":340},[1068],{"type":45,"value":1069},"{",{"type":39,"tag":317,"props":1071,"children":1072},{"style":372},[1073],{"type":45,"value":1074}," tags",{"type":39,"tag":317,"props":1076,"children":1077},{"style":340},[1078],{"type":45,"value":380},{"type":39,"tag":317,"props":1080,"children":1081},{"style":372},[1082],{"type":45,"value":1083}," [",{"type":39,"tag":317,"props":1085,"children":1086},{"style":340},[1087],{"type":45,"value":402},{"type":39,"tag":317,"props":1089,"children":1090},{"style":414},[1091],{"type":45,"value":1092},"product",{"type":39,"tag":317,"props":1094,"children":1095},{"style":340},[1096],{"type":45,"value":402},{"type":39,"tag":317,"props":1098,"children":1099},{"style":372},[1100],{"type":45,"value":1101},"] ",{"type":39,"tag":317,"props":1103,"children":1104},{"style":340},[1105],{"type":45,"value":480},{"type":39,"tag":317,"props":1107,"children":1108},{"style":372},[1109],{"type":45,"value":89},{"type":39,"tag":317,"props":1111,"children":1112},{"style":340},[1113],{"type":45,"value":489},{"type":39,"tag":317,"props":1115,"children":1116},{"class":319,"line":27},[1117,1122,1126,1130,1134,1138,1143,1147,1151,1155,1160,1164,1170,1174,1178],{"type":39,"tag":317,"props":1118,"children":1119},{"style":334},[1120],{"type":45,"value":1121},"  return",{"type":39,"tag":317,"props":1123,"children":1124},{"style":340},[1125],{"type":45,"value":343},{"type":39,"tag":317,"props":1127,"children":1128},{"style":346},[1129],{"type":45,"value":349},{"type":39,"tag":317,"props":1131,"children":1132},{"style":372},[1133],{"type":45,"value":1064},{"type":39,"tag":317,"props":1135,"children":1136},{"style":340},[1137],{"type":45,"value":402},{"type":39,"tag":317,"props":1139,"children":1140},{"style":414},[1141],{"type":45,"value":1142},"Purged",{"type":39,"tag":317,"props":1144,"children":1145},{"style":340},[1146],{"type":45,"value":402},{"type":39,"tag":317,"props":1148,"children":1149},{"style":340},[1150],{"type":45,"value":360},{"type":39,"tag":317,"props":1152,"children":1153},{"style":340},[1154],{"type":45,"value":975},{"type":39,"tag":317,"props":1156,"children":1157},{"style":372},[1158],{"type":45,"value":1159}," status",{"type":39,"tag":317,"props":1161,"children":1162},{"style":340},[1163],{"type":45,"value":380},{"type":39,"tag":317,"props":1165,"children":1167},{"style":1166},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[1168],{"type":45,"value":1169}," 202",{"type":39,"tag":317,"props":1171,"children":1172},{"style":340},[1173],{"type":45,"value":985},{"type":39,"tag":317,"props":1175,"children":1176},{"style":372},[1177],{"type":45,"value":89},{"type":39,"tag":317,"props":1179,"children":1180},{"style":340},[1181],{"type":45,"value":489},{"type":39,"tag":317,"props":1183,"children":1184},{"class":319,"line":465},[1185],{"type":39,"tag":317,"props":1186,"children":1187},{"style":340},[1188],{"type":45,"value":1189},"};\n",{"type":39,"tag":55,"props":1191,"children":1192},{},[1193],{"type":45,"value":1194},"Purge entire site:",{"type":39,"tag":306,"props":1196,"children":1198},{"className":308,"code":1197,"language":310,"meta":311,"style":311},"await purgeCache();\n",[1199],{"type":39,"tag":82,"props":1200,"children":1201},{"__ignoreMap":311},[1202],{"type":39,"tag":317,"props":1203,"children":1204},{"class":319,"line":320},[1205,1210,1214,1219],{"type":39,"tag":317,"props":1206,"children":1207},{"style":334},[1208],{"type":45,"value":1209},"await",{"type":39,"tag":317,"props":1211,"children":1212},{"style":346},[1213],{"type":45,"value":980},{"type":39,"tag":317,"props":1215,"children":1216},{"style":352},[1217],{"type":45,"value":1218},"()",{"type":39,"tag":317,"props":1220,"children":1221},{"style":340},[1222],{"type":45,"value":489},{"type":39,"tag":55,"props":1224,"children":1225},{},[1226,1232,1234,1239],{"type":39,"tag":82,"props":1227,"children":1229},{"className":1228},[],[1230],{"type":45,"value":1231},"purgeCache()",{"type":45,"value":1233}," picks up the site ID and credentials automatically ",{"type":39,"tag":59,"props":1235,"children":1236},{},[1237],{"type":45,"value":1238},"only when it runs inside a deployed Netlify Function",{"type":45,"value":1240},". Called from anywhere else — a local script, a CI job, a build step, or any code outside the Netlify Functions runtime — it has no ambient credentials, and you must pass a Netlify personal access token (and the site ID). Read the token from an environment variable; never hardcode it:",{"type":39,"tag":306,"props":1242,"children":1244},{"className":308,"code":1243,"language":310,"meta":311,"style":311},"await purgeCache({\n  token: process.env.NETLIFY_PURGE_TOKEN, \u002F\u002F a Netlify personal access token, from env\n  siteID: process.env.NETLIFY_SITE_ID,\n  tags: [\"product\"],\n});\n",[1245],{"type":39,"tag":82,"props":1246,"children":1247},{"__ignoreMap":311},[1248,1268,1313,1350,1387],{"type":39,"tag":317,"props":1249,"children":1250},{"class":319,"line":320},[1251,1255,1259,1263],{"type":39,"tag":317,"props":1252,"children":1253},{"style":334},[1254],{"type":45,"value":1209},{"type":39,"tag":317,"props":1256,"children":1257},{"style":346},[1258],{"type":45,"value":980},{"type":39,"tag":317,"props":1260,"children":1261},{"style":352},[1262],{"type":45,"value":1064},{"type":39,"tag":317,"props":1264,"children":1265},{"style":340},[1266],{"type":45,"value":1267},"{\n",{"type":39,"tag":317,"props":1269,"children":1270},{"class":319,"line":330},[1271,1276,1280,1285,1290,1295,1299,1304,1308],{"type":39,"tag":317,"props":1272,"children":1273},{"style":372},[1274],{"type":45,"value":1275},"  token",{"type":39,"tag":317,"props":1277,"children":1278},{"style":340},[1279],{"type":45,"value":380},{"type":39,"tag":317,"props":1281,"children":1282},{"style":352},[1283],{"type":45,"value":1284}," process",{"type":39,"tag":317,"props":1286,"children":1287},{"style":340},[1288],{"type":45,"value":1289},".",{"type":39,"tag":317,"props":1291,"children":1292},{"style":352},[1293],{"type":45,"value":1294},"env",{"type":39,"tag":317,"props":1296,"children":1297},{"style":340},[1298],{"type":45,"value":1289},{"type":39,"tag":317,"props":1300,"children":1301},{"style":352},[1302],{"type":45,"value":1303},"NETLIFY_PURGE_TOKEN",{"type":39,"tag":317,"props":1305,"children":1306},{"style":340},[1307],{"type":45,"value":360},{"type":39,"tag":317,"props":1309,"children":1310},{"style":324},[1311],{"type":45,"value":1312}," \u002F\u002F a Netlify personal access token, from env\n",{"type":39,"tag":317,"props":1314,"children":1315},{"class":319,"line":368},[1316,1321,1325,1329,1333,1337,1341,1346],{"type":39,"tag":317,"props":1317,"children":1318},{"style":372},[1319],{"type":45,"value":1320},"  siteID",{"type":39,"tag":317,"props":1322,"children":1323},{"style":340},[1324],{"type":45,"value":380},{"type":39,"tag":317,"props":1326,"children":1327},{"style":352},[1328],{"type":45,"value":1284},{"type":39,"tag":317,"props":1330,"children":1331},{"style":340},[1332],{"type":45,"value":1289},{"type":39,"tag":317,"props":1334,"children":1335},{"style":352},[1336],{"type":45,"value":1294},{"type":39,"tag":317,"props":1338,"children":1339},{"style":340},[1340],{"type":45,"value":1289},{"type":39,"tag":317,"props":1342,"children":1343},{"style":352},[1344],{"type":45,"value":1345},"NETLIFY_SITE_ID",{"type":39,"tag":317,"props":1347,"children":1348},{"style":340},[1349],{"type":45,"value":426},{"type":39,"tag":317,"props":1351,"children":1352},{"class":319,"line":387},[1353,1358,1362,1366,1370,1374,1378,1383],{"type":39,"tag":317,"props":1354,"children":1355},{"style":372},[1356],{"type":45,"value":1357},"  tags",{"type":39,"tag":317,"props":1359,"children":1360},{"style":340},[1361],{"type":45,"value":380},{"type":39,"tag":317,"props":1363,"children":1364},{"style":352},[1365],{"type":45,"value":1083},{"type":39,"tag":317,"props":1367,"children":1368},{"style":340},[1369],{"type":45,"value":402},{"type":39,"tag":317,"props":1371,"children":1372},{"style":414},[1373],{"type":45,"value":1092},{"type":39,"tag":317,"props":1375,"children":1376},{"style":340},[1377],{"type":45,"value":402},{"type":39,"tag":317,"props":1379,"children":1380},{"style":352},[1381],{"type":45,"value":1382},"]",{"type":39,"tag":317,"props":1384,"children":1385},{"style":340},[1386],{"type":45,"value":426},{"type":39,"tag":317,"props":1388,"children":1389},{"class":319,"line":27},[1390,1394,1398],{"type":39,"tag":317,"props":1391,"children":1392},{"style":340},[1393],{"type":45,"value":480},{"type":39,"tag":317,"props":1395,"children":1396},{"style":352},[1397],{"type":45,"value":89},{"type":39,"tag":317,"props":1399,"children":1400},{"style":340},[1401],{"type":45,"value":489},{"type":39,"tag":55,"props":1403,"children":1404},{},[1405,1410,1412,1417],{"type":39,"tag":82,"props":1406,"children":1408},{"className":1407},[],[1409],{"type":45,"value":867},{"type":45,"value":1411}," is ",{"type":39,"tag":59,"props":1413,"children":1414},{},[1415],{"type":45,"value":1416},"purge-only",{"type":45,"value":1418},": tagged responses are still cleared by automatic deploy-based invalidation like everything else. The tag only lets you purge them on demand between deploys.",{"type":39,"tag":299,"props":1420,"children":1422},{"id":1421},"surviving-deploys-with-netlify-cache-id",[1423,1425],{"type":45,"value":1424},"Surviving deploys with ",{"type":39,"tag":82,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":45,"value":1430},"Netlify-Cache-ID",{"type":39,"tag":55,"props":1432,"children":1433},{},[1434,1436,1442,1444,1449,1451,1456,1458,1463],{"type":45,"value":1435},"To keep a cached response ",{"type":39,"tag":1437,"props":1438,"children":1439},"em",{},[1440],{"type":45,"value":1441},"across",{"type":45,"value":1443}," deploys, set a ",{"type":39,"tag":82,"props":1445,"children":1447},{"className":1446},[],[1448],{"type":45,"value":1430},{"type":45,"value":1450}," header. A response carrying it is ",{"type":39,"tag":59,"props":1452,"children":1453},{},[1454],{"type":45,"value":1455},"excluded from automatic deploy-based invalidation",{"type":45,"value":1457}," — it persists across deploys and clears only on explicit purge. The ",{"type":39,"tag":82,"props":1459,"children":1461},{"className":1460},[],[1462],{"type":45,"value":1430},{"type":45,"value":1464}," value also auto-registers as a purge tag, so you purge it by that same id:",{"type":39,"tag":306,"props":1466,"children":1468},{"className":308,"code":1467,"language":310,"meta":311,"style":311},"return new Response(body, {\n  headers: {\n    \"Netlify-Cache-ID\": \"catalog\",\n    \"Netlify-CDN-Cache-Control\": \"public, s-maxage=86400\",\n  },\n});\n",[1469],{"type":39,"tag":82,"props":1470,"children":1471},{"__ignoreMap":311},[1472,1499,1514,1550,1585,1592],{"type":39,"tag":317,"props":1473,"children":1474},{"class":319,"line":320},[1475,1479,1483,1487,1491,1495],{"type":39,"tag":317,"props":1476,"children":1477},{"style":334},[1478],{"type":45,"value":337},{"type":39,"tag":317,"props":1480,"children":1481},{"style":340},[1482],{"type":45,"value":343},{"type":39,"tag":317,"props":1484,"children":1485},{"style":346},[1486],{"type":45,"value":349},{"type":39,"tag":317,"props":1488,"children":1489},{"style":352},[1490],{"type":45,"value":355},{"type":39,"tag":317,"props":1492,"children":1493},{"style":340},[1494],{"type":45,"value":360},{"type":39,"tag":317,"props":1496,"children":1497},{"style":340},[1498],{"type":45,"value":365},{"type":39,"tag":317,"props":1500,"children":1501},{"class":319,"line":330},[1502,1506,1510],{"type":39,"tag":317,"props":1503,"children":1504},{"style":372},[1505],{"type":45,"value":375},{"type":39,"tag":317,"props":1507,"children":1508},{"style":340},[1509],{"type":45,"value":380},{"type":39,"tag":317,"props":1511,"children":1512},{"style":340},[1513],{"type":45,"value":365},{"type":39,"tag":317,"props":1515,"children":1516},{"class":319,"line":368},[1517,1521,1525,1529,1533,1537,1542,1546],{"type":39,"tag":317,"props":1518,"children":1519},{"style":340},[1520],{"type":45,"value":393},{"type":39,"tag":317,"props":1522,"children":1523},{"style":372},[1524],{"type":45,"value":1430},{"type":39,"tag":317,"props":1526,"children":1527},{"style":340},[1528],{"type":45,"value":402},{"type":39,"tag":317,"props":1530,"children":1531},{"style":340},[1532],{"type":45,"value":380},{"type":39,"tag":317,"props":1534,"children":1535},{"style":340},[1536],{"type":45,"value":411},{"type":39,"tag":317,"props":1538,"children":1539},{"style":414},[1540],{"type":45,"value":1541},"catalog",{"type":39,"tag":317,"props":1543,"children":1544},{"style":340},[1545],{"type":45,"value":402},{"type":39,"tag":317,"props":1547,"children":1548},{"style":340},[1549],{"type":45,"value":426},{"type":39,"tag":317,"props":1551,"children":1552},{"class":319,"line":387},[1553,1557,1561,1565,1569,1573,1577,1581],{"type":39,"tag":317,"props":1554,"children":1555},{"style":340},[1556],{"type":45,"value":393},{"type":39,"tag":317,"props":1558,"children":1559},{"style":372},[1560],{"type":45,"value":243},{"type":39,"tag":317,"props":1562,"children":1563},{"style":340},[1564],{"type":45,"value":402},{"type":39,"tag":317,"props":1566,"children":1567},{"style":340},[1568],{"type":45,"value":380},{"type":39,"tag":317,"props":1570,"children":1571},{"style":340},[1572],{"type":45,"value":411},{"type":39,"tag":317,"props":1574,"children":1575},{"style":414},[1576],{"type":45,"value":920},{"type":39,"tag":317,"props":1578,"children":1579},{"style":340},[1580],{"type":45,"value":402},{"type":39,"tag":317,"props":1582,"children":1583},{"style":340},[1584],{"type":45,"value":426},{"type":39,"tag":317,"props":1586,"children":1587},{"class":319,"line":27},[1588],{"type":39,"tag":317,"props":1589,"children":1590},{"style":340},[1591],{"type":45,"value":471},{"type":39,"tag":317,"props":1593,"children":1594},{"class":319,"line":465},[1595,1599,1603],{"type":39,"tag":317,"props":1596,"children":1597},{"style":340},[1598],{"type":45,"value":480},{"type":39,"tag":317,"props":1600,"children":1601},{"style":352},[1602],{"type":45,"value":89},{"type":39,"tag":317,"props":1604,"children":1605},{"style":340},[1606],{"type":45,"value":489},{"type":39,"tag":306,"props":1608,"children":1610},{"className":308,"code":1609,"language":310,"meta":311,"style":311},"import { purgeCache } from \"@netlify\u002Ffunctions\";\n\n\u002F\u002F Purge by the same id — it doubles as a purge tag.\nawait purgeCache({ tags: [\"catalog\"] });\n",[1611],{"type":39,"tag":82,"props":1612,"children":1613},{"__ignoreMap":311},[1614,1653,1660,1668],{"type":39,"tag":317,"props":1615,"children":1616},{"class":319,"line":320},[1617,1621,1625,1629,1633,1637,1641,1645,1649],{"type":39,"tag":317,"props":1618,"children":1619},{"style":334},[1620],{"type":45,"value":970},{"type":39,"tag":317,"props":1622,"children":1623},{"style":340},[1624],{"type":45,"value":975},{"type":39,"tag":317,"props":1626,"children":1627},{"style":352},[1628],{"type":45,"value":980},{"type":39,"tag":317,"props":1630,"children":1631},{"style":340},[1632],{"type":45,"value":985},{"type":39,"tag":317,"props":1634,"children":1635},{"style":334},[1636],{"type":45,"value":990},{"type":39,"tag":317,"props":1638,"children":1639},{"style":340},[1640],{"type":45,"value":411},{"type":39,"tag":317,"props":1642,"children":1643},{"style":414},[1644],{"type":45,"value":999},{"type":39,"tag":317,"props":1646,"children":1647},{"style":340},[1648],{"type":45,"value":402},{"type":39,"tag":317,"props":1650,"children":1651},{"style":340},[1652],{"type":45,"value":489},{"type":39,"tag":317,"props":1654,"children":1655},{"class":319,"line":330},[1656],{"type":39,"tag":317,"props":1657,"children":1658},{"emptyLinePlaceholder":496},[1659],{"type":45,"value":499},{"type":39,"tag":317,"props":1661,"children":1662},{"class":319,"line":368},[1663],{"type":39,"tag":317,"props":1664,"children":1665},{"style":324},[1666],{"type":45,"value":1667},"\u002F\u002F Purge by the same id — it doubles as a purge tag.\n",{"type":39,"tag":317,"props":1669,"children":1670},{"class":319,"line":387},[1671,1675,1679,1683,1687,1691,1695,1699,1703,1707,1711,1715,1719,1723],{"type":39,"tag":317,"props":1672,"children":1673},{"style":334},[1674],{"type":45,"value":1209},{"type":39,"tag":317,"props":1676,"children":1677},{"style":346},[1678],{"type":45,"value":980},{"type":39,"tag":317,"props":1680,"children":1681},{"style":352},[1682],{"type":45,"value":1064},{"type":39,"tag":317,"props":1684,"children":1685},{"style":340},[1686],{"type":45,"value":1069},{"type":39,"tag":317,"props":1688,"children":1689},{"style":372},[1690],{"type":45,"value":1074},{"type":39,"tag":317,"props":1692,"children":1693},{"style":340},[1694],{"type":45,"value":380},{"type":39,"tag":317,"props":1696,"children":1697},{"style":352},[1698],{"type":45,"value":1083},{"type":39,"tag":317,"props":1700,"children":1701},{"style":340},[1702],{"type":45,"value":402},{"type":39,"tag":317,"props":1704,"children":1705},{"style":414},[1706],{"type":45,"value":1541},{"type":39,"tag":317,"props":1708,"children":1709},{"style":340},[1710],{"type":45,"value":402},{"type":39,"tag":317,"props":1712,"children":1713},{"style":352},[1714],{"type":45,"value":1101},{"type":39,"tag":317,"props":1716,"children":1717},{"style":340},[1718],{"type":45,"value":480},{"type":39,"tag":317,"props":1720,"children":1721},{"style":352},[1722],{"type":45,"value":89},{"type":39,"tag":317,"props":1724,"children":1725},{"style":340},[1726],{"type":45,"value":489},{"type":39,"tag":48,"props":1728,"children":1730},{"id":1729},"cache-key-variation",[1731],{"type":45,"value":1732},"Cache Key Variation",{"type":39,"tag":55,"props":1734,"children":1735},{},[1736,1742,1744,1750,1751,1757,1758,1764,1765,1771,1773,1779],{"type":39,"tag":82,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":45,"value":1741},"Netlify-Vary",{"type":45,"value":1743}," controls what creates separate cache entries. Each directive names a dimension — ",{"type":39,"tag":82,"props":1745,"children":1747},{"className":1746},[],[1748],{"type":45,"value":1749},"query",{"type":45,"value":144},{"type":39,"tag":82,"props":1752,"children":1754},{"className":1753},[],[1755],{"type":45,"value":1756},"header",{"type":45,"value":144},{"type":39,"tag":82,"props":1759,"children":1761},{"className":1760},[],[1762],{"type":45,"value":1763},"cookie",{"type":45,"value":144},{"type":39,"tag":82,"props":1766,"children":1768},{"className":1767},[],[1769],{"type":45,"value":1770},"country",{"type":45,"value":1772},", or ",{"type":39,"tag":82,"props":1774,"children":1776},{"className":1775},[],[1777],{"type":45,"value":1778},"language",{"type":45,"value":1780}," — followed by an enumerated, pipe-separated list of the values to key on:",{"type":39,"tag":306,"props":1782,"children":1784},{"className":308,"code":1783,"language":310,"meta":311,"style":311},"return new Response(body, {\n  headers: {\n    \"Netlify-Vary\": \"cookie=ab_test|is_logged_in\",\n  },\n});\n",[1785],{"type":39,"tag":82,"props":1786,"children":1787},{"__ignoreMap":311},[1788,1815,1830,1866,1873],{"type":39,"tag":317,"props":1789,"children":1790},{"class":319,"line":320},[1791,1795,1799,1803,1807,1811],{"type":39,"tag":317,"props":1792,"children":1793},{"style":334},[1794],{"type":45,"value":337},{"type":39,"tag":317,"props":1796,"children":1797},{"style":340},[1798],{"type":45,"value":343},{"type":39,"tag":317,"props":1800,"children":1801},{"style":346},[1802],{"type":45,"value":349},{"type":39,"tag":317,"props":1804,"children":1805},{"style":352},[1806],{"type":45,"value":355},{"type":39,"tag":317,"props":1808,"children":1809},{"style":340},[1810],{"type":45,"value":360},{"type":39,"tag":317,"props":1812,"children":1813},{"style":340},[1814],{"type":45,"value":365},{"type":39,"tag":317,"props":1816,"children":1817},{"class":319,"line":330},[1818,1822,1826],{"type":39,"tag":317,"props":1819,"children":1820},{"style":372},[1821],{"type":45,"value":375},{"type":39,"tag":317,"props":1823,"children":1824},{"style":340},[1825],{"type":45,"value":380},{"type":39,"tag":317,"props":1827,"children":1828},{"style":340},[1829],{"type":45,"value":365},{"type":39,"tag":317,"props":1831,"children":1832},{"class":319,"line":368},[1833,1837,1841,1845,1849,1853,1858,1862],{"type":39,"tag":317,"props":1834,"children":1835},{"style":340},[1836],{"type":45,"value":393},{"type":39,"tag":317,"props":1838,"children":1839},{"style":372},[1840],{"type":45,"value":1741},{"type":39,"tag":317,"props":1842,"children":1843},{"style":340},[1844],{"type":45,"value":402},{"type":39,"tag":317,"props":1846,"children":1847},{"style":340},[1848],{"type":45,"value":380},{"type":39,"tag":317,"props":1850,"children":1851},{"style":340},[1852],{"type":45,"value":411},{"type":39,"tag":317,"props":1854,"children":1855},{"style":414},[1856],{"type":45,"value":1857},"cookie=ab_test|is_logged_in",{"type":39,"tag":317,"props":1859,"children":1860},{"style":340},[1861],{"type":45,"value":402},{"type":39,"tag":317,"props":1863,"children":1864},{"style":340},[1865],{"type":45,"value":426},{"type":39,"tag":317,"props":1867,"children":1868},{"class":319,"line":387},[1869],{"type":39,"tag":317,"props":1870,"children":1871},{"style":340},[1872],{"type":45,"value":471},{"type":39,"tag":317,"props":1874,"children":1875},{"class":319,"line":27},[1876,1880,1884],{"type":39,"tag":317,"props":1877,"children":1878},{"style":340},[1879],{"type":45,"value":480},{"type":39,"tag":317,"props":1881,"children":1882},{"style":352},[1883],{"type":45,"value":89},{"type":39,"tag":317,"props":1885,"children":1886},{"style":340},[1887],{"type":45,"value":489},{"type":39,"tag":67,"props":1889,"children":1890},{},[1891,1902,1913,1923,1934],{"type":39,"tag":71,"props":1892,"children":1893},{},[1894,1900],{"type":39,"tag":82,"props":1895,"children":1897},{"className":1896},[],[1898],{"type":45,"value":1899},"query=param1|param2",{"type":45,"value":1901}," — key on the named query parameters",{"type":39,"tag":71,"props":1903,"children":1904},{},[1905,1911],{"type":39,"tag":82,"props":1906,"children":1908},{"className":1907},[],[1909],{"type":45,"value":1910},"header=X-Custom",{"type":45,"value":1912}," — key on the named request header",{"type":39,"tag":71,"props":1914,"children":1915},{},[1916,1921],{"type":39,"tag":82,"props":1917,"children":1919},{"className":1918},[],[1920],{"type":45,"value":1857},{"type":45,"value":1922}," — key on the named cookies",{"type":39,"tag":71,"props":1924,"children":1925},{},[1926,1932],{"type":39,"tag":82,"props":1927,"children":1929},{"className":1928},[],[1930],{"type":45,"value":1931},"country=us|de",{"type":45,"value":1933}," — serve a distinct cached entry to visitors from the listed countries (two-letter, lowercase ISO country codes)",{"type":39,"tag":71,"props":1935,"children":1936},{},[1937,1943,1945,1951],{"type":39,"tag":82,"props":1938,"children":1940},{"className":1939},[],[1941],{"type":45,"value":1942},"language=en|fr",{"type":45,"value":1944}," — key on the listed ",{"type":39,"tag":82,"props":1946,"children":1948},{"className":1947},[],[1949],{"type":45,"value":1950},"Accept-Language",{"type":45,"value":1952}," values",{"type":39,"tag":55,"props":1954,"children":1955},{},[1956,1958,1964,1966,1972,1974,1980,1982,1988],{"type":45,"value":1957},"Combine dimensions by separating directives with commas — e.g. ",{"type":39,"tag":82,"props":1959,"children":1961},{"className":1960},[],[1962],{"type":45,"value":1963},"Netlify-Vary: query=theme, cookie=plan",{"type":45,"value":1965}," keys the cache on both the ",{"type":39,"tag":82,"props":1967,"children":1969},{"className":1968},[],[1970],{"type":45,"value":1971},"theme",{"type":45,"value":1973}," query parameter and the ",{"type":39,"tag":82,"props":1975,"children":1977},{"className":1976},[],[1978],{"type":45,"value":1979},"plan",{"type":45,"value":1981}," cookie. Always enumerate the specific values; keying on an entire dimension (for example a bare ",{"type":39,"tag":82,"props":1983,"children":1985},{"className":1984},[],[1986],{"type":45,"value":1987},"Vary: Cookie",{"type":45,"value":1989},") fragments the cache into a separate entry per unique visitor.",{"type":39,"tag":48,"props":1991,"children":1993},{"id":1992},"framework-specific-caching",[1994],{"type":45,"value":1995},"Framework-Specific Caching",{"type":39,"tag":299,"props":1997,"children":1999},{"id":1998},"nextjs",[2000],{"type":45,"value":2001},"Next.js",{"type":39,"tag":55,"props":2003,"children":2004},{},[2005,2007,2013,2015,2021],{"type":45,"value":2006},"ISR uses Netlify's durable cache automatically (runtime 5.5.0+). ",{"type":39,"tag":82,"props":2008,"children":2010},{"className":2009},[],[2011],{"type":45,"value":2012},"revalidatePath",{"type":45,"value":2014}," and ",{"type":39,"tag":82,"props":2016,"children":2018},{"className":2017},[],[2019],{"type":45,"value":2020},"revalidateTag",{"type":45,"value":2022}," trigger cache purge.",{"type":39,"tag":299,"props":2024,"children":2026},{"id":2025},"astro-remix",[2027],{"type":45,"value":2028},"Astro \u002F Remix",{"type":39,"tag":55,"props":2030,"children":2031},{},[2032,2034,2039],{"type":45,"value":2033},"Full control over cache headers in server routes. Set ",{"type":39,"tag":82,"props":2035,"children":2037},{"className":2036},[],[2038],{"type":45,"value":243},{"type":45,"value":2040}," in responses for CDN caching.",{"type":39,"tag":299,"props":2042,"children":2044},{"id":2043},"nuxt",[2045],{"type":45,"value":2046},"Nuxt",{"type":39,"tag":55,"props":2048,"children":2049},{},[2050,2052,2058,2060,2066,2068,2074],{"type":45,"value":2051},"Default Nitro preset handles caching. ISR-style patterns use ",{"type":39,"tag":82,"props":2053,"children":2055},{"className":2054},[],[2056],{"type":45,"value":2057},"routeRules",{"type":45,"value":2059}," with ",{"type":39,"tag":82,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":45,"value":2065},"swr",{"type":45,"value":2067}," or ",{"type":39,"tag":82,"props":2069,"children":2071},{"className":2070},[],[2072],{"type":45,"value":2073},"isr",{"type":45,"value":2075}," options.",{"type":39,"tag":299,"props":2077,"children":2079},{"id":2078},"vite-spa",[2080],{"type":45,"value":2081},"Vite SPA",{"type":39,"tag":55,"props":2083,"children":2084},{},[2085],{"type":45,"value":2086},"Static assets are cached by default. API responses from Netlify Functions need explicit cache headers.",{"type":39,"tag":55,"props":2088,"children":2089},{},[2090,2095,2097,2103,2105,2111,2112,2118,2120,2126],{"type":39,"tag":59,"props":2091,"children":2092},{},[2093],{"type":45,"value":2094},"The full query string is part of the cache key by default.",{"type":45,"value":2096}," With no ",{"type":39,"tag":82,"props":2098,"children":2100},{"className":2099},[],[2101],{"type":45,"value":2102},"Netlify-Vary: query=",{"type":45,"value":2104}," directive, every distinct query string is cached as a separate entry — so appending tracking or marketing params (",{"type":39,"tag":82,"props":2106,"children":2108},{"className":2107},[],[2109],{"type":45,"value":2110},"?utm_source=…",{"type":45,"value":144},{"type":39,"tag":82,"props":2113,"children":2115},{"className":2114},[],[2116],{"type":45,"value":2117},"fbclid",{"type":45,"value":2119},", and the like) silently fragments the cache into many near-duplicate entries and lowers the hit rate, even when those params don't change the response. Add ",{"type":39,"tag":82,"props":2121,"children":2123},{"className":2122},[],[2124],{"type":45,"value":2125},"Netlify-Vary: query=\u003Cnames>",{"type":45,"value":2127}," listing only the parameters that actually affect the output; the CDN then keys on just those and ignores all other query params, collapsing the variants onto one cache entry.",{"type":39,"tag":48,"props":2129,"children":2131},{"id":2130},"local-development",[2132],{"type":45,"value":2133},"Local Development",{"type":39,"tag":55,"props":2135,"children":2136},{},[2137,2143,2145,2151,2153,2159,2161,2166,2168,2173],{"type":39,"tag":82,"props":2138,"children":2140},{"className":2139},[],[2141],{"type":45,"value":2142},"netlify dev",{"type":45,"value":2144}," does not emulate the CDN cache. Header-based CDN caching is only observable on a deployed site: locally, cache headers pass through untouched, nothing is stored in or served from the CDN cache, Cache-API reads return no persisted entries, and the ",{"type":39,"tag":82,"props":2146,"children":2148},{"className":2147},[],[2149],{"type":45,"value":2150},"Cache-Status",{"type":45,"value":2152}," response header is absent. A \"cache miss every time\" on ",{"type":39,"tag":82,"props":2154,"children":2156},{"className":2155},[],[2157],{"type":45,"value":2158},"localhost",{"type":45,"value":2160}," is expected, not a bug — you cannot validate ",{"type":39,"tag":82,"props":2162,"children":2164},{"className":2163},[],[2165],{"type":45,"value":1741},{"type":45,"value":2167}," keying, cache tags, durable cache, or purge behavior locally. Verify caching on a deployed URL instead (a Deploy Preview or production) and read its ",{"type":39,"tag":82,"props":2169,"children":2171},{"className":2170},[],[2172],{"type":45,"value":2150},{"type":45,"value":2174}," header.",{"type":39,"tag":48,"props":2176,"children":2178},{"id":2177},"debugging",[2179],{"type":45,"value":2180},"Debugging",{"type":39,"tag":55,"props":2182,"children":2183},{},[2184,2186,2191,2193,2199,2201,2207],{"type":45,"value":2185},"Check the ",{"type":39,"tag":82,"props":2187,"children":2189},{"className":2188},[],[2190],{"type":45,"value":2150},{"type":45,"value":2192}," response header. Netlify emits it in the RFC 9211 format — one entry per named cache layer the request passed through, not a bare ",{"type":39,"tag":82,"props":2194,"children":2196},{"className":2195},[],[2197],{"type":45,"value":2198},"HIT",{"type":45,"value":2200},"\u002F",{"type":39,"tag":82,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":45,"value":2206},"MISS",{"type":45,"value":380},{"type":39,"tag":306,"props":2209,"children":2213},{"className":2210,"code":2212,"language":45},[2211],"language-text","Cache-Status: \"Netlify Edge\"; fwd=miss, \"Netlify Durable\"; hit; ttl=3600\n",[2214],{"type":39,"tag":82,"props":2215,"children":2216},{"__ignoreMap":311},[2217],{"type":45,"value":2212},{"type":39,"tag":67,"props":2219,"children":2220},{},[2221,2249,2260],{"type":39,"tag":71,"props":2222,"children":2223},{},[2224,2226,2232,2233,2239,2241,2247],{"type":45,"value":2225},"A named layer (",{"type":39,"tag":82,"props":2227,"children":2229},{"className":2228},[],[2230],{"type":45,"value":2231},"\"Netlify Edge\"",{"type":45,"value":144},{"type":39,"tag":82,"props":2234,"children":2236},{"className":2235},[],[2237],{"type":45,"value":2238},"\"Netlify Durable\"",{"type":45,"value":2240},") with ",{"type":39,"tag":82,"props":2242,"children":2244},{"className":2243},[],[2245],{"type":45,"value":2246},"hit",{"type":45,"value":2248}," — served from that cache",{"type":39,"tag":71,"props":2250,"children":2251},{},[2252,2258],{"type":39,"tag":82,"props":2253,"children":2255},{"className":2254},[],[2256],{"type":45,"value":2257},"fwd=miss",{"type":45,"value":2259}," — the entry was not in that layer, so the request was forwarded onward",{"type":39,"tag":71,"props":2261,"children":2262},{},[2263,2269],{"type":39,"tag":82,"props":2264,"children":2266},{"className":2265},[],[2267],{"type":45,"value":2268},"ttl=…",{"type":45,"value":2270}," — remaining freshness (seconds) for a hit",{"type":39,"tag":48,"props":2272,"children":2274},{"id":2273},"constraints",[2275],{"type":45,"value":2276},"Constraints",{"type":39,"tag":67,"props":2278,"children":2279},{},[2280,2285,2290,2302],{"type":39,"tag":71,"props":2281,"children":2282},{},[2283],{"type":45,"value":2284},"Basic auth disables caching for the entire site",{"type":39,"tag":71,"props":2286,"children":2287},{},[2288],{"type":45,"value":2289},"Durable cache is serverless functions only (not edge functions)",{"type":39,"tag":71,"props":2291,"children":2292},{},[2293,2295,2300],{"type":45,"value":2294},"Same URL must return identical ",{"type":39,"tag":82,"props":2296,"children":2298},{"className":2297},[],[2299],{"type":45,"value":1741},{"type":45,"value":2301}," headers across responses",{"type":39,"tag":71,"props":2303,"children":2304},{},[2305],{"type":45,"value":2306},"Deploy invalidation is scoped to deploy context (production vs preview)",{"type":39,"tag":2308,"props":2309,"children":2310},"style",{},[2311],{"type":45,"value":2312},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2314,"total":616},[2315,2332,2349,2364,2381,2388,2400],{"slug":2316,"name":2316,"fn":2317,"description":2318,"org":2319,"tags":2320,"stars":23,"repoUrl":24,"updatedAt":2331},"netlify-access-control","manage Netlify site access control","Use when the task involves controlling who can reach a Netlify site, or telling Netlify Identity apart from Secure Access. Trigger whenever the user wants to lock a site or deploy to their company\u002Fteam, restrict access to employees only, build an internal or employees-only app, set up password protection, SSO, or SAML, asks \"who can access my site\", or is confused about Netlify Identity vs Secure Access vs team login vs OAuth providers. Routes the request to the right layer — app-level Identity, site-visitor Password Protection, the Auth0 extension, or Team\u002FOrg SAML SSO — and explains the two-layer (perimeter + in-app identity) pattern and its double-login tradeoff. For building the app-level auth itself, use the netlify-identity skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2321,2324,2325,2328],{"name":2322,"slug":2323,"type":15},"Access Control","access-control",{"name":9,"slug":8,"type":15},{"name":2326,"slug":2327,"type":15},"Permissions","permissions",{"name":2329,"slug":2330,"type":15},"Security","security","2026-07-14T05:40:29.082149",{"slug":2333,"name":2333,"fn":2334,"description":2335,"org":2336,"tags":2337,"stars":23,"repoUrl":24,"updatedAt":2348},"netlify-agent-runner","run AI agent tasks on Netlify","Run AI agent tasks remotely on Netlify using Claude, Codex, or Gemini. Use when the user wants to run an AI agent on their site, get a second opinion from another model, or delegate development tasks to run remotely against their repo.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2338,2341,2344,2347],{"name":2339,"slug":2340,"type":15},"Agents","agents",{"name":2342,"slug":2343,"type":15},"Automation","automation",{"name":2345,"slug":2346,"type":15},"LLM","llm",{"name":9,"slug":8,"type":15},"2026-07-17T05:30:19.462913",{"slug":2350,"name":2350,"fn":2351,"description":2352,"org":2353,"tags":2354,"stars":23,"repoUrl":24,"updatedAt":2363},"netlify-ai-gateway","route AI requests via Netlify AI Gateway","Reference for Netlify AI Gateway — the managed proxy that routes calls to OpenAI, Anthropic, and Google Gemini SDKs without provider API keys. Use this skill any time the user wants to add AI on a Netlify site (chat, completion, reasoning, image generation, image-to-image edit\u002Fstylize), choose or change a model, wire up the OpenAI \u002F Anthropic \u002F @google\u002Fgenai SDK, decide which provider to use for an image-gen feature (it's Gemini-only on the gateway), or debug \"model not found\" \u002F \"API key missing\" against the gateway. Required reading before pinning a model — the gateway exposes a curated subset, not every provider model.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2355,2358,2361,2362],{"name":2356,"slug":2357,"type":15},"AI Infrastructure","ai-infrastructure",{"name":2359,"slug":2360,"type":15},"API Development","api-development",{"name":2345,"slug":2346,"type":15},{"name":9,"slug":8,"type":15},"2026-07-17T05:30:13.14555",{"slug":2365,"name":2365,"fn":2366,"description":2367,"org":2368,"tags":2369,"stars":23,"repoUrl":24,"updatedAt":2380},"netlify-blobs","manage file storage with Netlify Blobs","Guide for using Netlify Blobs for file and asset storage — images, documents, uploads, exports, cached binary artifacts. Covers getStore(), CRUD operations, metadata, listing, deploy-scoped vs site-scoped stores, and local development. Do NOT use Blobs as a dynamic data store — use Netlify Database for that.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2370,2373,2376,2377],{"name":2371,"slug":2372,"type":15},"Backend","backend",{"name":2374,"slug":2375,"type":15},"File Storage","file-storage",{"name":9,"slug":8,"type":15},{"name":2378,"slug":2379,"type":15},"Storage","storage","2026-07-17T05:30:16.503306",{"slug":4,"name":4,"fn":5,"description":6,"org":2382,"tags":2383,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2384,2385,2386,2387],{"name":21,"slug":22,"type":15},{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"slug":2389,"name":2389,"fn":2390,"description":2391,"org":2392,"tags":2393,"stars":23,"repoUrl":24,"updatedAt":2399},"netlify-config","configure Netlify site settings","Reference for netlify.toml configuration and site environment variables. Use when configuring build settings, redirects, rewrites, headers, deploy contexts, the `[dev]` block that controls `netlify dev` (command, port, targetPort, framework), or any site-level configuration — and when managing environment variables or secrets with the Netlify CLI, including scoping values to specific deploy contexts. Covers the complete netlify.toml syntax including redirects with splats\u002Fconditions, headers, deploy contexts, functions config, edge functions config, and the `[dev]` block (including when `framework` must be `\"#custom\"` — required when both a custom `command` and `targetPort` are set).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2394,2397,2398],{"name":2395,"slug":2396,"type":15},"Configuration","configuration",{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},"2026-07-17T05:30:21.284801",{"slug":2401,"name":2401,"fn":2402,"description":2403,"org":2404,"tags":2405,"stars":23,"repoUrl":24,"updatedAt":2414},"netlify-database","provision and manage Netlify Database","Guide for using Netlify Database — the GA managed Postgres product built into Netlify. Use when a project needs any kind of dynamic, structured, or relational data. Covers provisioning via @netlify\u002Fdatabase, Drizzle ORM (@beta) setup, migrations, preview branching, and safe production data handling. Blobs is only for file\u002Fasset storage — any dynamic data belongs in the database.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2406,2407,2410,2411],{"name":2371,"slug":2372,"type":15},{"name":2408,"slug":2409,"type":15},"Database","database",{"name":9,"slug":8,"type":15},{"name":2412,"slug":2413,"type":15},"PostgreSQL","postgresql","2026-07-20T05:58:58.934045",{"items":2416,"total":633},[2417,2432,2444,2451,2458,2465,2472,2479,2485,2492,2505,2520],{"slug":2418,"name":2418,"fn":2419,"description":2420,"org":2421,"tags":2422,"stars":2429,"repoUrl":2430,"updatedAt":2431},"configure-axis","configure AXIS agent evaluation scenarios","Author AXIS (Agent Experience Index Score) scenarios and axis.config.json for a project. Use when the user asks to set up AXIS, add a scenario, write or edit axis.config.json, or evaluate an AI agent with AXIS.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2423,2424,2425,2428],{"name":2339,"slug":2340,"type":15},{"name":2395,"slug":2396,"type":15},{"name":2426,"slug":2427,"type":15},"Evals","evals",{"name":9,"slug":8,"type":15},32,"https:\u002F\u002Fgithub.com\u002Fnetlify\u002Faxis","2026-07-20T05:59:47.468757",{"slug":2433,"name":2433,"fn":2434,"description":2435,"org":2436,"tags":2437,"stars":2429,"repoUrl":2430,"updatedAt":2443},"using-axis","run and interpret AXIS reports","Run AXIS, read its reports, navigate its project layout, and interpret scores. Use when the user asks to run AXIS, invoke the CLI, compare runs, explain a score, find a regression, manage baselines, or understand where AXIS writes its files.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2438,2441,2442],{"name":2439,"slug":2440,"type":15},"CLI","cli",{"name":2426,"slug":2427,"type":15},{"name":9,"slug":8,"type":15},"2026-07-14T05:40:13.443461",{"slug":2316,"name":2316,"fn":2317,"description":2318,"org":2445,"tags":2446,"stars":23,"repoUrl":24,"updatedAt":2331},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2447,2448,2449,2450],{"name":2322,"slug":2323,"type":15},{"name":9,"slug":8,"type":15},{"name":2326,"slug":2327,"type":15},{"name":2329,"slug":2330,"type":15},{"slug":2333,"name":2333,"fn":2334,"description":2335,"org":2452,"tags":2453,"stars":23,"repoUrl":24,"updatedAt":2348},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2454,2455,2456,2457],{"name":2339,"slug":2340,"type":15},{"name":2342,"slug":2343,"type":15},{"name":2345,"slug":2346,"type":15},{"name":9,"slug":8,"type":15},{"slug":2350,"name":2350,"fn":2351,"description":2352,"org":2459,"tags":2460,"stars":23,"repoUrl":24,"updatedAt":2363},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2461,2462,2463,2464],{"name":2356,"slug":2357,"type":15},{"name":2359,"slug":2360,"type":15},{"name":2345,"slug":2346,"type":15},{"name":9,"slug":8,"type":15},{"slug":2365,"name":2365,"fn":2366,"description":2367,"org":2466,"tags":2467,"stars":23,"repoUrl":24,"updatedAt":2380},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2468,2469,2470,2471],{"name":2371,"slug":2372,"type":15},{"name":2374,"slug":2375,"type":15},{"name":9,"slug":8,"type":15},{"name":2378,"slug":2379,"type":15},{"slug":4,"name":4,"fn":5,"description":6,"org":2473,"tags":2474,"stars":23,"repoUrl":24,"updatedAt":25},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2475,2476,2477,2478],{"name":21,"slug":22,"type":15},{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},{"slug":2389,"name":2389,"fn":2390,"description":2391,"org":2480,"tags":2481,"stars":23,"repoUrl":24,"updatedAt":2399},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2482,2483,2484],{"name":2395,"slug":2396,"type":15},{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"slug":2401,"name":2401,"fn":2402,"description":2403,"org":2486,"tags":2487,"stars":23,"repoUrl":24,"updatedAt":2414},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2488,2489,2490,2491],{"name":2371,"slug":2372,"type":15},{"name":2408,"slug":2409,"type":15},{"name":9,"slug":8,"type":15},{"name":2412,"slug":2413,"type":15},{"slug":2493,"name":2493,"fn":2494,"description":2495,"org":2496,"tags":2497,"stars":23,"repoUrl":24,"updatedAt":2504},"netlify-deploy","deploy and host projects on Netlify","Deploy, host, and publish web projects on Netlify with the Netlify CLI. Use when the user wants to deploy a site or repository to Netlify, link a local project to a Netlify site, ship a production or preview\u002Fdraft deploy, set up Git-based continuous deployment, run a manual or local deploy, configure CI deploys, or troubleshoot a failed or misconfigured deploy. Also use to view or tail a deployed site's runtime logs — function and edge-function output, deploy logs — via `netlify logs` when debugging what a live site is doing (recent errors, recent activity, streaming output).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2498,2499,2500,2501],{"name":2439,"slug":2440,"type":15},{"name":18,"slug":19,"type":15},{"name":9,"slug":8,"type":15},{"name":2502,"slug":2503,"type":15},"Web Development","web-development","2026-07-17T05:30:14.218977",{"slug":2506,"name":2506,"fn":2507,"description":2508,"org":2509,"tags":2510,"stars":23,"repoUrl":24,"updatedAt":2519},"netlify-edge-functions","write Netlify Edge Functions","Guide for writing Netlify Edge Functions. Use when building middleware, geolocation-based logic, request\u002Fresponse manipulation, authentication checks, A\u002FB testing, or any low-latency edge compute. Covers Deno runtime, context.next() middleware pattern, geolocation, and when to choose edge vs serverless.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2511,2514,2517,2518],{"name":2512,"slug":2513,"type":15},"Edge Functions","edge-functions",{"name":2515,"slug":2516,"type":15},"Middleware","middleware",{"name":9,"slug":8,"type":15},{"name":13,"slug":14,"type":15},"2026-07-14T05:40:34.147865",{"slug":2521,"name":2521,"fn":2522,"description":2523,"org":2524,"tags":2525,"stars":23,"repoUrl":24,"updatedAt":2534},"netlify-forms","handle HTML forms with Netlify","Guide for using Netlify Forms for HTML form handling. Use when adding contact forms, feedback forms, file upload forms, or any form that should be collected by Netlify. Covers the data-netlify attribute, spam filtering, AJAX submissions, file uploads, notifications, and the submissions API.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2526,2529,2532,2533],{"name":2527,"slug":2528,"type":15},"Forms","forms",{"name":2530,"slug":2531,"type":15},"HTML","html",{"name":9,"slug":8,"type":15},{"name":2502,"slug":2503,"type":15},"2026-07-14T05:40:16.075367"]