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 epubOr manually:
Installation
npm install fumadocs-epubEnable Processed Markdown
EPUB export requires includeProcessedMarkdown in your docs collection config:
import { defineDocs } from 'fumadocs-mdx/config';
export const docs = defineDocs({
docs: {
postprocess: {
includeProcessedMarkdown: true,
},
},
});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.
import { source } from '@/lib/source';
import { createEpubExportAPI } from 'fumadocs-epub';
export const revalidate = false;
export const { GET } = createEpubExportAPI({
source,
title: 'My Documentation',
author: 'My Team',
description: 'Documentation for my project',
cover: '/cover.png',
secret: process.env.EXPORT_SECRET,
});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 next
# or: astro | tanstack-start | react-router | wakuThis fetches from your running server (Next.js) or copies from the build output (other frameworks). Run a production build first for non-Next.js frameworks.
Options
Both exportEpub and createEpubExportAPI accept these options:
| Option | Type | Description |
|---|---|---|
title | string | Required. Book title |
author | string | string[] | Author name(s). Default: 'anonymous' |
description | string | Book description |
language | string | Language code (e.g. 'en'). Default: 'en' |
publisher | string | Publisher name. Default: 'anonymous' |
isbn | string | ISBN |
cover | string | Cover image. Supports file://, http(s)://, /public/..., or relative paths |
outputPath | string | If set, writes the EPUB to file in addition to returning the buffer |
includePages | (page) => boolean | Filter: include only pages where this returns true |
excludePages | (page) => boolean | Filter: exclude pages where this returns true |
css | string | Custom CSS for the EPUB. Uses defaultEpubStyles if omitted |
publicDir | string | Public 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 thepublicdirectory - Remote URLs (e.g.
https://...) — embedded as-is
How is this guide?
Last updated on
