A simple and efficient loader for fetching content from Notion databases and converting it to markdown format. Perfect for Astro static site generators and other content management workflows.
- 🚀 Easy Integration: Simple API for loading Notion content
- 📝 Markdown Conversion: Automatically converts Notion pages to markdown
- 🔧 Flexible Filtering: Support for Notion database filters
- ⚡ Fast Performance: Efficient batch processing of pages
- 🛡️ Error Handling: Robust error handling for failed conversions
- 📦 TypeScript Support: Full TypeScript definitions included
npm install astro-notion-loader
- Go to Notion Integrations
- Click "New integration"
- Give it a name and associate it with your workspace
- Copy the Internal Integration Token (this is your API key)
- Open your Notion database
- Click the "Share" button in the top right
- Click "Invite" and search for your integration name
- Select your integration and click "Invite"
Your database ID is the 32-character string in your database URL:
https://notion.so/your-workspace/DATABASE_ID?v=...
import { loader } from 'astro-notion-loader';
const pages = await loader({
notionAPIKey: 'your-notion-api-key',
notionDatabaseId: 'your-database-id'
});
console.log(pages);
// src/content/config.ts
import { defineCollection } from 'astro:content';
import { getCollection } from 'astro-notion-loader';
const blog = defineCollection(
getCollection({
notionAPIKey: process.env.NOTION_API_KEY,
notionDatabaseId: process.env.NOTION_DATABASE_ID
})
);
export const collections = { blog };
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
import { loader } from 'astro-notion-loader';
const blog = defineCollection({
loader: () => loader({
notionAPIKey: process.env.NOTION_API_KEY,
notionDatabaseId: process.env.NOTION_DATABASE_ID
}),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
status: z.string(),
content: z.string(), // HTML content
}),
});
export const collections = { blog };
import { loader } from 'astro-notion-loader';
// Only fetch published posts
const publishedPosts = await loader({
notionAPIKey: 'your-notion-api-key',
notionDatabaseId: 'your-database-id',
filter: {
property: 'Status',
status: {
equals: 'Published'
}
}
});
Create a .env
file in your project root:
NOTION_API_KEY=your_notion_integration_token
NOTION_DATABASE_ID=your_database_id
Then use in your code:
import { loader } from 'astro-notion-loader';
const pages = await loader({
notionAPIKey: process.env.NOTION_API_KEY,
notionDatabaseId: process.env.NOTION_DATABASE_ID
});
-
options
(object): Configuration object-
notionAPIKey
(string): Your Notion integration token -
notionDatabaseId
(string): The ID of your Notion database -
filter
(object, optional): Notion database filter object
-
Promise that resolves to an array of page objects:
interface NotionPage {
id: string; // Notion page ID
title: string; // Page title from Title property
description: string; // Description from Description property
pubDate: Date; // Date from "Published Date" property
status: string; // Status from Status property
content: string; // HTML content converted from markdown
}
Returns a pre-configured Astro content collection with the loader and schema already set up.
-
options
(object): Configuration object-
notionAPIKey
(string): Your Notion integration token -
notionDatabaseId
(string): The ID of your Notion database -
filter
(object, optional): Notion database filter object
-
Content collection configuration object that can be used directly with defineCollection()
.
Your Notion database should have these properties (case-sensitive):
- Title (Title): The page title
- Description (Rich Text): Page description/summary
- Published Date (Date): Publication date
- Status (Status): Page status (e.g., "Draft", "Published")
The loader includes robust error handling:
- Pages that fail to convert will still be included with empty content
- Errors are logged to console for debugging
- Missing properties are handled gracefully with default values
// src/content/config.ts
import { defineCollection } from 'astro:content';
import { getCollection } from 'astro-notion-loader';
const blog = defineCollection(
getCollection({
notionAPIKey: process.env.NOTION_API_KEY,
notionDatabaseId: process.env.NOTION_DATABASE_ID,
filter: {
property: 'Status',
status: { equals: 'Published' }
}
})
);
export const collections = { blog };
// Only published posts
const filter = {
property: 'Status',
status: { equals: 'Published' }
};
// Posts from last month
const filter = {
property: 'Published Date',
date: {
after: '2024-01-01'
}
};
// Combine multiple filters
const filter = {
and: [
{
property: 'Status',
status: { equals: 'Published' }
},
{
property: 'Published Date',
date: { after: '2024-01-01' }
}
]
};
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
MIT License - see LICENSE file for details.