Lifecycle Hooks
PluginLifecycleHooks — hooks del ciclo de vida de build y dev, cadenas de transformación y señales de cadena para plugins de Boltdocs.
hooks — PluginLifecycleHooks
Los hooks del lifecycle son la forma principal en que los plugins
inyectan comportamiento en el pipeline de Boltdocs. Cada hook recibe
un PluginContext como primer argumento y puede ser síncrono o
asíncrono.
Hooks del Pipeline de Frontmatter & Rutas
| Hook | Firma | Descripción |
|---|---|---|
frontmatter:transform | (ctx, { frontmatter, filePath, rawContent }) => Record<string, unknown> | void | Intercepta y enriquece el frontmatter (tiempo de lectura, fecha de actualización, autores, metadata custom). |
routes:resolved | (ctx, { routes }) => RouteMeta[] | void | Se ejecuta después de escanear, normalizar y ordenar todas las rutas de la documentación. |
ts
import { definePlugin } from 'boltdocs'
export default definePlugin({
name: 'mi-plugin-metadata',
hooks: {
'frontmatter:transform'(ctx, { frontmatter, rawContent }) {
const words = rawContent.split(/\s+/).length
return {
...frontmatter,
readingTime: Math.ceil(words / 200),
wordCount: words,
}
},
'routes:resolved'(ctx, { routes }) {
ctx.logger.info(`Resueltas ${routes.length} rutas en total.`)
},
},
})
Hook Contrato de Búsqueda (search:index)
| Hook | Firma | Descripción |
|---|---|---|
search:index | (ctx, { documents, routes }) => unknown | Promise<unknown> | Hook de índice de búsqueda estandarizado. Recibe SearchDocument[] para generar índices de búsqueda (FlexSearch, Pagefind, Algolia, Meilisearch). |
Interfaz SearchDocument
ts
interface SearchDocument {
id: string
path: string
title: string
content: string
headings: Array<{ level: number; text: string; id: string }>
frontmatter: Record<string, unknown>
locale?: string
version?: string
}
ts
import { definePlugin } from 'boltdocs'
export default definePlugin({
name: 'mi-plugin-busqueda',
hooks: {
'search:index'(ctx, { documents }) {
ctx.logger.info(`Indexando ${documents.length} documentos para búsqueda...`)
// Compilar índice...
},
},
})
Hooks del ciclo de vida de Dev y Servidor
| Hook | Firma | Cuándo se ejecuta |
|---|---|---|
dev:before | (ctx: PluginContext) => void | Promise<void> | Antes de que el dev server comience a escuchar |
dev:after | (ctx: PluginContext) => void | Promise<void> | Después de que el dev server esté completamente inicializado |
server:configure | (ctx: PluginContext, { server, middleware }) => void | Promise<void> | Configura middlewares HTTP y endpoints API en dev y preview |
ts
import { definePlugin } from 'boltdocs'
export default definePlugin({
name: 'mi-plugin-dev',
hooks: {
'dev:before'(ctx) {
ctx.logger.info('Iniciando dev server...')
},
'server:configure'(ctx, { middleware }) {
middleware.useAt('/api/feedback', (req, res) => {
res.end(JSON.stringify({ status: 'ok' }))
})
},
'dev:after'(ctx) {
ctx.logger.info('Dev server listo!')
},
},
})
Hooks de cadena de transformación
Estos hooks forman una cadena — la salida de un plugin alimenta la
entrada del siguiente. Se ejecutan en orden enforce (pre → normal
→ post) dentro de cada fase.
| Hook | Firma | Cuándo se ejecuta |
|---|---|---|
transform:source | (ctx, { code, filePath, frontmatter? }) => { code, __signal? } | En el fuente MDX antes de la compilación MDX |
transform:mdx | (ctx, { code, filePath, frontmatter? }) => { code, __signal? } | En el JavaScript MDX compilado después de la compilación |
transform:html | (ctx, { html, path, route? }) => { html, __signal? } | En el HTML renderizado durante la generación SSG |
TransformSourceParams
ts
interface TransformSourceParams {
code: string
filePath: string
frontmatter?: Record<string, unknown>
}
TransformHtmlParams
ts
interface TransformHtmlParams {
html: string
path: string
route?: RouteMeta
}
Resultado de transformación & ChainSignal
ts
type ChainSignal = 'skip' | 'break'
type TransformResult<T> = T & { __signal?: ChainSignal }
| Señal | Comportamiento |
|---|---|
__signal: 'skip' | La salida de este hook se descarta; los params originales pasan al siguiente plugin |
__signal: 'break' | La cadena se detiene inmediatamente — ningún plugin adicional se ejecuta |
ts
import { definePlugin } from 'boltdocs'
export default definePlugin({
name: 'mi-plugin-transform',
hooks: {
async transformSource(ctx, { code }) {
const transformed = code
.replace(/\$\$(.+?)\$\$/gs, '<BlockMath>$1</BlockMath>')
.replace(/\$(.+?)\$/g, '<Math>$1</Math>')
return { code: transformed }
},
async transformHtml(ctx, { html }) {
return {
html: html.replace('</body>', '<footer>© 2026 Mis Docs</footer></body>'),
}
},
},
})
Orden de ejecución
text
beforeBuild / beforeDev
→ frontmatter:transform
→ routes:resolved
→ transformSource (cadena: pre → normal → post)
→ Compilación MDX
→ transformMdx (cadena: pre → normal → post)
→ Renderizado HTML (SSG)
→ transformHtml (cadena: pre → normal → post)
→ search:index
→ build:generate
afterBuild / afterDev
buildEnd
Ver también
- PluginContext — objeto de contexto base
- definePlugin y Slots de UI — definición de plugins e inyección de slots
- Middleware — pipeline de middleware de transformación
- Descripción general del Sistema de Plugins — arquitectura, conceptos, inicio rápido
Last updated on October 18, 2026