Docs menu
IntegrationsDocusaurus
Docusaurus
Export a Docusaurus site to one PDF at build time: a plugin, a key in the environment, a link on the site.
The plugin reads the docs sidebars, collects the pages in sidebar order, joins them into one document with a cover and a contents list, and sends it to the legivel API. The PDF lands in the build output next to index.html, so the site can link it.
Each PDF carries the Markdown it was made from, so AI agents can read it exactly. The same Markdown is saved beside the PDF (see source).
Setup#
Create an API key
On the API keys page. A Free account includes 100 documents a month.
Install the plugin
npm install --save-dev docusaurus-plugin-legivelAdd it to the config
docusaurus.config.js// docusaurus.config.js module.exports = { // … plugins: [["docusaurus-plugin-legivel", { filename: "handbook.pdf" }]], };Build with the key in the environment
LEGIVEL_API_KEY="lgvl_your_key_here" npm run buildThe key is never an option: a key in the config is refused with a message that says where it belongs.
Link the file from the site
For example a navbar item. The plugin's own «Download PDF» button is on by default (see
buttonbelow).docusaurus.config.jsthemeConfig: { navbar: { items: [ { to: "/handbook.pdf", label: "Download the PDF", position: "right", target: "_blank", }, ], }, },
Every PDF rendered counts as one document of the account's plan: the manual on every build (see rebuild), each module on every build, each page PDF only when it changed. The build log ends with the count.
Options#
Every option is optional. A wrong value stops the build with a sentence that names it.
| Name | Type | Description |
|---|---|---|
filename | string | The file name in the build output. No folder, must end in .pdf. The default is docs.pdf. |
sections | string[] | Sidebar ids, or doc id prefixes such as guides/, to include. Every sidebar when omitted. |
exclude | string[] | Doc ids, or doc id prefixes, to leave out. A page with pdf: false in its front matter stays out too. |
version | string | The docs version to export, by name (current) or label (2.0), for a versioned site. The site's default when omitted. |
locales | string[] | The locales that get a PDF. Docusaurus builds each locale on its own; each build writes its PDF into its own output. Every locale when omitted. |
pageBreaks | string | chapters, the default, starts a new page before each top-level sidebar entry; pages before every page. |
modules | boolean | string[] | true: one PDF per top-level sidebar entry beside the manual, as handbook-<entry>.pdf; or a list of the entries wanted, by category label or doc id. Off by default. |
pages | boolean | true: one PDF per page under handbook/<doc id>.pdf, rendered again only when the page or a setting changed since the last build. Off by default. |
themes | string[] | ["light", "dark"] renders both; the dark files carry -dark. The button serves the one the visitor reads in. The default is ["light"]. |
button | boolean | A «Download PDF» button at the top of every docs page: the page's own PDF when there is one, else its module's, else the manual. On by default. |
credit | boolean | The line «PDF made with legivel» under the button, linking to legivel.com. A Free account keeps it; a paid plan may set false. The PDF itself carries no credit. |
cover | boolean | object | true, the default, for the site title and tagline; false for none; or { title, subtitle }. |
page | object | The page settings of the API under their own names: size (A4, Letter, A5 landscape, 210mm 297mm), margin (CSS order), header, footer, numbering, first. See the render reference. |
features | object | The feature switches of the API under their own names: theme (light or dark), mermaid, math, archive, accessible, hyphenation, … |
resources | string | lenient, the default, leaves a missing image out; strict fails the build on it. |
language | string | A language tag such as en or de; sets hyphenation and is written into the PDF. The site's locale when omitted. |
sign | object | The sign setting of the API: seals the PDF with the account's certificate. See Sealing. |
rebuild | boolean | true, the default, renders on every build, so the PDF never goes stale. false renders only when a page or a setting changed since the last build and reuses the last PDF otherwise. |
source | boolean | Attaches the Markdown to the PDF as document.md (readable by AI agents and by any PDF reader's attachments pane) and saves it beside the PDF, as handbook.md next to handbook.pdf. On by default. |
docsPluginId | string | The docs plugin instance to export when a site has several. The default is default. |
keyEnv | string | The environment variable that holds the key. The default is LEGIVEL_API_KEY. |
Defaults for a manual, where the config sets nothing else: the page number reads «Page X of Y», in the footer center or beside the footer text; the cover carries no header, footer or number; the language is the site's locale.
A fuller config:
plugins: [
[
"docusaurus-plugin-legivel",
{
filename: "handbook.pdf",
sections: ["docs"],
modules: true,
themes: ["light", "dark"],
cover: { title: "Product handbook", subtitle: "Built from the docs" },
page: { size: "A4", footer: "Product handbook" },
features: { math: true, archive: true },
language: "en",
},
],
],Free accounts#
A Free account renders up to 20 pages per document. When the manual is longer, the plugin renders the first chapters that fit (a chapter is a top-level sidebar entry with its children) and ends the PDF with a short note that the full manual needs a Starter plan. The build log says the same, with the page count. The tries that are refused for their length spend no document; the one PDF does.
What the PDF contains#
- The cover, when on, on a page of its own: the title, the subtitle, the version on a versioned site, the site address and the build date.
- A contents list with page numbers on the next page, and the PDF's bookmarks, both following the sidebar tree: a top-level entry is a chapter, its children sit under it. A category that links to a page puts that page first; a category without one is a heading of its own, with its generated index's description.
- Each chapter on a new page, in sidebar order, the page's own headings one level below its title. Drafts, unlisted pages and excluded pages stay out.
- Markdown as written: paragraphs, lists, tables, code blocks with their titles, diagrams in
mermaidfences, math, images. See What renders. - Every link works in the PDF: a link to a page of the export, or to a part of the same page, goes to its heading; a link to anything else on the site (a page left out, a blog post, another docs instance, a relative path) carries the full address on the site; a link to another website stays as written.
- Images with a path relative to the file, or a site path under
static/, embedded from disk at build time, up to the plan's resource allowance per document (nine tenths of it; the rest are left out with their alt text and one line in the log). A site path not on disk is loaded from the site'surl. Should the document still be refused for its size, the plugin halves the image budget and sends it again, down to no images; a refused try spends no document. - The Markdown the PDF was made from, attached inside the PDF and saved beside it (
source: falseleaves both out).
What becomes Markdown, and what is left out#
Docusaurus pages are MDX. What has a plain reading becomes Markdown; the rest is left out and named in the build log with its file:
<Tabs>: every tab's content stays, one tab after another, each under its label in bold.- A partial imported from a Markdown file (
import Part from './_part.mdx', placed as<Part />) is read in place. <details>becomes its summary in bold and its text.- An
<iframe>(a sandbox, a video) cannot play on paper: it becomes one line, «Embedded content:» and a link to its address, named by itstitleor the host. The log names each one. - A JSX attribute on an HTML tag (
<img src={'…'} width={200} style={{…}} />) becomes a plain one, or goes when it holds an object or an expression. :::note,:::tip,:::info,:::warning,:::danger: a quoted block whose first line is the title, or the kind, in bold.- A code block's
title="…"becomes a bold line above the block;showLineNumbersand line marks go, the language stays. importandexportlines are removed.- Any other component (
<MyWidget />, a JSX block) is removed with its content; the log names the component and the file.
Every change appears in the build log as [legivel-pdf] <doc id> (<file>): ….
Errors#
A failure stops the build with the API's own sentence and code, for example:
docusaurus-plugin-legivel: legivel answered 401 unauthorized: The API key is missing or not valid. Send it as "Authorization: Bearer <key>". Check the key in the environment variable; it starts with lgvl_ and is shown once on the API keys page.The key never appears in the log, in an error or in the output. The codes are the API's, listed under Errors and quota.
Requirements#
Docusaurus 3 with @docusaurus/plugin-content-docs (checked on 3.1.0 and 3.10.2), Node 18 or newer. LEGIVEL_PDF_DEBUG=1 on the build keeps every document the plugin sends under .docusaurus/legivel-pdf/debug/.