Skip to main content

PDF Export

Doom provides powerful PDF export capabilities that transform your documentation into professional, print-ready PDF files. The feature includes automatic table of contents generation, custom styling, multi-language support, and selective content export.

Quick Start

Export your entire documentation to PDF:
# Build the documentation first
doom build

# Export to PDF
doom export
This generates PDF files in your output directory (default: dist/).

How It Works

The export process:
  1. Builds your documentation (if not already built)
  2. Serves the built site locally
  3. Crawls pages based on sidebar configuration
  4. Renders each page using Puppeteer
  5. Combines pages into PDF with outlines
  6. Generates separate PDFs per language and scope
The export command uses the @alauda/doom-export package internally, which provides advanced PDF generation features.

Configuration

Configure PDF export in your doom.config.yml:
# Define what to export
export:
  # Export a specific section
  - name: user-guide
    scope: '*/usage/*'
  
  # Export multiple sections
  - name: api-reference
    scope: '*/apis/*'
  
  # Export specific paths
  - name: getting-started
    scope:
      - '*/guide/installation'
      - '*/guide/quickstart'
      - '*/guide/configuration'

Export Items

name
string
required
Name for the output PDF file (e.g., “user-guide” → “user-guide-en.pdf”)
scope
string | string[]
required
Glob patterns or paths to include in the export.Supports wildcards:
  • * matches the language directory (e.g., en, zh)
  • ** matches any nested directories
  • Specific paths can be provided as an array

Scope Patterns

export:
  - name: usage-docs
    scope: '*/usage/**'

Command Options

The doom export command accepts several options:
doom export [root] [options]
root
string
Root directory of the documentation (default: current directory)
--host, -H
string
default:"localhost"
Server host name for the preview server
--port, -P
string
default:"4173"
Server port number for the preview server
--ignore, -i
boolean
default:false
Ignore internal routes during export

Example Commands

# Export with custom port
doom export --port 3000

# Export with custom host
doom export --host 0.0.0.0 --port 8080

# Ignore internal routes
doom export --ignore

# Export from specific directory
doom export ./my-docs

Automatic Exclusions

The export automatically excludes:
  • API routes: apis/** and */apis/** (unless explicitly included)
  • Internal routes: Routes defined in internalRoutes config
  • Hidden pages: Pages with hidden: true in frontmatter
To include API documentation in exports, add it to the export configuration with includeApisPages: true.

PDF Generation Options

The export uses sophisticated PDF generation with these built-in settings:

Page Margins

{
  margin: {
    top: 40,
    right: 40,
    bottom: 40,
    left: 40
  }
}

Headers & Footers

Custom HTML templates for headers and footers:
<!-- Header Template -->
<div style="
  margin-top: -0.4cm;
  height: 70%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: lightgray;
  border-bottom: solid lightgray 1px;
  font-size: 10px;
">
  <span class="title"></span>
</div>

<!-- Footer Template -->
<div style="
  margin-bottom: -0.4cm;
  height: 70%;
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  color: lightgray;
  border-top: solid lightgray 1px;
  font-size: 10px;
"></div>

Printer Options

{
  ignoreHTTPSErrors: true,
  initScripts: [
    // Force light theme for printing
    async () => {
      localStorage.setItem('rspress-theme-appearance', 'light')
      localStorage.setItem('rspress-visited', '1')
    }
  ],
  outlineContainerSelector: '.rp-doc',
  outlineExcludeSelector: '.rp-toc-exclude *'
}

Multi-Language Export

Doom automatically generates separate PDFs for each language:
lang: en
themeConfig:
  locales:
    - lang: en
      label: English
    - lang: zh
      label: 中文
    - lang: ru
      label: Русский
With this configuration, running doom export produces:
  • Documentation-en.pdf
  • Documentation-zh.pdf
  • Documentation-ru.pdf

Custom Export Names

When using the export config, files are named based on the export item:
export:
  - name: installation-guide
    scope: '*/guide/installation'
Generates:
  • installation-guide-en.pdf
  • installation-guide-zh.pdf
  • installation-guide-ru.pdf

Table of Contents

The export automatically generates a hierarchical table of contents based on:
  1. Sidebar structure from _meta.json files
  2. Page headings within each document
  3. Nested sections and subsections

Custom Outlines

The export includes intelligent outline generation:
// Automatically creates PDF outlines matching sidebar structure
{
  title: 'Getting Started',
  to: 0,
  children: [
    {
      title: 'Installation',
      to: 3,
      children: []
    },
    {
      title: 'Configuration',
      to: 8,
      children: []
    }
  ]
}

Advanced Configuration

Including API Routes

By default, API routes are excluded. To include them:
export:
  - name: complete-api-reference
    scope:
      - '*/apis/references/**'
      - '*/apis/kubernetes_apis/**'
The export process detects API routes by pattern matching:
  • Routes starting with apis/
  • Routes matching */apis/** pattern

Version-Specific Exports

Export specific versions:
multiVersion:
  default: v2.0
  versions:
    - v1.0
    - v2.0

export:
  - name: v1-guide
    scope: 'v1.0/**'
  - name: v2-guide
    scope: 'v2.0/**'

Scoped Exports

Create targeted exports for different audiences:
export:
  # For end users
  - name: user-guide
    scope:
      - '*/getting-started'
      - '*/usage/**'
      - '*/tutorials/**'
  
  # For developers
  - name: developer-guide
    scope:
      - '*/api/**'
      - '*/development/**'
      - '*/contributing'
  
  # For administrators
  - name: admin-guide
    scope:
      - '*/installation'
      - '*/configuration/**'
      - '*/maintenance/**'

Page Collection

The export collects pages by:
  1. Reading the sidebar configuration
  2. Extracting all page links
  3. Filtering based on scope patterns
  4. Removing duplicates
  5. Ordering based on sidebar structure

Example Collection Process

1

Scan Sidebar

Read the sidebar structure for the specified language/version
2

Extract Links

Collect all page links from sidebar items and nested groups
3

Apply Scope Filter

Match links against the configured scope patterns
4

Generate PDF

Render each page and combine into final PDF with table of contents

Customization

Custom Naming

The default PDF naming uses:
{title}-{lang}.pdf
With export items:
{export-name}-{lang}.pdf
The naming is handled by the getPdfName utility from ~/workspace/source/packages/doom/src/cli/export.ts:23. Add print-specific styles to your documentation:
@media print {
  /* Hide navigation in PDF */
  .nav-bar,
  .sidebar {
    display: none !important;
  }
  
  /* Optimize for print */
  body {
    font-size: 10pt;
    line-height: 1.4;
  }
  
  /* Page breaks */
  h1, h2 {
    page-break-after: avoid;
  }
  
  pre, code {
    page-break-inside: avoid;
  }
}

Query Parameters

Pages are loaded with ?print query parameter for print-specific rendering:
{
  path: base + link + '.html?print'
}
This allows you to customize rendering for PDF export in your components:
const isPrintMode = new URLSearchParams(window.location.search).get('print')

if (isPrintMode) {
  // Render print-optimized version
}

Troubleshooting

Build Required

Error: “Please build the documentation first”
Run doom build before doom export:
doom build
doom export
Or use a npm script to chain commands:
{
  "scripts": {
    "docs:export": "doom build && doom export"
  }
}

No Pages Found

Warning: “Cannot find matched scope”
  1. Check that your scope patterns match actual routes
  2. Verify the sidebar configuration includes the pages
  3. Ensure the language directory exists
  4. Use glob pattern testing to validate your patterns
# Test pattern matching
ls -R docs/en/usage/

Memory Issues

For very large documentation:
Increase Node.js memory limit:
NODE_OPTIONS="--max-old-space-size=4096" doom export
Or export in smaller chunks:
export:
  - name: part-1
    scope: '*/guide/**'
  - name: part-2
    scope: '*/reference/**'

Timeout Errors

If pages timeout during rendering:
  1. Check for JavaScript errors in the built documentation
  2. Ensure all resources (images, scripts) load correctly
  3. Test the built site locally: doom preview
  4. Look for infinite loops or heavy computations

Best Practices

Test Build First

Always test doom preview before exporting to catch rendering issues early.

Use Descriptive Names

Choose clear export names that describe the content (e.g., “api-reference”, “user-guide”).

Optimize Images

Compress images to reduce PDF file size without sacrificing quality.

Test PDF Output

Review generated PDFs to ensure formatting, links, and layout are correct.

Integration Examples

CI/CD Pipeline

# .github/workflows/docs.yml
name: Build and Export Docs

on:
  push:
    branches: [main]

jobs:
  export:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: yarn install
      
      - name: Build documentation
        run: yarn doom build
      
      - name: Export to PDF
        run: yarn doom export
      
      - name: Upload PDFs
        uses: actions/upload-artifact@v3
        with:
          name: documentation-pdfs
          path: dist/*.pdf

NPM Scripts

{
  "scripts": {
    "docs": "doom dev",
    "docs:build": "doom build",
    "docs:export": "doom build && doom export",
    "docs:preview": "doom preview"
  }
}

Auto Sidebar

Configure sidebar structure that controls PDF export organization

Translation

Export documentation PDFs for multiple languages automatically

Build docs developers (and LLMs) love