Plugins
Davaux plugins let you extend the framework in two ways: adding esbuild transforms to the build pipeline, and registering new route file suffixes so the scanner recognises them. Both capabilities are exposed through a single DavauxPlugin interface.
Using plugins
Pass plugins to davaux.config.ts:
// davaux.config.ts
import { defineConfig } from 'davaux/config'
import { markdown } from '@davaux/markdown'
import { mdx } from '@davaux/mdx'
export default defineConfig({
plugins: [markdown(), mdx()],
})
Plugin esbuild contributions are added to every build context — server routes, the islands client bundle, and the optional user client bundle. Scanner suffix entries extend which files the route scanner picks up.
Official plugins
| Package | Route suffix | Description |
|---|---|---|
@davaux/markdown | .page.md | Markdown routes with YAML frontmatter |
@davaux/mdx | .page.mdx | MDX routes — markdown with JSX component imports |
Authoring a plugin
A plugin is a factory function that returns a DavauxPlugin object:
import type { DavauxPlugin } from 'davaux/config'
export function myPlugin(): DavauxPlugin {
return {
name: 'my-plugin',
esbuild: [myEsbuildPlugin()],
scanner: {
suffixes: [['.page.myext', 'page']],
},
}
}
DavauxPlugin fields:
| Field | Type | Description |
|---|---|---|
name | string | Unique identifier, used in error messages |
esbuild | Plugin[] | esbuild plugins added to all build contexts |
scanner.suffixes | [string, RouteType][] | File suffix + route type pairs for the scanner |
RouteType is 'page' | 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options'.
Example: a YAML front-matter page plugin
This example adds .page.yaml as a route type that renders a simple data dump page — a minimal but complete plugin:
import type { Plugin } from 'esbuild'
import type { DavauxPlugin } from 'davaux/config'
import { readFileSync } from 'node:fs'
function yamlPagePlugin(): Plugin {
return {
name: 'davaux-yaml-page',
setup(build) {
build.onLoad({ filter: /\.page\.yaml$/ }, (args) => {
const raw = readFileSync(args.path, 'utf-8')
// Real implementation would parse YAML; this serialises the raw string
const contents = `
import { definePage } from 'davaux'
export default definePage((ctx) => {
ctx.head.title = 'YAML Data'
return \`<pre>\${${JSON.stringify(raw)}}</pre>\`
})
`
return { contents, loader: 'ts' }
})
},
}
}
export function yaml(): DavauxPlugin {
return {
name: 'davaux-yaml',
esbuild: [yamlPagePlugin()],
scanner: { suffixes: [['.page.yaml', 'page']] },
}
}
esbuild plugin context
Davaux runs three separate esbuild build contexts:
- Server routes — all files under
src/routes/andsrc/islands/(server JSX runtime) - Islands client bundle — island files recompiled with the client JSX runtime
- User client bundle —
src/client.tsif present
Your plugin's esbuild array is added to all three contexts. If your transform only makes sense in one context (e.g. a server-only loader), check the build options or use a filter that matches only the relevant files.
Scanner suffixes
The scanner looks for files matching known suffixes to build the route manifest. Without registering a suffix, files with your custom extension are silently ignored even if they export the right define* wrappers.
The suffix registration format is [suffix, routeType]:
scanner: {
suffixes: [
['.page.md', 'page'], // GET page route
['.api.ts', 'get'], // explicit GET API route
]
}
Route type controls which HTTP methods the route responds to — 'page' responds to GET and HEAD, 'get' responds to GET only, and so on.