Skip to Content
Fumadocs

Export EPUB

Export your documentation to EPUB format for e-readers

Introduction

The EPUB integration lets you export your Fumadocs documentation as an EPUB file, making it easy for readers to download and read your docs on e-readers, tablets, or any EPUB-compatible app.

It converts your MDX content to HTML, resolves images, and produces a standards-compliant EPUB with a table of contents.

Setup

Fumadocs CLI can set it up for you. It creates the export route, protected by an EXPORT_SECRET, and enables includeProcessedMarkdown:

npx @fumadocs/cli feature epub

Or manually:

Installation

npm install fumadocs-epub

Enable Processed Markdown

EPUB export requires includeProcessedMarkdown in the integration options:

astro.config.mjs
import { defineConfig } from 'astro/config';
import fumadocs from '@fumadocs/astro';

export default defineConfig({
  integrations: [
    fumadocs({
      includeProcessedMarkdown: { output: 'function' }, 
    }),
  ],
});

Create Export Route

createEpubExportAPI builds the route handler. It is guarded by secret: without a matching Authorization: Bearer <secret> header the request is rejected, and the route answers 503 when the secret itself is unset.

src/pages/export/epub.ts
import type { APIRoute } from 'astro';
import { source } from '@/lib/source';
import { createEpubExportAPI } from 'fumadocs-epub';
import { getSecret } from 'astro:env/server';

// render per request, needs an adapter
export const prerender = false;

const api = createEpubExportAPI({
  source,
  title: 'My Documentation',
  secret: getSecret('EXPORT_SECRET'),
});

export const GET: APIRoute = ({ request }) => api.GET(request);

For a public endpoint, or to build the file yourself (e.g. in a script), call exportEpub() directly and return the buffer.

Using the CLI

You can also export EPUB via the Fumadocs CLI:

fumadocs export epub --framework astro

It fetches the file from your running server on port 4321 (or PORT), with the EXPORT_SECRET env var as the secret.

Options

Both exportEpub and createEpubExportAPI accept these options:

OptionTypeDescription
titlestringRequired. Book title
authorstring | string[]Author name(s). Default: 'anonymous'
descriptionstringBook description
languagestringLanguage code (e.g. 'en'). Default: 'en'
publisherstringPublisher name. Default: 'anonymous'
isbnstringISBN
coverstringCover image. Supports file://, http(s)://, /public/..., or relative paths
outputPathstringIf set, writes the EPUB to file in addition to returning the buffer
includePages(page) => booleanFilter: include only pages where this returns true
excludePages(page) => booleanFilter: exclude pages where this returns true
cssstringCustom CSS for the EPUB. Uses defaultEpubStyles if omitted
publicDirstringPublic directory for resolving /public/... image paths. Default: ./public

createEpubExportAPI adds two more: secret (required, guards the route) and filename (the downloaded file name, default docs.epub).

Custom CSS

You can override the default EPUB styles:

import { exportEpub, defaultEpubStyles } from 'fumadocs-epub';

const buffer = await exportEpub({
  source,
  title: 'My Docs',
  author: 'Me',
  css: `${defaultEpubStyles}
/* Custom overrides */
body { font-size: 1.1em; }
`,
});

Filtering Pages

Use includePages and excludePages to control which docs are exported:

const buffer = await exportEpub({
  source,
  title: 'My Docs',
  author: 'Me',
  // Only include docs under /docs/getting-started
  includePages: (page) => page.path.startsWith('getting-started'),
  // Exclude specific paths
  excludePages: (page) => page.path === 'changelog',
});

Image Resolution

Images in your MDX are resolved automatically:

  • Relative paths (e.g. ./image.png): resolved relative to the page file
  • Public paths (e.g. /og.png): resolved from the public directory
  • Remote URLs (e.g. https://...): embedded as-is

How is this guide?

Last updated on