Next.js
Next.js support is for static export builds.
Install
Section titled “Install”Install OpenNav in your Next.js project.
npm install @opennav-ai/opennavpnpm add @opennav-ai/opennavyarn add @opennav-ai/opennavbun add @opennav-ai/opennavQuick start
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
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”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)”Wraps a Next.js config object and runs OpenNav after supported static export builds.
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”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”Required. Public absolute URL used for generated links and manifest URLs. The
value should include the protocol and host, such as https://example.com.
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”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”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.
export default OpenNavNext({ siteName: "Example Docs", siteUrl: "https://example.com", platform: "cloudflare-pages",})(nextConfig);contentExtraction
Section titled “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 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.
export default OpenNavNext({ siteName: "Example Docs", siteUrl: "https://example.com", contentExtraction: { stripLayout: true, },})(nextConfig);contentExtraction.stripLayout
Section titled “contentExtraction.stripLayout”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”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.
export default OpenNavNext({ siteName: "Example Docs", siteUrl: "https://example.com", platform: "cloudflare-pages", staticHeaders: { enabled: false, },})(nextConfig);staticHeaders.enabled
Section titled “staticHeaders.enabled”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”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”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”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:
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 for the shared Astro and Next.js launch shape.