Configuration
This page documents all configuration options available in the notion-to-md v4 library. The library uses a builder pattern for configuration, making it easy to customize while maintaining readability.
NotionConverter Builder Methods
The main NotionConverter
class provides several builder methods to configure different aspects of the conversion process. The builder pattern makes configuration intuitive and type-safe.
Basic Configuration
const n2m = new NotionConverter(notionClient)
.configureFetcher({...}) // Configure block fetching behavior
.downloadMediaTo({...}) // Configure media downloading
.uploadMediaUsing({...}) // Configure media uploading
.withPageReferences({...}) // Configure page reference handling
.withRenderer(renderer) // Set custom renderer
.withExporter(exporter); // Add output exporter
Block Fetcher Configuration
Block Fetcher is responsible for retrieving content from the Notion API. Its configuration controls what data is fetched and how the process is optimized.
interface BlockFetcherConfig {
fetchPageProperties?: boolean; // Include page properties in output
fetchComments?: boolean; // Include comments in output
maxRequestsPerSecond?: number; // API rate limit (default: 3)
batchSize?: number; // Batch size for concurrent requests (default: 3)
trackMediaBlocks?: boolean; // Track blocks with media content
trackPageRefBlocks?: boolean; // Track blocks with page references
}
Field Explanations
fetchPageProperties: When
true
, notion page properties are included in the output. Essential for generating frontmatter in markdown or any other use case.fetchComments: When
true
, retrieves comments on blocks. Useful for collaborative workflows where comments might contain important information.maxRequestsPerSecond: Controls the API rate limiting to prevent hitting Notion’s limits. The default of 3 is safe, but you can adjust based on your API tier.
batchSize: Determines how many blocks are processed in parallel. Higher values improve performance but increase memory usage. The default of 3 balances performance and resource usage.
trackMediaBlocks: When
true
, identifies and tracks blocks containing media (images, files, etc.) for special processing. Automatically enabled when using media handlers.trackPageRefBlocks: When
true
, identifies and tracks blocks containing page references for link processing. Automatically enabled when using page reference handling.
Example
const n2m = new NotionConverter(notionClient).configureFetcher({
fetchPageProperties: true,
fetchComments: false,
maxRequestsPerSecond: 5,
batchSize: 10,
});
Media Handling Configuration
notion-to-md v4 offers media handling to ensure images and files are properly processed during conversion. Three strategies are available: downloading files locally (DownloadStrategy
), uploading to an external service (UploadStrategy
), or using direct Notion URLs, optionally with in-memory buffering (DirectStrategy
).
Direct Strategy (default)
This is the default strategy, when it’s not configured it’s default behavior is to keep original Notion URLs for media files in your output. This is the simplest strategy but relies on Notion’s temporary URLs, which might expire.
This strategy also supports optional in-memory buffering of media content and needs to be enabled through extra configuration. It adds an extra field to the block/property called buffer
. Proves to be useful in cases where media preprocessing is required.
/** Custom handler function type for DirectStrategy buffering */
export type CustomBufferHandler = (
/** The full reference object (block or property) being processed. */
reference: TrackedBlockReferenceObject, // Requires definition or import if not available
/** The index of the file within a property (undefined for blocks, only valid for properties). */
index: number | undefined,
/** The original URL of the media file. */
url: string,
) => Promise<Buffer>;
/** Configuration options specifically for buffering in DirectStrategy. */
export interface DirectStrategyBufferOptions {
/**
* Array specifying which reference types to enable buffering for.
* If `buffer` is set to `true` in `DirectStrategyConfig` and this is omitted,
* it defaults to `['block', 'database_property']`.
* To enable for page properties as well, use `['block', 'database_property', 'page_property']`.
* Provide an empty array `[]` to disable buffering even if `buffer` is `true`.
* See `MediaReferenceType` in Advanced Types.
* @default ['block', 'database_property']
*/
enableFor?: MediaReferenceType[];
/**
* **Only applies if 'block' is included in `enableFor`**.
* Array specifying which specific Notion media block content types should be buffered.
* If omitted, all supported media block types ('image', 'video', 'pdf', 'file')
* encountered within enabled 'block' references will be buffered.
* Example: `['image', 'pdf']` to only buffer images and PDFs found in blocks.
* See `NotionMediaBlockType` in Advanced Types.
*/
includeBlockContentTypes?: NotionMediaBlockType[];
/**
* Maximum buffer size in bytes for each media file.
* If a file exceeds this size, buffering will be skipped for that file.
* Set to `0` or `undefined` for no limit.
* @default 0
*/
maxBufferSize?: number;
/**
* Optional custom fetching logic per reference type.
* Allows providing specific functions to fetch and return a Buffer for
* 'block', 'database_property', or 'page_property' references.
* If a handler is provided for a type, it overrides the default fetch behavior for that type.
*/
handlers?: Partial<Record<MediaReferenceType, CustomBufferHandler>>;
}
interface DirectStrategyConfig {
/**
* Enables or configures in-memory buffering of media content.
* - `false` (default): Buffering is disabled. Original URLs are used.
* - `true`: Buffering is enabled with default options (buffers blocks and database properties).
* - `DirectStrategyBufferOptions`: Provide an object to customize buffering behavior (which types to buffer, size limits, custom handlers).
* When enabled, a `buffer` property (Node.js Buffer) is attached to the corresponding Notion block or property file object.
* @default false
*/
buffer?: boolean | DirectStrategyBufferOptions;
/** Continue processing other media references on errors. @default true */
failForward?: boolean;
}
Field Explanations
- buffer: Controls whether media content is fetched and stored in memory as a Node.js
Buffer
.- If
false
(default), only the original Notion URL is used. - If
true
, enables buffering with default settings (targets blocks and database properties). - If an object (
DirectStrategyBufferOptions
) is provided, allows fine-grained control over buffering (e.g., which types to buffer (enableFor
), which block content types (includeBlockContentTypes
), maximum size (maxBufferSize
), custom fetching logic (handlers
)). - When buffering is successful, the fetched
Buffer
is attached as abuffer
property directly onto the modified Notion block object (e.g.,image
,file
,video
,pdf
) or the specific file entry within afiles
property. Consumers (like renderers or transformers) can then access this raw data.
- If
- failForward: When
true
(default), continues processing other references even if fetching/buffering fails for one. Whenfalse
, errors during buffering will halt the conversion.
Example (Buffering Images and PDFs)
const n2m = new NotionConverter(notionClient)
// Use direct strategy with buffering enabled only for image/pdf blocks
.useDirectMediaStrategy({
buffer: {
enableFor: ['block'], // Only buffer block references
includeBlockContentTypes: ['image', 'pdf'], // Only buffer these block types
maxBufferSize: 5 * 1024 * 1024, // 5MB limit per file
},
});
// In a custom renderer/transformer:
function handleImageBlock(block: NotionImageBlock) {
if (block.buffer) {
// Use the buffer (e.g., create base64 data URI)
const base64 = block.buffer.toString('base64');
const mimeType = 'image/png'; // Determine actual mime type if possible
return `<img src="data:${mimeType};base64,${base64}" />`;
} else {
// Fallback to URL if buffer is missing (e.g., too large, fetch error)
return `<img src="${block.image.url}" />`;
}
}
Note: The builder method might be
.useDirectMediaStrategy({...})
or similar, depending on the actual implementation. Check the API reference. Using the Direct strategy without buffering requires no explicit configuration (new NotionConverter(notion)
would use it by default if no other strategy is specified, assuming it’s the default).
Download Strategy
Use this strategy when you want to save Notion media files to your local filesystem or server and refer to them in your output. Ideal for static site generation or when you are using some framework.
interface DownloadStrategyConfig {
outputDir: string; // Directory to save media files
transformPath?: (localPath: string) => string; // Transform file paths for output
preserveExternalUrls?: boolean; // Keep external URLs unchanged (default: false)
/**
* Specifies which types of media references this strategy should apply to.
* If omitted, defaults to all types: `['block', 'database_property', 'page_property']`.
* @default ['block', 'database_property', 'page_property']
*/
enableFor?: MediaReferenceType[];
failForward?: boolean; // Continue on errors (default: true)
}
Field Explanations
outputDir: The directory where media files will be saved. Must be accessible and writable by the application.
transformPath: A function that converts local file paths to the paths that will appear in the output. For example, converting
/server/path/image.jpg
to/public/images/image.jpg
. This ensures URLs in the output content correctly reference the media files.preserveExternalUrls: When
true
, doesn’t download media from external sources (non-Notion URLs). Keeps the original URLs in the output. Defaults tofalse
.enableFor: Decide which Notion media you want this strategy to handle based on where it is in Notion. You can specify an array with these options:
'block'
: For media placed directly within your page content (like image blocks, file blocks, PDFs).'database_property'
: For media found in ‘Files & media’ properties within database entries (like attachments in a table row).'page_property'
: For media in ‘Files & media’ properties on the page properties (not in a database), including page covers or icons if they are files uploaded to Notion. If you don’t set this option, the strategy will apply to media from all these locations by default (['block', 'database_property', 'page_property']
). For example, you could use['block']
if you only care about downloading images and files embedded directly in your page’s main content.
failForward: When
true
(default), continues processing even if a media file fails to download. The original URL will be used as a fallback. Whenfalse
, errors during media processing will halt the conversion.
Example
const n2m = new NotionConverter(notionClient).downloadMediaTo({
outputDir: './public/images',
transformPath: (localPath) => `/images/${path.basename(localPath)}`,
preserveExternalUrls: true,
});
Upload Strategy
Use this strategy when you want to upload Notion media to an external service like AWS S3, Cloudinary, or a custom storage system.
interface UploadStrategyConfig {
uploadHandler: (url: string, blockId: string) => Promise<string>; // Upload function
cleanupHandler?: (entry: MediaManifestEntry) => Promise<void>; // Cleanup function
transformPath?: (uploadedUrl: string) => string; // Transform URLs
preserveExternalUrls?: boolean; // Keep external URLs (default: false)
/**
* Specifies which types of media references this strategy should apply to.
* If omitted, defaults to all types: `['block', 'database_property', 'page_property']`.
* @default ['block', 'database_property', 'page_property']
*/
enableFor?: MediaReferenceType[];
failForward?: boolean; // Continue on errors (default: true)
}
Field Explanations
uploadHandler: A function that receives the original media URL and block ID, handles the upload process, and returns the new URL. This is where you implement your custom upload logic.
cleanupHandler: An optional function that cleans up media files when they’re no longer needed (e.g., when a block is deleted or changed). Helps prevent accumulating unused files. This is called internally when the media is no longer referenced.
transformPath: A function that transforms the URLs returned by your upload handler. Useful for adding CDN prefixes or modifying domains.
preserveExternalUrls: When
true
, doesn’t upload media from external sources. Keeps the original URLs in the output. Defaults tofalse
.enableFor: Decide which Notion media you want this strategy to handle based on where it is in Notion. You can specify an array with these options:
'block'
: For media placed directly within your page content (like image blocks, file blocks, PDFs).'database_property'
: For media found in ‘Files & media’ properties within database entries (like attachments in a table row).'page_property'
: For media in ‘Files & media’ properties on the page properties (not in a database), including page covers or icons if they are files uploaded to Notion. If you don’t set this option, the strategy will apply to media from all these locations by default (['block', 'database_property', 'page_property']
). For example, you could use['block']
if you only care about downloading images and files embedded directly in your page’s main content.
failForward: When
true
(default), continues processing even if media upload fails. The original URL will be used as a fallback. Whenfalse
, upload errors will halt the conversion.
Example
const n2m = new NotionConverter(notionClient).uploadMediaUsing({
uploadHandler: async (url, blockId) => {
// Upload file to S3/Cloudinary/etc
return 'https://cdn.example.com/uploaded-file.jpg';
},
cleanupHandler: async (entry) => {
// Delete file from storage when no longer needed
},
transformPath: (url) => url.replace('s3.amazonaws.com', 'cdn.example.com'),
});
Page Reference Configuration
The Page Reference handler manages links between Notion pages, ensuring they work properly in the output. This is especially important for websites or knowledge bases built from Notion content. You are required to provide URL where the page will be live once published. That will be used as reference for page links.
interface PageRefConfig {
UrlPropertyNameNotion?: string; // Property containing page URL
baseUrl?: string; // Base URL for page references
transformUrl?: (url: string) => string; // Custom URL transformation
}
Field Explanations
UrlPropertyNameNotion: The name of a Notion page property that contains the URL or slug for the page. If provided, this property’s value will be used instead of generating a URL from the page ID.
baseUrl: The base URL that will be prepended to page references. For example,
https://example.com/blog
will transform references tohttps://example.com/blog/page-slug
.transformUrl: A function that customizes how URLs are generated or transformed. Useful for implementing custom slug generation, URL normalization, or adding path prefixes.
Example
const n2m = new NotionConverter(notionClient).withPageReferences({
UrlPropertyNameNotion: 'slug',
baseUrl: 'https://example.com/blog',
transformUrl: (url) => url.toLowerCase().replace(/\s+/g, '-'),
});
Renderer Configuration
Renderers determine the output format of the conversion. notion-to-md v4 includes a default MDX renderer, but you can create custom renderers for any format.
MDX Renderer Configuration
The built-in MDX renderer supports frontmatter generation and customization.
interface FrontmatterConfig {
include?: string[]; // Properties to include
exclude?: string[]; // Properties to exclude
rename?: Record<string, string>; // Rename properties
transform?: Record<
string,
(
property: NotionPageProperty,
allProperties: NotionPageProperties,
) => string
>; // Transform functions
defaults?: Record<string, any>; // Default values
}
interface MDXRendererConfig {
frontmatter?: boolean | FrontmatterConfig; // Enable/configure frontmatter
}
Field Explanations
frontmatter: Controls frontmatter generation. Can be:
true
: Generate frontmatter from all page propertiesfalse
: Don’t generate frontmatterFrontmatterConfig
: Configure detailed frontmatter behavior
include: An array of property names to include in the frontmatter. If provided, only these properties will be used.
exclude: An array of property names to exclude from the frontmatter. Useful when you want most properties except specific ones.
rename: A mapping of original property names to new names. For example,
{ "Created time": "date" }
will rename the “Created time” property to “date” in the output.transform: A mapping where keys are property names and values are functions
(property: NotionPageProperty, allProperties: NotionPageProperties) => string
. These functions receive the Notion property object and all page properties, and it should return a transformed string value for the frontmatter. Useful for formatting dates, generating slugs, etc.defaults: Default values for properties that might be missing. These values will be used if the corresponding property doesn’t exist or is empty.
Note
The property names are case-sensitive. Meaning that “Title” and “title” are considered different properties.
Example
import { MDXRenderer } from 'notion-to-md/plugins/renderer/mdx';
import { NotionPageProperty, NotionPageProperties } from 'notion-to-md/types/notion';
const renderer = new MDXRenderer({
frontmatter: {
include: ['Name', 'date', 'tags'],
rename: { Name: 'title' },
transform: {
date: (prop: NotionPageProperty) => prop.type === 'date' ? new Date(prop.date.start).toLocaleDateString() : '',
tags: (prop: NotionPageProperty) => prop.type === 'multi_select' ? JSON.stringify(prop.multi_select.map(t => t.name)) : '[]'
},
defaults: { draft: false }
}
});
const n2m = new NotionConverter(notionClient)
.withRenderer(renderer);
Exporter Configuration
Exporters determine how and where the converted content is saved or used. You can create custom exporters for any destination.
interface NotionExporter<TConfig = unknown> {
export(data: ChainData): Promise<void>;
}
interface ChainData {
pageId: string; // ID of the converted page
blockTree: ExtendedFetcherOutput; // Raw block data
metadata?: Record<string, any>; // Additional metadata
content: string; // Converted content
}
Field Explanations
export(): The main method that handles the export process. Receives the complete
ChainData
object containing all information about the conversion.pageId: The Notion page ID that was converted.
blockTree: The complete tree of blocks retrieved from Notion, including all metadata and content.
metadata: Additional information collected during the conversion process, such as processing statistics or conversion settings.
content: The final converted content string (e.g., markdown, HTML) ready for export.
Example
class FileSystemExporter implements NotionExporter {
constructor(private outputDir: string) {}
async export(data: ChainData): Promise<void> {
const filename = `${data.pageId}.md`;
const filepath = path.join(this.outputDir, filename);
await fs.writeFile(filepath, data.content, 'utf-8');
}
}
const n2m = new NotionConverter(notionClient)
.withExporter(new FileSystemExporter('./content'));
Advanced Types
For reference, these are the detailed types used in some configuration options. These types provide deeper insight into the structure of the data handled during conversion.
Media Types
enum MediaStrategyType {
DOWNLOAD = 'DOWNLOAD', // Media is downloaded to local filesystem
UPLOAD = 'UPLOAD', // Media is uploaded to external service
DIRECT = 'DIRECT', // Original media URLs are used directly
}
/** Identifies the source of a media reference (block, page property, or database property). */
export type MediaReferenceType =
| 'block'
| 'page_property'
| 'database_property';
/** Specific Notion block types that contain media URLs and can potentially be buffered. */
export type NotionMediaBlockType = 'image' | 'video' | 'file' | 'pdf';
interface MediaInfo {
type: MediaStrategyType; // The strategy used for this media
originalUrl: string; // The original Notion URL
localPath?: string; // Path on local filesystem (for DOWNLOAD)
uploadedUrl?: string; // URL after upload (for UPLOAD)
transformedPath?: string; // Final URL/filepath used in output (derived from local/uploaded/original)
mimeType?: string; // Media content type (may not always be available)
sourceType: MediaReferenceType; // Where the media URL was found
propertyName?: string; // Name of the property if sourceType is property
propertyIndex?: number; // Index within the files array if sourceType is property
}
interface MediaManifestEntry {
mediaInfo: MediaInfo; // Complete media information
lastEdited: string; // Last edit timestamp from Notion
createdAt: string; // When the entry was first created
updatedAt: string; // When the entry was last updated
}
Page Reference Types
enum PageReferenceEntryType {
PROPERTY = 'PROPERTY', // URL derived from page property
MANIFEST = 'MANIFEST', // URL stored in reference manifest
}
interface PageReferenceEntry {
url: string; // The URL for the page reference
source: PageReferenceEntryType; // How the URL was determined
lastUpdated: string; // When the reference was last updated
}