Overview
Projects are stored in a Notion database (NOTION_PROJECTS_DB_ID) and synced as MDX files to src/content/projects/ during the pre-build process. This allows you to maintain a portfolio of your work with rich content.
Database Schema
Your Notion projects database must include these properties (defined insrc/content.config.ts:4-13):
| Property | Type | Description |
|---|---|---|
| title | Title | Project name (required) |
| description | Text | Project summary/tagline |
| path | Text | URL slug (e.g., /projects/my-app) |
| published | Date | Publication or completion date |
| dates | Text | Project duration (e.g., “Jan 2024 - Mar 2024”) |
| tags | Text | Technologies or categories (comma-separated) |
| public | Checkbox | Visibility toggle (only true projects sync) |
| lastEditedTime | Last edited time | Auto-updated by Notion |
The projects schema includes a
dates field for showing project duration, which is particularly useful for portfolio entries.Creating a Project Entry
Add a new page to your Notion projects database
Create a new entry in your Notion database specified by
NOTION_PROJECTS_DB_ID.Configure project properties
Set the following properties:
- title: Your project name
- description: Brief summary or tagline
- path: URL slug (e.g.,
/projects/portfolio-site) - published: Project completion or publication date
- dates: Duration (e.g., “Summer 2024” or “Jan - Mar 2024”)
- tags: Technologies used (e.g., “React, TypeScript, Tailwind”)
- public: Check this box to publish
Document your project
Add project details using Notion’s block editor:
- Project overview and goals
- Screenshots or demo videos
- Technical implementation details
- Challenges and solutions
- Links to live demos or repositories
Content Sync Process
Projects sync identically to blog posts (scripts/index.ts:5):
- Query:
queryNotionDatabase()fetches all pages wherepublic: true - Check: Compares
lastEditedTimeto skip unchanged projects - Parse: Converts Notion blocks to Markdown
- Assets: Downloads images and media files locally
- Generate: Creates
src/content/projects/{page-id}.mdx
Both blog posts and projects use the same
downloadPostsAsMdx() function, ensuring consistent behavior and incremental updates.Generated Project Structure
A synced project generates an MDX file with frontmatter:Accessing Projects in Code
Query projects using Astro’s content collections:Project Content Best Practices
Structure your project documentation
Structure your project documentation
Use a consistent structure for all projects:
- Overview: What the project does
- Problem: What challenge it solves
- Solution: Your approach
- Technologies: Stack and tools used
- Results: Outcomes or metrics
- Links: Live demo, GitHub, etc.
Use rich media effectively
Use rich media effectively
Enhance project pages with:
- Screenshots of key features
- Demo videos or GIFs
- Architecture diagrams
- Code snippets showing interesting implementations
Tag comprehensively
Tag comprehensively
Include tags for:
- Technologies used (React, Node.js, PostgreSQL)
- Project type (web app, mobile, API)
- Industry or domain (fintech, education, e-commerce)
- Skills demonstrated (frontend, backend, design)
Keep dates informative
Keep dates informative
The
dates field is flexible - use whatever format makes sense:- “Jan 2024 - Mar 2024” (specific range)
- “Fall 2024” (seasonal)
- “2024” (year only)
- “Ongoing” (current projects)
Updating Projects
Common Project Page Patterns
Embedding Live Demos
Use Notion’s embed block to include live demos:Code Examples
Use Notion’s code blocks for syntax-highlighted snippets:Project Galleries
Add multiple images in sequence for a gallery effect:Differences from Blog Posts
While projects and blog posts share the same schema, they’re typically used differently:| Aspect | Blog Posts | Projects |
|---|---|---|
| Purpose | Written content, articles, tutorials | Portfolio showcases, case studies |
| Updates | Rarely updated after publication | May be updated as projects evolve |
| Dates field | Usually empty | Project duration or timeline |
| Tags | Content categories (dev, design) | Technologies and skills |
| Length | Variable, often narrative | Structured documentation |
Displaying Projects
Example project listing page:Troubleshooting
Project not syncing
Check:NOTION_PROJECTS_DB_IDenvironment variable is correct- Notion integration has access to the projects database
publiccheckbox is enabled for the project- Run
pnpm devorpnpm buildto trigger sync
Schema validation errors
Check:- All required properties exist in your Notion database
- Property names match exactly (case-sensitive)
- Property types are correct (Text, Title, Checkbox, Date)
- Review
src/content.config.ts:4-13for the schema definition
Missing or broken media
If images or videos aren’t loading:- Check that files were downloaded to
src/assets/orpublic/assets/ - Verify image references in the generated MDX file
- Ensure Notion blocks use native image/video blocks, not just links