<!-- Generated from llms-txt-cloudflare/index.html. The canonical document is the HTML page. -->

- [ Home ](/) 
/
- [ How to create ](/how-to-create/) 
/
- Cloudflare Pages guide            
# llms.txt with Cloudflare Pages

Two approaches: place a static file in your build output directory for instant zero-config deployment, or use a Cloudflare Pages Function for dynamic content.

Last updated: April 22, 2026

✓ This site runs on Cloudflare Pages

llmtxt.info is deployed on Cloudflare Pages via GitHub. Our own  /llms.txt 
is served using the static file approach (Approach 1 below), you can inspect the live headers with
curl -I https://llmtxt.info/llms.txt .

## Approach 1, Static file in the build output

The simplest option. Cloudflare Pages serves every file in your build output directory directly
from their global CDN. No Workers, no Functions, no configuration changes needed.
static file, framework directory map   
Copy

```
# For any framework deployed on Cloudflare Pages,
# place llms.txt in the directory that gets published.
#
# Framework       → file location
# Astro           → public/llms.txt
# Next.js         → public/llms.txt
# SvelteKit       → static/llms.txt
# Hugo            → static/llms.txt
# Eleventy        → _site root (copy via passthrough)
# Plain HTML      → project root or output folder

# After deploy, Cloudflare serves it at /llms.txt from their global CDN.
# Verify:
curl -I https://your-domain.com/llms.txt
# Expected: HTTP/2 200 | Content-Type: text/plain | CF-Cache-Status: HIT
```

The correct location depends on your framework:

- **Astro** → `public/llms.txt` (copied to `dist/` automatically) 
- **Next.js** → `public/llms.txt` (Cloudflare Pages Next.js adapter supports
this) 
- **SvelteKit** → `static/llms.txt` 
- **Hugo** → `static/llms.txt` 
- **Eleventy** → add a passthrough copy: `eleventyConfig.addPassthroughCopy("llms.txt")` 
- **Plain HTML** → place in the folder you set as your build output directory   
Once deployed, Cloudflare serves the file from their edge network worldwide. The
`Content-Type: text/plain` header is set automatically based on the
`.txt` extension.

✓ GitHub integration

Cloudflare Pages connects directly to your GitHub (or GitLab) repository. Every push to your
production branch triggers a new build and deploy. Committing  public/llms.txt 
is all you need, no manual upload step.

## Approach 2, Cloudflare Pages Function

Cloudflare Pages Functions let you handle specific routes with TypeScript code running on the
Cloudflare Workers runtime. Create a file at `functions/llms.txt.ts` and it automatically
handles requests to `/llms.txt`.
functions/llms.txt.ts, hardcoded content   
Copy

```
// functions/llms.txt.ts
// Cloudflare Pages Functions use the file path as the route.
// This file handles GET requests to /llms.txt

interface Env {
// Add KV namespace or D1 bindings here if needed
}

export const onRequestGet: PagesFunction  = async (context) => {
// Build content, hardcode here or pull from KV / D1 / API
const content = [
'# My Site',
'',
'> One-sentence description of what this site is about.',
'',
'## Documentation',
'',
'- [Getting started](https://yoursite.com/docs/getting-started/): first steps.',
'- [API reference](https://yoursite.com/docs/api/): full endpoint catalog.',
'',
'## Optional',
'',
'- [Changelog](https://yoursite.com/changelog/): version history.',
].join('\n');

return new Response(content, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
// Cache at the edge for 1 hour, allow stale for 24h
'Cache-Control': 'public, max-age=3600, stale-while-revalidate=86400',
},
});
};

```

**When to use this:** when you want to generate the file from a data source (database,
CMS API, KV store) without rebuilding the entire site. Example with
[KV Namespace](https://developers.cloudflare.com/kv/):
functions/llms.txt.ts, KV-backed content   
Copy

```
// functions/llms.txt.ts, pulling content from KV
// Useful if you update the file from a CMS webhook without redeploying.

interface Env {
LLMS_TXT: KVNamespace;
}

export const onRequestGet: PagesFunction  = async ({ env }) => {
const content = await env.LLMS_TXT.get('content');

if (!content) {
return new Response('# My Site\n\n> Content not configured yet.', {
status: 200,
headers: { 'Content-Type': 'text/plain; charset=utf-8' },
});
}

return new Response(content, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
'Cache-Control': 'public, max-age=300, stale-while-revalidate=3600',
},
});
};

```

With the KV approach, you can update the content of `/llms.txt` by writing to the KV namespace
(via API, dashboard, or a webhook from your CMS) without triggering a full Pages deployment.

⚠ Pages Function vs static file

If both  functions/llms.txt.ts  and a static  llms.txt  exist in your build
output, the Pages Function takes precedence. Use one approach or the other, not both.

## Alternative: Cloudflare Worker

If your site is not on Cloudflare Pages but uses Cloudflare as a CDN/DNS proxy, you can
intercept the `/llms.txt` path with a standalone Cloudflare Worker using a
[route pattern](https://developers.cloudflare.com/workers/configuration/routing/routes/):
Cloudflare Worker, standalone   
Copy

```
// Cloudflare Worker, wrangler.toml config
// Use this if you want a standalone Worker (not tied to Pages).

// wrangler.toml
// name = "llms-txt-worker"
// main = "src/index.ts"
// compatibility_date = "2024-09-01"
//
// [[routes]]
// pattern = "yoursite.com/llms.txt"
// zone_name = "yoursite.com"

// src/index.ts
export default {
async fetch(request: Request): Promise  {
const content = `# My Site

> One-sentence description.

## Core pages

- [Getting started](https://yoursite.com/docs/getting-started/): first steps.
- [API reference](https://yoursite.com/docs/api/): full endpoint catalog.
`;

return new Response(content, {
headers: {
'Content-Type': 'text/plain; charset=utf-8',
'Cache-Control': 'public, max-age=3600',
},
});
},
} satisfies ExportedHandler;

```

## Cache headers and CDN behaviour

Cloudflare caches static files from your build output automatically. For static files, you
don&rsquo;t need to set cache headers, Cloudflare respects the default TTL from your Pages
project settings.

For Pages Functions, set `Cache-Control` explicitly in the response. Recommended:

- `public, max-age=3600`, cache at edge for 1 hour (good for manually-maintained
files). 
- `public, max-age=3600, stale-while-revalidate=86400`, serve stale for up to 24h
while revalidating in background. 
- `public, max-age=300`, 5-minute cache for KV-backed content that may update
frequently.   
When you deploy a new version, Cloudflare automatically invalidates the cache for changed static
files. For Pages Functions, use the Cloudflare dashboard or API to purge the specific URL if you
need immediate invalidation.

## Verify after deploy
verify   
Copy

```
# Check headers, look for Content-Type and CF-Cache-Status
curl -I https://yoursite.com/llms.txt

# Check content
curl https://yoursite.com/llms.txt

# Purge Cloudflare cache if you deployed a new version:
# Dashboard → Caching → Configuration → Purge Everything
# or via API:
curl -X POST "https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/purge_cache" \
-H "Authorization: Bearer {CF_API_TOKEN}" \
-H "Content-Type: application/json" \
--data '{"files":["https://yoursite.com/llms.txt"]}'
```

After verifying headers, paste your live URL into the [validator](/validator/)
to confirm spec compliance: exactly one H1, valid link syntax, all URLs absolute, no empty sections.

&rarr; [Full creation guide](/how-to-create/) &middot;
[Astro guide](/llms-txt-astro/) &middot;
[Next.js guide](/llms-txt-nextjs/)

## Sources

- [ llmstxt.org, official spec ](https://llmstxt.org/)
- [ Cloudflare Pages, Functions ](https://developers.cloudflare.com/pages/functions/)
- [ Cloudflare, llms.txt live example ](https://cloudflare.com/llms.txt)           
On this page

- [ Approach 1, Static file in the build output ](#approach-1)
- [ Approach 2, Cloudflare Pages Function ](#approach-2)
- [ Alternative: Cloudflare Worker ](#workers)
- [ Cache headers and CDN behaviour ](#cache)
- [ Verify after deploy ](#verify)
