a minimal static personal blog built for github pages. dark theme, lowercase typography, markdown content.
- 100% static — no server, database, or api routes
- github pages — deploys via github actions
- decap cms — browser-based content editing (git-backed)
- markdown — blog posts with syntax highlighting
- responsive — mobile-first design
npm install
npm run devopen http://localhost:3000.
npm run buildoutput goes to ./out (static html, css, js).
├── app/ # next.js app router pages
│ ├── page.tsx # home
│ ├── blog/ # blog index + post pages
│ ├── resume/ # resume page
│ └── contact/ # contact page
├── components/ # shared components
├── content/
│ ├── posts/*.md # blog posts
│ └── resume.md # resume content
├── lib/ # utilities (markdown parsing)
├── public/
│ ├── admin/ # decap cms (not in nav)
│ │ ├── index.html # cms loader
│ │ └── config.yml # cms config
│ ├── resume.pdf # downloadable resume
│ ├── sitemap.xml # generated at build
│ └── robots.txt # generated at build
├── scripts/
│ └── generate-sitemap.ts
└── .github/workflows/
└── deploy.yml # github actions deploy
- go to your repo settings → pages
- under build and deployment, set source to github actions
- save
push your code to the main branch. the workflow will:
- install dependencies
- run
npm run build - deploy the
outfolder to github pages
your site will be live at https://<username>.github.io (for user/org sites) or https://<username>.github.io/<repo-name> (for project sites).
add a CNAME file in public/ with your domain. the workflow copies public/ to out/, so it will be included.
the admin panel is at /admin. it is hidden from the main navigation and has noindex for search engines.
the github backend requires a server for oauth. you have two options:
option a: netlify (recommended)
- import your repo to netlify
- in netlify dashboard: site settings → access control → authentication
- enable identity and add github as an external provider
- your
/adminwill work when visiting the netlify url (e.g.https://yoursite.netlify.app/admin)
you can keep using github pages for the main site and use netlify only for admin access, or host entirely on netlify.
option b: oauth proxy
for github pages only, you need an oauth proxy. options:
- deploy netlify-cms-oauth-provider to a server or serverless function
- use a community proxy service
- add
proxy_urltopublic/admin/config.ymlpointing to your proxy
edit public/admin/config.yml to match your repo:
backend:
name: github
repo: your-username/your-repo-name
branch: main- blog posts — create, edit, delete in
content/posts/ - resume — edit markdown in
content/resume.md - resume.pdf — replace
public/resume.pdfmanually (upload your pdf to the repo)
---
title: your post title
date: 2026-02-10
excerpt: optional short description
slug: url-slug # optional, defaults to filename
---
your markdown content here...edit content/resume.md directly or via the cms. the pdf at public/resume.pdf is linked from the resume page.
- site url — update
SITE_URLinscripts/generate-sitemap.tsfor sitemap/robots - posts per page — change
POSTS_PER_PAGEinapp/blog/page.tsxandapp/blog/page/[page]/page.tsx - contact email — edit
app/contact/page.tsx - theme — adjust colors in
tailwind.config.tsandapp/globals.css
- next.js 14 (app router, static export)
- typescript
- tailwind css
- gray-matter, remark, rehype (markdown)
- decap cms (git-backed cms)
mit