A modern, fast, and SEO-optimized blog starter built with Next.js (App Router) and NotionX
Transform your Notion workspace into a blazing-fast blog with automatic SEO optimization, RSS feeds, and social sharing support.
This project is a copy-paste fork of nextjs-notion-starter-kit adopted to use Next.js App Router, which powers my own blog lizurchik.dev deployed on Vercel.
- π― Zero Configuration - Works out of the box with your Notion database
- β‘ Lightning Fast - 1-minute cache with Next.js App Router and ISR
- π SEO Optimized - Meta tags, Open Graph, Twitter cards, and sitemap
- π€ Social Sharing - Auto-generated social images for each post
- π° RSS Feed - Built-in RSS support at
/feed.xml
and/rss
- π Sitemap - Automatic sitemap generation at
/sitemap.xml
- π Draft Support - Toggle post visibility with Notion's Public property
- π¨ Customizable - Easy theming and configuration
- π« 404 Handling - Custom not-found pages
- ποΈ Collection Support - Organize posts with Notion databases
- π Friendly URLs - Custom slugs for better readability
- π± Responsive Design - Looks great on all devices
- Node.js 18+
- A Notion account with a published page/database
-
Clone the repository
git clone https://github.com/likerRr/lizurchik.dev mv lizurchik.dev notion-blog-starter cd notion-blog-starter
-
Install dependencies
npm install # or yarn install # or pnpm install
-
Set up environment variables
cp .env.example .env.local
Configure your environment variables:
# local NEXT_PUBLIC_DOMAIN=localhost:3000 NEXT_PUBLIC_HOST=http://$NEXT_PUBLIC_DOMAIN # production NEXT_PUBLIC_DOMAIN=yourdomain.com NEXT_PUBLIC_HOST=https://yourdomain.com
-
Configure your Notion page
- Create or use an existing Notion page/database
- Publish it to the web
- Copy the page ID and update
rootNotionPageId
inconfig.ts
-
Run the development server
npm run dev
-
Open your browser Navigate to http://localhost:3000 to see your blog!
Edit the config.ts
file in the root directory to customize your blog:
export const config = {
rootNotionPageId: 'your-notion-page-id',
// ... other configuration options
}
π Note on Notion Page IDs: The Notion page IDs in the configuration file are not sensitive data since they refer to publicly published pages. These IDs are intentionally kept in the codebase for transparency and ease of configuration.
Key Configuration Options:
rootNotionPageId
β The ID of your root Notion page (must be published to web)name
β Your blog namedomain
β Your domain namedescription
β Blog description for SEOdefaultPageCover
β Default cover image URLnavigationLinks
β Static pages that appear in the site header navigation
Configure static navigation links that will appear in your site header:
navigationLinks: [
{
title: 'About',
pageId: '2653641abc5980adb8c4fdb5f59625d5', // Notion page ID
url: undefined, // Leave undefined for Notion pages
},
{
title: 'Portfolio',
pageId: '2653641abc59800da61ccc5208d3e2fc',
url: undefined,
},
{
title: 'External Link',
pageId: undefined, // Leave undefined for external URLs
url: 'https://example.com', // External URL
},
]
Replace /src/app/favicon.ico
with your custom favicon file.
Replace /public/empty-cover-preview.png
with your default cover image (recommended aspect ratio: 16:9).
/public/empty-cover-preview.png
β Default cover for pages without images/public/not-found.png
β 404 page image/src/app/favicon.ico
β Site favicon
Set up your Notion database with these properties for full functionality:
Property | Type | Description | Required |
---|---|---|---|
Public | Checkbox | Controls post visibility | β |
Published | Date | Publication date | β |
Slug | Text | Custom URL slug | β |
Description | Text | Meta description for SEO | β |
Social Image | Text | URL for social sharing image (falls back to a page cover) |
β |
Intro | Text | Short description for post previews on the index page |
β |
Tags | Multi-select | Post categories/tags | β |
Last Updated | Date | Auto-generated update time | β |
Created | Date | Auto-generated creation time | β |
For optimal SEO performance, consider updating the following properties for your posts:
- Description - Used for meta description and search snippets
- Social Image - Custom image for social sharing
- Meaningful Title - Clear, descriptive post titles
- Proper Tags - Relevant categorization for better discovery
Create a .env.local
file with the following variables:
# Required
NEXT_PUBLIC_DOMAIN=yourdomain.com
NEXT_PUBLIC_HOST=https://yourdomain.com
# Optional - Redis Cache
REDIS_ENABLED=1
REDIS_HOST=your-redis-host
REDIS_USER=your-redis-user
REDIS_PASSWORD=your-redis-password
# OR
REDIS_URL=redis://your-redis-url
Enable Redis caching for improved performance when isPreviewImageSupportEnabled
is active:
Option 1: Individual Redis credentials
REDIS_ENABLED=1
REDIS_HOST=localhost
REDIS_USER=default
REDIS_PASSWORD=your-password
Option 2: Redis connection URL
REDIS_ENABLED=1
REDIS_URL=redis://username:password@host:port
RSS feeds are automatically generated and available at:
/feed.xml
- Main RSS feed/rss
- Alternative RSS endpoint
Customize RSS generation in /src/app/feed.xml/route.ts
.
βββ config.ts # Main configuration
βββ src/
β βββ app/ # Next.js App Router
β β βββ [pageId]/ # Dynamic page routes
β β βββ api/ # API routes
β β βββ ...
β βββ components/ # React components
β βββ lib/ # Utility functions
β βββ styles/ # CSS styles
βββ public/ # Static assets
βββ ...
This project is licensed under the MIT License - see the LICENSE.md file for details.
If you encounter any questions create a new issue.