Skip to main content

Quick Start Guide

Get the site running on your local machine in just a few steps. This guide assumes you have Node.js 18+ installed.
Prerequisites: Node.js 18+, pnpm (or npm), and a Notion account

Installation Steps

1

Clone the Repository

Clone the source code to your local machine:
git clone <repository-url>
cd website-astro
2

Install Dependencies

This project uses pnpm as the package manager. Install it if you don’t have it:
npm install -g pnpm
Then install project dependencies:
pnpm install
The project uses "type": "module" in package.json, enabling ES module syntax throughout the codebase.
3

Set Up Environment Variables

Create a .env file in the project root. You’ll need Notion API credentials:
touch .env
Add your Notion credentials (see Environment Setup for details):
NOTION_TOKEN=secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTION_BLOG_DB_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NOTION_PROJECTS_DB_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ... other environment variables
The site will not build without valid Notion credentials. The pre-build script syncs content before starting the dev server.
4

Start Development Server

Run the development server:
pnpm dev
This command does two things:
  1. Runs the pre-build script (jiti scripts/index.ts) to sync Notion content
  2. Starts the Astro development server on http://localhost:4321
The pre-build script is defined in package.json:
"predev": "jiti scripts/index.ts"
5

Open in Browser

Navigate to http://localhost:4321 to see your site running locally!

Available Scripts

The project includes several npm scripts for different workflows:
# Start dev server (syncs Notion content first)
pnpm dev

# Alternative start command
pnpm start

Understanding the Pre-Build Hook

Both pnpm dev and pnpm build automatically run the content sync script before starting. Here’s what happens:
// scripts/index.ts
import "dotenv/config";
import { downloadPostsAsMdx } from "../src/lib/notion-download";

downloadPostsAsMdx("blog");
downloadPostsAsMdx("projects");

console.log("Finished downloading content.");
This script:
  1. Connects to your Notion workspace using NOTION_TOKEN
  2. Queries blog and project databases
  3. Downloads content that has changed since last sync
  4. Converts Notion blocks to MDX format
  5. Writes files to src/content/blog/ and src/content/projects/
The sync is incremental - it only updates files where lastEditedTime in Notion is newer than the local file.

Project Structure Overview

Here’s what you’ll find in the codebase:
website-astro/
├── src/
│   ├── components/          # UI components (Astro, React, Solid.js)
│   │   ├── Navigation.astro # Dynamic navigation from Notion
│   │   ├── Map.tsx         # Interactive Leaflet map (Solid.js)
│   │   └── Icon.tsx        # Icon component library
│   ├── content/            # Auto-generated MDX files from Notion
│   │   ├── blog/           # Blog posts
│   │   └── projects/       # Project entries
│   ├── layouts/
│   │   └── Layout.astro    # Main layout with SEO
│   ├── lib/                # Core utilities
│   │   ├── notion-client.ts    # Notion API singleton
│   │   ├── notion-download.ts  # Content sync logic
│   │   ├── notion-parse.ts     # Block → Markdown converter
│   │   └── notion-cms.ts       # Database queries
│   ├── pages/              # File-based routing
│   │   ├── index.astro     # Home page
│   │   ├── blog/           # Blog listing & posts
│   │   ├── projects/       # Projects listing & pages
│   │   └── places.astro    # Interactive map
│   ├── styles/             # Global CSS
│   │   ├── global.css      # Tailwind imports
│   │   ├── prose.css       # Typography overrides
│   │   └── fonts.css       # Variable fonts (Inter, Newsreader)
│   └── content.config.ts   # Content collections schema
├── scripts/
│   └── index.ts           # Pre-build Notion sync
├── public/                # Static assets
├── astro.config.mjs      # Astro configuration
└── package.json          # Dependencies & scripts

Verify Installation

To ensure everything is working correctly:
1

Check Notion Sync

After running pnpm dev, verify MDX files were created:
ls src/content/blog/
ls src/content/projects/
You should see .mdx files with Notion page IDs as filenames.
2

Test Hot Reload

Make a change to any .astro file and save. The browser should auto-reload.
3

Run Build

Test the production build:
pnpm build
pnpm preview
Visit http://localhost:4321 to see the production build.

Common Issues

Make sure you installed dependencies with pnpm install. The project uses dotenv for environment variable management.
This means the Notion sync didn’t run or failed. Check:
  • .env file exists with valid NOTION_TOKEN
  • Database IDs are correct
  • Your Notion integration has access to the databases
  • Run pnpm dev and watch for error messages
Either kill the process using port 4321, or start Astro on a different port:
pnpm dev -- --port 3000
Make sure your IDE is using the workspace TypeScript version. In VS Code:
  1. Open any .ts file
  2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows)
  3. Select “TypeScript: Select TypeScript Version”
  4. Choose “Use Workspace Version”

Development Tips

Fast Refresh

Astro’s dev server supports instant HMR (Hot Module Replacement). Changes to components appear immediately without full page reload.

Type Safety

The project uses TypeScript throughout. Content schemas in src/content.config.ts validate all Notion data at build time.

Incremental Sync

Only changed Notion pages are re-downloaded. Delete src/content/ to force a full re-sync.

Notion Test

Create a test page in your Notion blog database and mark it public. Run pnpm dev to see it sync.

Next Steps

Now that you have the site running:

Environment Setup

Learn how to configure Notion databases and environment variables in detail

Content Schema

Understand the frontmatter schema and how Notion properties map to MDX

Customization

Customize styles, add new pages, and modify the Notion sync logic

Deployment

Deploy to Vercel or your preferred hosting platform
Ready to customize? Check out src/pages/index.astro to see how pages fetch and render Notion content.

Build docs developers (and LLMs) love