Integrations
OpenAPI, Mermaid, KaTeX, search, analytics — the integrations Publier ships or auto-detects, and how to add your own.
Publier sits on top of Astro 7, so every Astro integration works. Publier auto-wires the ones you actually need (MDX, resumable islands, syntax highlighting, Mermaid when present) and reads declarative opt-ins from publier.config.yaml for analytics, fonts, and content variables.
@publier/openapi
Generate MDX pages and interactive components from an OpenAPI 3.x or AsyncAPI 2/3 spec. The API Reference section of this site is built with it.
pnpm add @publier/openapiPoint publier.config.yaml at your spec and Publier auto-generates pages under /api at build time:
integrations: openapi: ./openapi.yaml # or an array of paths for multi-spec merge asyncapi: ./events.yamlOr call the server-side API yourself for full control:
import { generateFiles } from '@publier/openapi/generate';import { readFileSync } from 'node:fs';import { parse } from 'yaml';
generateFiles({ spec: parse(readFileSync('./openapi.yaml', 'utf-8')), outputDir: './src/content/docs/api', groupBy: 'tag', per: 'operation',});The generator emits one MDX file per operation (with per: 'operation', the default shown above) plus a meta.yaml per group subdirectory that orders them on the sidebar.
See the OpenAPI guide for the full walkthrough.
Search
Publier’s search is powered by Pagefind. After every build, the scanner runs against your emitted HTML and writes a static index that ships alongside your site. There’s no server component and no proprietary index format.
Zero-config — docsShell() wires up the search modal and the index automatically. The dialog opens on ⌘K or the header search button and inherits your theme tokens, so it matches the rest of the site in both light and dark mode.
To opt out of search entirely:
import { docsShell } from '@publier/shell/integration';export default defineConfig({ integrations: [docsShell({ search: false })],});When search: false, the dialog is skipped; the header search button becomes a no-op unless you wire your own publier:search-toggle listener.
Dev-server note: the index is only generated at build time. On a brand-new clone with no prior build, the dialog opens but shows “Search index not ready yet — run a production build to generate it.” Run publier build once; subsequent publier dev sessions serve the previously-built index transparently.
Diagrams — Mermaid
Install the packages and Publier picks them up automatically. No config changes.
pnpm add astro-mermaid mermaidThen use fenced mermaid blocks in any MDX file:
```mermaidflowchart LR A[MDX] --> B(Publier) --> C[Static HTML]```Dark/light theme follows ThemeToggle automatically.
To disable Mermaid even when the packages are installed, pass docsShell({ mermaid: false }) explicitly.
Math — KaTeX
Install the peer deps and opt in via docsShell({ math: true }):
pnpm add remark-math rehype-katex kateximport { defineConfig } from 'astro/config';import tailwind from '@tailwindcss/vite';import { docsShell } from '@publier/shell/integration';
export default defineConfig({ integrations: [docsShell({ math: true })], vite: { plugins: [tailwind()] },});Then write inline or display math in any MDX file:
Inline: $E = mc^2$
Block:$$\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}$$See the Math Equations guide for the full reference.
Analytics
Declare analytics in publier.config.yaml — Publier injects the provider snippets into <head> at build time. Five providers are supported out of the box, plus arbitrary custom scripts.
Google Analytics 4
analytics: ga4: measurementId: G-XXXXXXXXXXPostHog
analytics: posthog: apiKey: phc_xxxxxxxx host: https://app.posthog.com # optional, defaults to https://app.posthog.comPlausible
analytics: plausible: domain: example.com selfHosted: https://plausible.my-host.com # optional, for self-hosted instancesFathom
analytics: fathom: siteId: ABCDEFGHUmami
analytics: umami: websiteId: 00000000-0000-0000-0000-000000000000 src: https://analytics.my-host.com/script.jsCustom scripts
Need a tag that isn’t one of the built-in providers? Add arbitrary scripts:
analytics: scripts: - src: https://my-cdn.example.com/my-tag.js async: true - content: "window.dataLayer = window.dataLayer || [];" placement: headAll scripts respect placement: head | body and the async / defer flags.
Custom fonts
Declare web fonts in publier.config.yaml — Publier injects the <link>/@font-face declarations and overrides the --font-sans / --font-serif / --font-mono CSS variables:
fonts: heading: family: Inter googleFontsUrl: https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap body: family: Inter googleFontsUrl: https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap mono: family: JetBrains Mono src: /fonts/JetBrainsMono-Regular.woff2 weight: "400"Google Fonts and local @font-face sources are both supported; local files are referenced relative to public/.
Content variables
Centralize repeated strings (version numbers, product names, URLs) in publier.config.yaml:
vars: productName: My Product version: "2.5.0"Use them with {{key}} interpolation in any MDX/Markdown text:
Install {{productName}} v{{version}}: `pnpm add my-product@{{version}}`.Need help? Email {{supportEmail}}.Code blocks are not interpolated — placeholders inside fenced code are rendered literally.
Adding your own remark/rehype plugins
Publier auto-wires the standard plugins. Append your own via Astro’s markdown config:
import { defineConfig } from 'astro/config';import { docsShell } from '@publier/shell/integration';import remarkSmartypants from 'remark-smartypants';import rehypeExternalLinks from 'rehype-external-links';
export default defineConfig({ integrations: [docsShell()], markdown: { remarkPlugins: [[remarkSmartypants, { dashes: 'oldschool' }]], rehypePlugins: [[rehypeExternalLinks, { target: '_blank', rel: ['noopener'] }]], },});User plugins run after Publier’s built-ins. See Plugins for the full list and execution order.