[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)
- [Output Folder Behavior](#output-folder-behavior)
- [OpenNavNext(options)](#opennavnextoptions)
  - [siteName](#sitename)
  - [siteUrl](#siteurl)
  - [mode](#mode)
  - [outputDirectory](#outputdirectory)
  - [platform](#platform)
  - [contentExtraction](#contentextraction)
  - [contentExtraction.stripLayout](#contentextractionstriplayout)
  - [staticHeaders](#staticheaders)
  - [staticHeaders.enabled](#staticheadersenabled)
  - [accessGuidance](#accessguidance)
  - [accessGuidance.contentSignals](#accessguidancecontentsignals)
- [Server-Side Support](#server-side-support)

## On this page

- [Overview](#_top)
- [Install](#install)
- [Output Folder Behavior](#output-folder-behavior)
- [OpenNavNext(options)](#opennavnextoptions)
  - [siteName](#sitename)
  - [siteUrl](#siteurl)
  - [mode](#mode)
  - [outputDirectory](#outputdirectory)
  - [platform](#platform)
  - [contentExtraction](#contentextraction)
  - [contentExtraction.stripLayout](#contentextractionstriplayout)
  - [staticHeaders](#staticheaders)
  - [staticHeaders.enabled](#staticheadersenabled)
  - [accessGuidance](#accessguidance)
  - [accessGuidance.contentSignals](#accessguidancecontentsignals)
- [Server-Side Support](#server-side-support)

# Next.js

Next.js support is for static export builds.

## Install

[Section titled “Install”](#install)

Install OpenNav in your Next.js project.

- [npm](#tab-panel-8)
- [pnpm](#tab-panel-9)
- [yarn](#tab-panel-10)
- [bun](#tab-panel-11)

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
```

Quick start

```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",})(nextConfig);
```

This is all you need for the standard Next static export folder. OpenNav reads `out` after `next build` and writes the generated AI Web Compatibility Layer files there.

Full example

```txt
import { OpenNavNext } from "@opennav-ai/opennav/next";import type { NextConfig } from "next";
const nextConfig: NextConfig = {  output: "export",  distDir: "dist",};
export default OpenNavNext({  siteName: "Example Docs",  siteUrl: "https://example.com",  mode: "static",  platform: "cloudflare-pages",  contentExtraction: {    stripLayout: true,  },  accessGuidance: {    contentSignals: {      search: "allow",      aiInput: "allow",      aiTrain: "disallow",    },  },})(nextConfig);
```

OpenNav follows `distDir` automatically, so the example above reads and writes `dist` without repeating that path inside `OpenNavNext(...)`.

## Output Folder Behavior

[Section titled “Output Folder Behavior”](#output-folder-behavior)

Most projects should leave `outputDirectory` out of `OpenNavNext(...)`. OpenNav uses the same folder Next uses for the static export.

| Next config | OpenNav scans |
| --- | --- |
| `output: "export"` | `out` |
| `output: "export", distDir: "dist"` | `dist` |
| `output: "export", distDir: "public-build/"` | `public-build` |

Pass `outputDirectory` only when OpenNav should read a different relative folder than the one configured for the Next static export.

## `OpenNavNext(options)`

[Section titled “OpenNavNext(options)”](#opennavnextoptions)

Wraps a Next.js config object and runs OpenNav after supported static export builds.

```txt
interface OpenNavNextOptions {  readonly siteName: string;  readonly siteUrl: string;  readonly mode?: "static";  readonly outputDirectory?: string;  readonly platform?: "cloudflare-pages";  readonly contentExtraction?: {    readonly stripLayout?: boolean;  };  readonly staticHeaders?: {    readonly enabled: boolean;  };  readonly accessGuidance?: {    readonly contentSignals?: {      readonly search?: "allow" | "disallow";      readonly aiInput?: "allow" | "disallow";      readonly aiTrain?: "allow" | "disallow";    };  };}
```

### `siteName`

[Section titled “siteName”](#sitename)

Required. Human-readable site or docs name written into generated OpenNav files, including `llms.txt`, page Markdown files, and `.well-known/opennav.json` inside the static export folder.

### `siteUrl`

[Section titled “siteUrl”](#siteurl)

Required. Public absolute URL used for generated links and manifest URLs. The value should include the protocol and host, such as `https://example.com`.

### `mode`

[Section titled “mode”](#mode)

Optional. Only `"static"` is supported today, and OpenNav uses it when `mode` is omitted.

OpenNav runs only when the wrapped Next config uses `output: "export"`.

### `outputDirectory`

[Section titled “outputDirectory”](#outputdirectory)

Optional. Static export folder OpenNav scans and updates after `next build`. Defaults to the wrapped Next config’s `distDir` when it is a string, then falls back to `out`.

Use this only when OpenNav should read a different folder than the one configured for the Next static export. Relative paths are resolved from the working directory that runs `next build`, so monorepo setups can use paths such as `apps/docs/out`. Absolute paths are rejected, and trailing slashes are handled automatically.

### `platform`

[Section titled “platform”](#platform)

Optional. Static hosting platform for platform-specific generated files.

Supported values are `"cloudflare-pages"`. When `platform: "cloudflare-pages"` is passed, OpenNav creates or updates `_headers` inside the static export folder by default so Cloudflare Pages serves generated Markdown, `llms` files, and the OpenNav manifest with explicit response content types. The same `_headers` block also adds per-page HTTP `Link` headers to HTML routes so agents can discover each page’s Markdown alternate and the root `llms.txt` index from response headers.

Omit `platform` for a generic Next static export build. More platform values will be added as OpenNav gains first-class support for additional static hosts.

```txt
export default OpenNavNext({  siteName: "Example Docs",  siteUrl: "https://example.com",  platform: "cloudflare-pages",})(nextConfig);
```

### `contentExtraction`

[Section titled “contentExtraction”](#contentextraction)

Optional. Controls how OpenNav reads built HTML pages before creating generated Markdown page artifacts and `llms-full.txt`.

When omitted, OpenNav preserves the current conservative behavior: it converts the whole HTML `<body>` to Markdown. Set `stripLayout` to `true` to remove the documented fixed list of layout elements before Markdown conversion.

See the [content extraction reference](https://docs.opennav.ai/reference/content-extraction/index.md) for the exact stripped elements and the cases where you should leave this unset.

This first version uses a fixed strip list. Future versions are expected to add more granular HTML element controls, such as tag-level, class-level, or selector-level strip and preserve rules.

```txt
export default OpenNavNext({  siteName: "Example Docs",  siteUrl: "https://example.com",  contentExtraction: {    stripLayout: true,  },})(nextConfig);
```

### `contentExtraction.stripLayout`

[Section titled “contentExtraction.stripLayout”](#contentextractionstriplayout)

Optional. Defaults to `false`.

When `true`, OpenNav still starts from the whole HTML `<body>`, but removes the declared layout elements before converting that body to Markdown.

### `staticHeaders`

[Section titled “staticHeaders”](#staticheaders)

Optional. Controls platform response-header artifacts such as Cloudflare Pages `_headers`.

When omitted, OpenNav uses the configured platform default. The current Cloudflare Pages default is enabled, so `platform: "cloudflare-pages"` creates or updates `_headers` in the static export folder unless you opt out.

If an existing caller-owned `_headers` route overlaps OpenNav’s generated routes, OpenNav leaves `_headers` untouched and reports a warning.

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

### `staticHeaders.enabled`

[Section titled “staticHeaders.enabled”](#staticheadersenabled)

Required inside `staticHeaders`. Set to `false` to keep platform metadata such as `platform: "cloudflare-pages"` without creating or editing the platform header file. Set to `true` to explicitly request the platform header file. When `true`, `platform` must also be configured because each host has its own header-file format.

### `accessGuidance`

[Section titled “accessGuidance”](#accessguidance)

Optional. Controls whether OpenNav creates or updates its managed Content Signals block in the static export folder’s `robots.txt`.

When omitted, OpenNav does not create or edit `robots.txt` for access guidance.

### `accessGuidance.contentSignals`

[Section titled “accessGuidance.contentSignals”](#accessguidancecontentsignals)

Optional. Content-use preferences OpenNav writes into the static export folder’s `robots.txt`.

At least one nested field must be configured before OpenNav creates or updates its managed Content Signals block.

#### `search`

Optional. Writes `search=yes` for `“allow”` or `search=no` for `“disallow”`. When omitted, OpenNav does not express a search-use preference.

#### `aiInput`

Optional. Writes `ai-input=yes` for `“allow”` or `ai-input=no` for `“disallow”`. When omitted, OpenNav does not express an AI-input preference.

#### `aiTrain`

Optional. Writes `ai-train=yes` for `“allow”` or `ai-train=no` for `“disallow”`. When omitted, OpenNav does not express an AI-training preference.

## Server-Side Support

[Section titled “Server-Side Support”](#server-side-support)

Next.js server output is the next open-source track. This is the future of agent-ready websites: the same route can serve HTML to people and Markdown to agents through content negotiation.

Planned launch shape:

```txt
import { OpenNavNextServer } from "@opennav-ai/opennav/next/server";import type { NextRequest } from "next/server";
const opennav = OpenNavNextServer({  siteName: "Example Docs",  markdown: {    mode: "content-negotiation",    routes: ["/docs/:path*", "/blog/:path*"],  },});
export function proxy(request: NextRequest) {  return opennav.handle(request);}
export const config = {  matcher: ["/docs/:path*", "/blog/:path*"],};
```

When a request prefers `text/markdown`, OpenNav will return an agent-readable Markdown representation from the same URL. Browser requests still receive HTML, and responses include `Vary: Accept` so caches keep both representations correct.

See the [server-side framework roadmap](https://docs.opennav.ai/frameworks/server-side/index.md) for the shared Astro and Next.js launch shape.

[PreviousAstro](https://docs.opennav.ai/frameworks/astro/index.md)

[NextServer-side frameworks](https://docs.opennav.ai/frameworks/server-side/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" -->
