[Skip to content](#_top)

[![OpenNav AI](/_astro/full-open-logo.CGezuffk.svg) OpenNav AI](https://opennav.ai/)

Search CtrlK

Cancel

[Docs](https://docs.opennav.ai/index.md)

[Quick Start](https://docs.opennav.ai/getting-started/index.md)

[SDK](https://docs.opennav.ai/sdk/index.md)

[OpenNav AI on X](https://x.com/OpenNavAI)

[Joshua Bellew on X](https://x.com/manofyear93)

[Email Joshua Bellew](mailto:joshua@opennav.ai)

- Start Here

  - [Overview](https://docs.opennav.ai/index.md)
  - [How It Works](https://docs.opennav.ai/how-it-works/index.md)
  - [Getting Started](https://docs.opennav.ai/getting-started/index.md)

- Use OpenNav

  - [CLI](https://docs.opennav.ai/cli/index.md)
  - [SDK](https://docs.opennav.ai/sdk/index.md)

- Frameworks

  - [Astro](https://docs.opennav.ai/frameworks/astro/index.md)
  - [Next.js](https://docs.opennav.ai/frameworks/next/index.md)
  - [Server-side frameworks Soon](https://docs.opennav.ai/frameworks/server-side/index.md)

- Platforms

  - [Cloudflare](https://docs.opennav.ai/platforms/cloudflare/index.md)

- Reference

  - [Generated Files](https://docs.opennav.ai/reference/generated-files/index.md)
  - [Content Extraction](https://docs.opennav.ai/reference/content-extraction/index.md)
  - [Access Guidance](https://docs.opennav.ai/reference/access-guidance/index.md)

- External

  - [AcceptMarkdown](https://acceptmarkdown.com/)
  - [Cloudflare Agent Readiness](https://blog.cloudflare.com/agent-readiness/)
  - [Is It Agent Ready?](https://isitagentready.com/)

[OpenNav AI on X](https://x.com/OpenNavAI)

[Joshua Bellew on X](https://x.com/manofyear93)

[Email Joshua Bellew](mailto:joshua@opennav.ai)

On this page

- [Overview](#_top)
- [Install](#install)
- [Choose Your Cloudflare Path](#choose-your-cloudflare-path)
- [Cloudflare Pages With The CLI](#cloudflare-pages-with-the-cli)
- [Astro On Cloudflare Pages](#astro-on-cloudflare-pages)
- [Next.js Static Export On Cloudflare Pages](#nextjs-static-export-on-cloudflare-pages)
- [Custom SDK Or Monorepo Builds](#custom-sdk-or-monorepo-builds)
- [Cloudflare Pages Headers](#cloudflare-pages-headers)
- [Workers Static Assets](#workers-static-assets)
- [AI Gateway And Agent Experiments](#ai-gateway-and-agent-experiments)
- [What Gets Published](#what-gets-published)
- [Cloudflare References](#cloudflare-references)

## On this page

- [Overview](#_top)
- [Install](#install)
- [Choose Your Cloudflare Path](#choose-your-cloudflare-path)
- [Cloudflare Pages With The CLI](#cloudflare-pages-with-the-cli)
- [Astro On Cloudflare Pages](#astro-on-cloudflare-pages)
- [Next.js Static Export On Cloudflare Pages](#nextjs-static-export-on-cloudflare-pages)
- [Custom SDK Or Monorepo Builds](#custom-sdk-or-monorepo-builds)
- [Cloudflare Pages Headers](#cloudflare-pages-headers)
- [Workers Static Assets](#workers-static-assets)
- [AI Gateway And Agent Experiments](#ai-gateway-and-agent-experiments)
- [What Gets Published](#what-gets-published)
- [Cloudflare References](#cloudflare-references)

# Cloudflare

Cloudflare is the clearest first platform for OpenNav: Pages already deploys a finished folder, Workers can serve static assets from a configured directory, and AI Gateway teams are already thinking about agent cost, routing, and observability.

OpenNav currently ships the static agent-readable layer. It does not install Worker middleware or configure AI Gateway. Start by publishing the files agents can discover today, then use the server-side roadmap when runtime Markdown responses are available.

Cloudflare Pages is the first platform with a built-in OpenNav platform default. Passing `platform: "cloudflare-pages"` in the SDK, Astro, or Next, or `--platform cloudflare-pages` in the CLI, creates the Pages `_headers` artifact by default. Additional platform defaults are planned as OpenNav adds first-class support for more static hosts.

## Install

[Section titled “Install”](#install)

Install OpenNav in the project that owns the Cloudflare build command.

- [npm](#tab-panel-16)
- [pnpm](#tab-panel-17)
- [yarn](#tab-panel-18)
- [bun](#tab-panel-19)

Terminal window

```txt
npm install @opennav-ai/opennav
```

Terminal window

```txt
pnpm add @opennav-ai/opennav
```

Terminal window

```txt
yarn add @opennav-ai/opennav
```

Terminal window

```txt
bun add @opennav-ai/opennav
```

## Choose Your Cloudflare Path

[Section titled “Choose Your Cloudflare Path”](#choose-your-cloudflare-path)

| Cloudflare path | OpenNav setup |
| --- | --- |
| Pages with any static output folder | Run the [CLI](https://docs.opennav.ai/cli/index.md) after your normal build. |
| Pages with Astro | Use [OpenNavAstro](https://docs.opennav.ai/frameworks/astro/index.md) after `astro build`. |
| Pages with Next.js static export | Use [OpenNavNext](https://docs.opennav.ai/frameworks/next/index.md) with `output: "export"`. |
| Pages with a custom build script or monorepo | Use the [TypeScript SDK](https://docs.opennav.ai/sdk/index.md) from the script that knows the output folder. |
| Workers static assets | Run OpenNav before `wrangler deploy` uploads the configured assets directory. |
| AI Gateway or agent experiments | Fetch the generated OpenNav files from Pages or Workers assets; AI Gateway remains the AI app proxy and observability layer. |

## Cloudflare Pages With The CLI

[Section titled “Cloudflare Pages With The CLI”](#cloudflare-pages-with-the-cli)

Cloudflare Pages lets you configure a build command and an output directory. Use the same output directory for both OpenNav and the Pages publish directory.

```txt
{  "scripts": {    "build": "astro build && opennav build --static --output dist --site-url https://example.com --site-name \"Example Docs\" --platform cloudflare-pages"  }}
```

In Cloudflare Pages:

| Pages setting | Value |
| --- | --- |
| Build command | `npm run build` |
| Build output directory | `dist` |

Use the deployed production URL for `--site-url`, including the protocol and host. In monorepos, make `--output` relative to the project root that Pages uses for the build command.

Run a dry run locally when you want to preview the file plan before changing the build command:

Terminal window

```txt
opennav build --static \  --output dist \  --site-url https://example.com \  --site-name "Example Docs" \  --platform cloudflare-pages \  --dry-run
```

`--platform cloudflare-pages` is enough to create or update `_headers`; the older explicit `--static-headers` flag is not required for Cloudflare Pages.

## Astro On Cloudflare Pages

[Section titled “Astro On Cloudflare Pages”](#astro-on-cloudflare-pages)

Astro static builds usually publish `dist`. Add `OpenNavAstro` to the Astro config, then let Pages run the normal Astro build.

```txt
import { defineConfig } from "astro/config";import { OpenNavAstro } from "@opennav-ai/opennav/astro";
export default defineConfig({  site: "https://example.com",  integrations: [    OpenNavAstro({      siteName: "Example Docs",      mode: "static",      platform: "cloudflare-pages",    }),  ],});
```

In Cloudflare Pages:

| Pages setting | Value |
| --- | --- |
| Build command | `npm run build` |
| Build output directory | `dist` |

Use this path for Astro sites that produce static HTML. Server-side Astro on Cloudflare is part of the [server-side roadmap](https://docs.opennav.ai/frameworks/server-side/index.md), not the current static profile.

To keep the Cloudflare platform setting without writing `_headers`, opt out in the integration:

```txt
OpenNavAstro({  siteName: "Example Docs",  mode: "static",  platform: "cloudflare-pages",  staticHeaders: {    enabled: false,  },});
```

## Next.js Static Export On Cloudflare Pages

[Section titled “Next.js Static Export On Cloudflare Pages”](#nextjs-static-export-on-cloudflare-pages)

OpenNav supports Next.js static export builds. Configure Next with `output: "export"` and publish the generated `out` folder.

```txt
import { OpenNavNext } from "@opennav-ai/opennav/next";import type { NextConfig } from "next";
const nextConfig: NextConfig = {  output: "export",};
export default OpenNavNext({  siteName: "Example Docs",  siteUrl: "https://example.com",  mode: "static",  platform: "cloudflare-pages",})(nextConfig);
```

In Cloudflare Pages:

| Pages setting | Value |
| --- | --- |
| Build command | `npm run build` |
| Build output directory | `out` |

Use this path for exported static routes. Next.js server output, route handlers, and request-time dynamic pages are not covered by the current static profile.

To keep the Cloudflare platform setting without writing `_headers`, opt out in the config wrapper:

```txt
OpenNavNext({  siteName: "Example Docs",  siteUrl: "https://example.com",  mode: "static",  platform: "cloudflare-pages",  staticHeaders: {    enabled: false,  },})(nextConfig);
```

## Custom SDK Or Monorepo Builds

[Section titled “Custom SDK Or Monorepo Builds”](#custom-sdk-or-monorepo-builds)

Use the root SDK when a custom script already knows which folder Cloudflare will publish.

```txt
import { OpenNavStaticSite } from "@opennav-ai/opennav";
const result = await new OpenNavStaticSite({  siteName: "Example Docs",  siteUrl: "https://example.com",  outputDirectory: "dist",  platform: "cloudflare-pages",}).build();
if (result.isErr()) {  console.error(result.error.message);  process.exit(1);}
```

Then call that script after the framework build and before Pages uploads the output folder.

```txt
{  "scripts": {    "build": "npm run build:site && node scripts/opennav.mjs"  }}
```

Set `staticHeaders: { enabled: false }` in the SDK options when you want to keep `platform: "cloudflare-pages"` for future Cloudflare-specific behavior but do not want OpenNav to create or edit `_headers`.

## Cloudflare Pages Headers

[Section titled “Cloudflare Pages Headers”](#cloudflare-pages-headers)

Cloudflare Pages can read a `_headers` file from the deployed output directory and attach response headers to matching routes. When `platform: "cloudflare-pages"` is configured, OpenNav creates or updates an OpenNav-managed block in that file by default.

| Entry point | Cloudflare Pages header behavior |
| --- | --- |
| CLI with `--platform cloudflare-pages` | Creates or updates `_headers` by default. |
| `OpenNavStaticSite({ platform: "cloudflare-pages" })` | Creates or updates `_headers` by default. |
| `OpenNavAstro({ platform: "cloudflare-pages" })` | Creates or updates `dist/_headers` by default. |
| `OpenNavNext({ platform: "cloudflare-pages" })` | Creates or updates `_headers` in the static export folder by default. |
| SDK, Astro, or Next with `staticHeaders: { enabled: false }` | Does not create or edit `_headers`. |

The default is enabled only for currently supported platforms that have a known static header file format. Today that is Cloudflare Pages. More platform support is planned.

```txt
dist/  _headers  llms.txt  llms-full.txt  .well-known/opennav.json  index.md
```

The generated `_headers` block sets:

| Route pattern | Response header behavior |
| --- | --- |
| `/*.md` | Serves generated Markdown mirrors as `text/markdown; charset=utf-8`. |
| `/llms.txt`, `/llms-full.txt`, and `.well-known` copies | Serves generated indexes as `text/plain; charset=utf-8`. |
| `/.well-known/opennav.json` | Serves the compatibility manifest as `application/json; charset=utf-8`. |
| HTML page routes such as `/`, `/docs/page`, or `/docs/page/` | Adds HTTP `Link` headers pointing to that page’s generated Markdown alternate and the root `llms.txt` index. |

OpenNav also sets `X-Content-Type-Options: nosniff` for those generated artifacts. In a request flow, an agent can fetch `https://example.com/llms.txt` or `https://example.com/docs/page/index.md`, and Cloudflare Pages will return the file with a concrete content type instead of relying on generic static-file detection.

For HTML responses, the generated page route block looks like this:

```txt
/docs/page  Link: <https://example.com/docs/page.md>; rel="alternate"; type="text/markdown"  Link: <https://example.com/llms.txt>; rel="index"; type="text/plain"
```

For a small site with a home page and one docs page, the complete generated `dist/_headers` file can look like this:

```txt
# Begin OpenNav AI# opennav compatible="true" version="1.0" profile="static-agent-ready" build-fingerprint="sha256:123456789abc" manifest="/.well-known/opennav.json"/llms.txt  Content-Type: text/plain; charset=utf-8  X-Content-Type-Options: nosniff
/llms-full.txt  Content-Type: text/plain; charset=utf-8  X-Content-Type-Options: nosniff
/.well-known/llms.txt  Content-Type: text/plain; charset=utf-8  X-Content-Type-Options: nosniff
/.well-known/llms-full.txt  Content-Type: text/plain; charset=utf-8  X-Content-Type-Options: nosniff
/.well-known/opennav.json  Content-Type: application/json; charset=utf-8  X-Content-Type-Options: nosniff
/*.md  Content-Type: text/markdown; charset=utf-8  X-Content-Type-Options: nosniff
/  Link: <https://example.com/index.md>; rel="alternate"; type="text/markdown"  Link: <https://example.com/llms.txt>; rel="index"; type="text/plain"
/docs/page  Link: <https://example.com/docs/page.md>; rel="alternate"; type="text/markdown"  Link: <https://example.com/llms.txt>; rel="index"; type="text/plain"# End OpenNav AI
```

That does not implement runtime `Accept: text/markdown` negotiation. It gives agents a response-header discovery path for the same Markdown alternate and site index that OpenNav already advertises inside the HTML `<head>`.

OpenNav preserves caller-owned `_headers` rules and replaces only the block between `# Begin OpenNav AI` and `# End OpenNav AI`. If an existing caller-owned route overlaps OpenNav’s generated header routes, OpenNav leaves `_headers` untouched and reports a warning so the site owner can resolve the conflict intentionally. This applies to any header on the overlapping route, not only `Content-Type`.

Cloudflare documents the file format, comment behavior, and route/header limits in [Pages Headers](https://developers.cloudflare.com/pages/configuration/headers/).

## Workers Static Assets

[Section titled “Workers Static Assets”](#workers-static-assets)

Workers can deploy static assets from a configured directory. Run OpenNav before `wrangler deploy` so the assets directory already contains the generated OpenNav files.

```txt
{  "$schema": "./node_modules/wrangler/config-schema.json",  "name": "example-docs",  "compatibility_date": "2026-05-01",  "assets": {    "directory": "./dist"  }}
```

```txt
{  "scripts": {    "build": "astro build && opennav build --static --output dist --site-url https://example.com --site-name \"Example Docs\"",    "deploy": "npm run build && wrangler deploy"  }}
```

If your Worker code serves assets through a binding, keep the binding pointed at the same directory OpenNav updates. OpenNav writes files only; it does not change Worker routing.

## AI Gateway And Agent Experiments

[Section titled “AI Gateway And Agent Experiments”](#ai-gateway-and-agent-experiments)

AI Gateway is useful for observing and controlling AI application traffic. It does not publish website content. Pair it with OpenNav by having the agent fetch the generated files from a Cloudflare Pages site or a Workers static-assets deployment:

| Agent need | OpenNav file |
| --- | --- |
| Find the readable site index | `https://example.com/llms.txt` |
| Read page content without visual HTML | `https://example.com/path/index.md` |
| Verify generated files and static compatibility | `https://example.com/.well-known/opennav.json` |
| Read content-use guidance | `https://example.com/robots.txt` when `accessGuidance` is configured |

Use this when you are testing agent workflows, token cost, or browser fallback behavior around Cloudflare-hosted sites.

## What Gets Published

[Section titled “What Gets Published”](#what-gets-published)

After OpenNav runs, the same Cloudflare deployment includes the agent-readable files beside your normal site:

```txt
dist/  llms.txt  llms-full.txt  _headers  .well-known/llms.txt  .well-known/llms-full.txt  .well-known/opennav.json  index.md  docs/getting-started/index.md  robots.txt
```

See the [generated files reference](https://docs.opennav.ai/reference/generated-files/index.md) for the full file behavior and ownership rules.

## Cloudflare References

[Section titled “Cloudflare References”](#cloudflare-references)

- [Cloudflare Pages build configuration](https://developers.cloudflare.com/pages/configuration/build-configuration/)
- [Cloudflare Pages Headers](https://developers.cloudflare.com/pages/configuration/headers/)
- [Cloudflare Workers static assets](https://developers.cloudflare.com/workers/static-assets/)
- [Cloudflare Agent Readiness](https://blog.cloudflare.com/agent-readiness/)

[PreviousServer-side frameworks](https://docs.opennav.ai/frameworks/server-side/index.md)

[NextGenerated Files](https://docs.opennav.ai/reference/generated-files/index.md)

---

Site index: [llms.txt](https://docs.opennav.ai/llms.txt)

<!-- opennav compatible="true" version="1.0" profile="static-agent-ready" build-fingerprint="sha256:ef7e48fe34cc" manifest="/.well-known/opennav.json" -->
