Project-local presentation hooks for custom sections and docs forms.
For the general definePlugin() setup API—MDX components, stable slots, theme component overrides, named layouts, styles, scripts, Markdown plugins, and search providers—see Presentation API → Presentation plugins. Those contributions and the collection/form hooks below share the same generated manifest and dev reload path.
Two axes
TidyPress separates content location from page model:
| Axis | Declared in | Use for |
|---|---|---|
| Collection | collections.<key> | a site section and base path |
| Doc form | docs frontmatter form | a page model inside the docs collection |
Folders build URLs. They do not declare page models.
Built-in docs forms
Docs pages support:
form | Layout |
|---|---|
doc | default docs page with sidebar, table of contents, and chapter navigation |
manual | procedural page chrome and step styling |
---
title: Install guide
form: manual
order: 1
---Doc pages can set part for chapter grouping:
---
title: Routing
part: Part I
order: 2
---Doc chapter navigation follows the configured sidebar order when present, then frontmatter order.
Custom collections
Add another section with a built-in kind:
collections: {
guides: {
enabled: true,
basePath: '/guides',
kind: 'content',
label: 'guides',
},
}Kinds: content, writing, projects, page.
Custom collection rendering
Project-local presentation code:
collections: {
api: {
enabled: true,
basePath: '/api',
kind: 'content',
render: {
presentation: './site/renderers/api-presentation.ts',
views: './site/views/api/',
},
},
}On tidypress dev and tidypress build:
- The config is validated.
- TidyPress writes a plugin manifest into the local cache (
~/.cache/tidypress/.../codegen/). - Custom Astro views resolve from your project via the
@projectalias. - The engine imports the presentation module.
RouteViewShelluses your view when a matching key exists.
Paths must be project-local ./ paths. Parent directory traversal is rejected.
collections.docs cannot set render. Docs pages use form.
Presentation module
Export createPresentation(site, context):
import type { TidyPressConfig } from '@tidypress/config'
import type { TidyPressPluginPresentation } from '@tidypress/engine/plugins'
export function createPresentation(
site: TidyPressConfig,
context: { collectionKey: string },
): TidyPressPluginPresentation {
return {
async buildIndex(route) {
return {
viewKey: `${context.collectionKey}:collection-index`,
site,
route,
title: 'API',
headings: [],
pagefindIgnore: true,
}
},
async buildEntry(route) {
return {
viewKey: `${context.collectionKey}:collection-entry`,
site,
route,
title: route.slug ?? 'API entry',
headings: [],
pagefindIgnore: false,
}
},
}
}Prefix view keys with the collection key.
Optional Astro views
If render.views points to ./site/views/api/, TidyPress looks for:
collection-index.astro
collection-entry.astro
version-root.astroMissing files are skipped. Built-in views are used as fallback.
Custom docs forms
Register custom forms with extensions.docForms:
extensions: {
docForms: {
'api-reference': {
label: 'API reference',
presentation: './site/renderers/api-reference-presentation.ts',
views: './site/views/api-reference/',
},
},
}Then use the form in docs frontmatter:
---
title: POST /v1/widgets
form: api-reference
---Built-in form names cannot be overridden.
Development reload
During tidypress dev, changes to config, presentation modules, and optional views regenerate the plugin manifest and reload the browser.
If a plugin path or export is invalid, TidyPress fails before the server starts. Fix the config path or module export and run again.