Project-local presentation hooks for custom sections and docs forms.
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, 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.