Project Configuration
Use esdev.json for build targets, compiler plugins and the development loop. Use afw.config.js for site/theme settings read by the project's prerender script and @opentf/afw-docs components. Neither replaces the other.
For the build-target and browser-entry setup, follow Production Build. The settings below apply when your project uses prerendering, the docs theme or locale routing.
// afw.config.js import { defineDocsConfig } from "@opentf/afw-docs/config"; export default defineDocsConfig({ site: { url: "https://example.com" }, docs: { title: "My Project", dir: "docs", repoUrl: "https://github.com/org/repo", // "Edit this page" links lastUpdated: true, // "Last updated" line per page }, blog: { dir: "blog", lastUpdated: true }, });
defineDocsConfig is an identity helper — it returns the object unchanged but gives your editor full type hints.
Explicit build plugins and the prerender script use it for docs navigation, posts, search, feeds, LLM context and last-updated; the Navbar/DocsLayout components read docs at runtime; and the SSG step reads site.url for canonical URLs, sitemap, and feeds.
Top-level keys
| Key | Purpose |
|---|---|
site | Canonical origin — { url }. Drives absolute canonicals, the sitemap, blog feeds, and LLM context links. |
docs | The documentation section (sidebar, navbar, search). |
blog | An optional blog section (post list, banners, feeds). |
i18n | Internationalization — locales for URL-prefix routing (@opentf/afw-i18n). |
proxy | Legacy CLI setting; it is not consumed by the native esdev compiler plugin. |
site
site: { url: "https://example.com" }
Required by this repo’s production docs/blog prerender script, which validates the origin before rendering. Supply it through this config or your own prerender script.
docs
The docs block supplies branding, navigation, footer and search settings to DocsLayout. Pass it to the layout explicitly; add the build plugins for generated navigation, timestamps and search output.
See Docs Configuration for the settings, plugin registration and per-folder _meta.js ordering.
Multiple sections
A section like an API reference is just another folder with a DocsLayout — no config. Any top-level folder under app/ that has a layout rendering DocsLayout becomes its own section with its own generated sidebar, breadcrumbs, prev/next, and (with lastUpdated) the "Last updated" / "Edit this page" line — the same traits as the main docs.
import { DocsLayout } from "@opentf/afw-docs"; import config from "../../afw.config.js"; export default function (props) { return ( <DocsLayout config={config.docs} frame={false}> {props.children} </DocsLayout> ); }
That's the whole thing — the same layout as app/docs/layout.jsx. DocsLayout reads the generated nav and scopes it to the current route, so app/api/** shows the /api sidebar (ordered by each folder's _meta.js). Add a third section by adding a folder and a copy of this file.
blog
Supplies settings for the blog components and release output. Register blogPostsPlugin explicitly to generate the post list. See Packages → afw-docs → Blog.
blog: { dir: "blog", title: "My Blog", lastUpdated: true }
i18n
Describes URL path-prefix locale routing for @opentf/afw-i18n. Pass these settings to the client mountApp and your prerender script to generate a static page per locale. Per-locale SSR requires locale detection in the request server.
i18n: { locales: ["en", "fr", "ja"], defaultLocale: "en", }
| Field | Type | Notes |
|---|---|---|
locales | string[] | All supported locales. |
defaultLocale | string | Served at the bare path; others are prefixed (/fr/…). |
See Packages → afw-i18n → Locale Routing for the full routing model and the message/formatting API.
Server routing and the legacy proxy setting
The old CLI interpreted afw.config.js's proxy map. The native compiler plugin and esdev do not apply that setting. A fullstack app's server entry owns backend routing, static assets and any forwarding to another runtime.
For a platform such as Workers, run the backend on its host's development runtime and configure forwarding in your app's server or an external proxy. Do not expect adding the old proxy key to enable it in esdev. See Server and Fetch handler.
esdev.json controls compilation, outputs and the development loop. afw.config.js supplies theme and prerender data; adding docs, blog or i18n there does not automatically install plugins or generate server entries.