Skip to content

thorbeck/abytegray-content

Repository files navigation

Notion to GitHub Pages Content Pipeline

Automated content management system that syncs blog posts from Notion to GitHub Pages as markdown files.

Overview

This repository serves as a content backend for a static blog. It fetches pages from a Notion database, converts them to markdown with frontmatter metadata, and publishes them to GitHub Pages for consumption by a frontend application.

Features

  • Incremental Sync – Only fetches and converts modified Notion pages
  • Frontmatter Metadata – Extracts title, dates, tags, and custom properties
  • Image Handling – Keeps images as Notion URLs (no local storage)
  • Automated Workflow – Daily sync via GitHub Actions
  • Manual Trigger – Run sync on-demand via GitHub Actions UI
  • Deleted Page Cleanup – Automatically removes archived Notion pages

Setup

1. Notion Configuration

  1. Create a Notion integration at https://www.notion.so/my-integrations
  2. Copy the Internal Integration Token
  3. Share your Notion database with the integration
  4. Copy your Database ID from the database URL

2. Local Development

# Clone the repository
git clone https://github.com/thorbeck/abytegray-content.git
cd abytegray-content

# Install dependencies
npm install

# Create .env file
cp .env.example .env

# Add your Notion credentials to .env
NOTION_API_KEY=your_integration_token_here
NOTION_DATABASE_ID=your_database_id_here

# Run sync locally
npm run sync

3. GitHub Secrets

For automated syncing via GitHub Actions:

  1. Go to repository SettingsSecrets and variablesActions
  2. Add two repository secrets:
    • NOTION_API_KEY: Your Notion integration token
    • NOTION_DATABASE_ID: Your Notion database ID

4. GitHub Pages

  1. Go to repository SettingsPages
  2. Set Source to "Deploy from a branch"
  3. Select Branch: main and Folder: / (root)
  4. Save

Your content will be available at: https://thorbeck.github.io/abytegray-content/

Usage

Manual Sync

Run locally:

npm run sync

Or trigger via GitHub Actions:

  1. Go to Actions tab
  2. Select Sync Notion Content workflow
  3. Click Run workflow

Automated Sync

The workflow runs automatically:

  • Daily at 2 AM UTC
  • On push to main (when sync.js or workflow changes)

Notion Database Structure

The sync script automatically extracts common Notion properties:

Property Type Frontmatter Field
Title title
Select Property name (single value)
Multi-select Property name (array)
Date Property name (ISO string)
Checkbox Property name (boolean)
Number Property name (number)
Rich Text Property name (plain text)

Example Notion properties:

  • Status (select) → Status: "Published"
  • Tags (multi-select) → Tags: ["JavaScript", "Tutorial"]
  • Published (date) → Published: "2024-01-30"

Frontmatter Example

---
title: "My Blog Post"
slug: "my-blog-post"
notionId: "abc123..."
createdTime: "2024-01-15T10:00:00.000Z"
lastEditedTime: "2024-01-30T15:20:00.000Z"
Status: "Published"
Tags:
  - JavaScript
  - Tutorial
Published: "2024-01-30"
---

# Content starts here...

Project Structure

abytegray-content/
├── .github/
│   └── workflows/
│       └── sync-notion.yml    # GitHub Actions workflow
├── content/                   # Generated markdown files
│   └── README.md
├── sync.js                    # Main sync script
├── .notion-sync-state.json    # Sync state (auto-generated)
├── .nojekyll                  # Disable Jekyll processing
├── .gitignore
├── package.json
└── README.md

How It Works

  1. Load Sync State – Read .notion-sync-state.json for last sync timestamp
  2. Query Notion – Fetch pages with last_edited_time > lastSyncTime
  3. Convert to Markdown – Use notion-to-md library
  4. Generate Frontmatter – Extract metadata from page properties
  5. Write Files – Save to content/ directory with slug-based filenames
  6. Handle Deletions – Remove markdown files for archived Notion pages
  7. Update State – Save new sync timestamp and page tracking info
  8. Commit & Push – GitHub Actions commits changes back to repository

Consuming Content

Your frontend can fetch content from GitHub Pages:

// Fetch all markdown files
const response = await fetch('https://thorbeck.github.io/abytegray-content/content/my-blog-post.md');
const markdown = await response.text();

// Parse frontmatter and content
// Use a library like gray-matter to extract YAML frontmatter

Or create an index JSON file for easier discovery (optional enhancement).

Troubleshooting

Sync fails with authentication error

  • Check that NOTION_API_KEY is set correctly in GitHub Secrets
  • Verify the integration has access to your database

Pages not syncing

  • Check that pages are not archived in Notion
  • Verify pages are in the correct database
  • Check GitHub Actions logs for errors

Missing properties in frontmatter

  • Ensure property names match (case-sensitive)
  • Check that properties have values in Notion
  • Review sync.js logs for warnings

License

ISC

Contributing

This is a personal project, but suggestions and bug reports are welcome via GitHub Issues.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published