π A modern, performant personal website and blog built with Next.js 14, TypeScript, and Tailwind CSS. Content is managed through Notion as a headless CMS, providing a seamless writing experience with powerful features.
Development Status: This repository will continue to be maintained and developed. However, please note that future versions of my blog may not be open source. This current version remains fully open source and available for use.
- Modern Tech Stack: Next.js 14 with App Router, TypeScript, Tailwind CSS
- Notion CMS Integration: Write and manage content directly in Notion
- Performance Optimized: ISR (Incremental Static Regeneration) for fast loading
- SEO Ready: Automatic sitemap generation, RSS feed, and meta tags
- Responsive Design: Mobile-first approach with dark/light theme support
- Notion as CMS: Manage blog posts, pages, and content in Notion
- Rich Content Support: Headings, lists, code blocks, images, videos, bookmarks
- Tag System: Organize content with tags and categories
- Reading Time: Automatic calculation of reading time
- Views Tracking: Integration with Umami analytics
- Dark/Light Theme: Automatic theme switching with system preference
- Table of Contents: Auto-generated TOC for blog posts
- Search Functionality: Basic search through blog posts (title and description)
- Pagination: Efficient content browsing
- Comments: Giscus integration for community engagement
- Type Safety: Full TypeScript coverage
- Modular Architecture: Well-organized service layer
- Error Handling: Comprehensive error boundaries and fallbacks
- Performance Monitoring: Built-in analytics and performance tracking
This project implements a pure unofficial Notion APIs approach, inspired by Anh-Thi Dinh's architectural insights:
Why This Architecture?
- Unofficial APIs Only: Complete implementation using unofficial Notion APIs
- Maximum Performance: Fastest possible data retrieval and rendering
- Full Feature Support: Complete access to all Notion block types and styles
src/services/notion/
βββ index.ts # Main entry point
βββ main.service.ts # Core Notion service (unofficial APIs)
βββ api.service.ts # Unofficial API functions
βββ utils.service.ts # Utility functions & data conversion
βββ notion-x.service.ts # NotionX integration (unofficial APIs)
βββ enhanced.service.ts # Enhanced service with performance optimizations
βββ unofficial-api.service.ts # Unofficial API service
βββ render.service.ts # Content rendering & styling
src/components/
βββ atoms/ # Basic UI components
βββ molecules/ # Composite components
βββ organisms/ # Complex components
βββ templates/ # Page templates
βββ notion/ # Notion-specific components
βββ providers/ # Context providers
- Node.js 18+
- npm, yarn, or pnpm
- Notion account
- GitHub account (for comments)
- Clone the repository
git clone https://github.com/howznguyen/howz.dev.git
cd howz.dev- Install dependencies
npm install
# or
yarn install
# or
pnpm install- Environment Setup
cp .env.example .env.local- Configure environment variables
# Notion Configuration
NOTION_API_KEY=your_notion_api_key
NOTION_POST_DATABASE_ID=your_database_id
NOTION_SPACE_ID=your_space_id
NOTION_TOKEN_V2=your_token_v2
NOTION_ACTIVE_USER=your_active_user
NOTION_API_WEB=https://www.notion.so/api/v3
# Site Configuration
NEXT_PUBLIC_SITE_URL=https://your-domain.com
NEXT_PUBLIC_SITE_NAME="Your Site Name"
NEXT_PUBLIC_SITE_DESCRIPTION="Your site description"
# Analytics (Optional)
NEXT_PUBLIC_GA_TRACKING_ID=your_ga_id
UMAMI_WEBSITE_ID=your_umami_id
UMAMI_SCRIPT_URL=your_umami_url
# Comments (Optional)
GISCUS_REPO=username/repository
GISCUS_REPO_ID=repository_id
GISCUS_CATEGORY_ID=category_idBased on the insights from Anh-Thi Dinh's experience, we use unofficial Notion APIs instead of official ones for several critical reasons:
- Speed: Unofficial APIs are extremely fast, with retrieval speed equal to that of the Notion site
- Full Style Support: Complete support for all block styles and formatting
- No Rate Limits: Avoid 429 "Too many requests" errors that plague official APIs
- Search Functionality: Basic search through blog posts (title and description)
- Image Support: Direct access to images uploaded to Notion
- Future Enhancement: Full-text search capability can be added using unofficial APIs
Use our Notion template or create your own with these properties:
Posts Database:
title(Title)slug(Rich Text)description(Rich Text)tags(Multi-select)status(Select: Published, Draft, Archived)published(Date)featured(Checkbox)views(Number)
From Notion URLs:
- Database ID: Found in the URL after the last
/ - Space ID: Found in the URL after
notion.so/ - Collection View ID: Found in the database view URL
From Browser (Chrome/Edge):
- Open Notion in your browser and log in
- Open Developer Tools (F12 or right-click β Inspect)
- Go to Application tab β Cookies β
https://www.notion.so - Find these cookies:
token_v2: Copy the value (this is yourNOTION_TOKEN_V2)notion_active_user: Copy the value (this is yourNOTION_ACTIVE_USER)
Alternative - From Network Tab:
- Open Developer Tools β Network tab
- Refresh Notion page or navigate to your database
- Look for API requests to
notion.so/api/v3 - Check request headers for
cookiefield containing the tokens
Detailed Guide (Based on Dinh Anh Thi's approach):
The unofficial APIs we use are actually from Notion, but they are not publicly available. When you view your note in the browser, you're already signed in and using your credentials to request content from Notion using their hidden APIs.
To see the requests:
- Open Developer Tools β Network tab
- Browse your database in Notion
- Look for requests to
notion.so/api/v3
For authorization, you need:
token_v2: Your authentication tokennotion_user_id: Your user ID (found innotion_active_usercookie)
Request headers should include:
{
"Content-Type": "application/json",
"cookie": "token_v2={{your_token_v2}}",
"x-notion-active-user-header": "{{your_notion_user_id}}"
}To fill the request body: Simply replicate the actions performed in the "Payload" tab of each request you see in the browser.
# Site Settings
BASE_URL=https://your-domain.com
# Unofficial Notion APIs Configuration
NOTION_TOKEN_V2=your_token_v2_from_browser_cookies
NOTION_ACTIVE_USER=your_active_user_from_browser_cookies
NOTION_SPACE_ID=your_space_id_from_notion_url
NOTION_POST_DATABASE_VIEW=your_collection_view_id
NOTION_POST_DATABASE_ID=your_database_id
NOTION_API_WEB=https://www.notion.so/api/v3
# Umami Analytics (Optional)
UMAMI_HOST=https://api.umami.is/v1
UMAMI_WEBSITE_ID=your_umami_website_id
UMAMI_TOKEN=your_umami_api_token
NEXT_PUBLIC_UMAMI_SCRIPT=https://cloud.umami.is
NEXT_PUBLIC_UMAMI_WEBSITE_ID=your_umami_website_id
# Google Analytics (Optional)
NEXT_PUBLIC_GA_MEASUREMENT_ID=your_ga_measurement_idThis project supports Giscus for comments. To enable comments:
- Create a GitHub Repository (if you haven't already)
- Install Giscus App on your repository
- Get Configuration from giscus.app
- Add Environment Variables:
# Giscus Configuration
GISCUS_REPO=your-username/your-repo
GISCUS_REPO_ID=your_github_repo_id
GISCUS_CATEGORY=General
GISCUS_CATEGORY_ID=your_giscus_category_idAs mentioned in the detailed guide, consider these optimizations:
- Separate Databases: Use different databases for different content types (posts, projects, bookmarks)
- Image Handling: Consider using third-party services like Cloudinary for image optimization
- Build Time: Unofficial APIs significantly reduce build times compared to official APIs
- Rate Limiting: Unofficial APIs don't have the same rate limits as official APIs
Based on real-world experience, here are common issues and solutions:
429 Errors (Too Many Requests)
- Problem: Not applicable with unofficial APIs
- Solution: Unofficial APIs don't have the same rate limits as official APIs
404 Errors on Posts
- Problem: Server-side rendering issues
- Solution: Instruct users to refresh the page
Build Timeouts on Vercel
- Problem: Free tier has 10-second execution limit
- Solution: Use unofficial APIs and optimize code performance
Database Privacy Concerns
- Problem: Need to make database public for full functionality
- Solution: Use third-party image services (Cloudinary, Imgur) for images
- Blog Posts: Create in your Notion database
- Pages: Add to the pages database
- Navigation: Update in
datas/navigation.ts - Footer: Customize in
datas/footer.ts
- Theme: Modify
tailwind.config.js - Colors: Update CSS variables in
globals.css - Components: Customize in
src/components/
- Comments: Configure Giscus in environment variables
- Analytics: Add Google Analytics or Umami tracking
- Search: Customize search functionality in components
- Push your code to GitHub
- Connect your repository to Vercel
- Add environment variables in Vercel dashboard
- Deploy!
The app works on any platform that supports Next.js:
- Netlify
- Railway
- DigitalOcean App Platform
- AWS Amplify
- Lighthouse Score: 95+ across all metrics
- Core Web Vitals: Optimized for excellent user experience
- ISR: Content updates without full rebuilds
- Image Optimization: Next.js Image component with WebP support
- Code Splitting: Automatic code splitting for optimal loading
We welcome contributions! Please see our Contributing Guide for details.
- 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
This project is licensed under the ISC License - see the LICENSE file for details.
- Next.js - The React framework
- Notion - The amazing CMS
- Tailwind CSS - Utility-first CSS
- Giscus - Comments system
- Umami - Privacy-focused analytics
- Full-text Search: Advanced search through all content using unofficial APIs
- Advanced Filtering: Filter posts by multiple tags, date ranges, and categories
- Content Recommendations: Related posts and content suggestions
- Performance Optimizations: Further improvements to build times and loading speeds
- Multi-language Support: Internationalization for different languages
- Advanced Analytics: Enhanced tracking and insights
- Content Scheduling: Schedule posts for future publication
- API Endpoints: RESTful API for external integrations
If you have any questions or need help:
- π§ Email: [email protected]
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
β Star this repository if you found it helpful!
Made with β€οΈ by Howz Nguyen