Skip to content

justinhuangcode/astro-theme-note

Repository files navigation

astro-theme-note

English | 简体中文 | 繁體中文

CI License: MIT Astro Tailwind CSS GitHub Stars Last Commit

An Astro theme that believes text itself is beautiful. Typography drives the design. Words speak for themselves. ✍️

Live Demo

Why astro-theme-note?

Good writing deserves good typography. Most themes bury your words under hero images, animations, and UI chrome. astro-theme-note takes the opposite approach -- it lets text be the design.

Elegant serif headings, a clean reading rhythm, and a layout that stays out of your way. Everything serves one goal: making your writing look and feel beautiful.

astro-theme-note Typical Astro Theme Hugo Theme Jekyll Theme
JavaScript output ~0.5 KB (inline) 50-200 KB 0 KB 0-50 KB
CSS Tailwind CSS v4, @theme design tokens Tailwind / framework Varies Varies
Typography Cross-platform (ui-serif, Georgia, system-ui) Theme-dependent Theme-dependent Theme-dependent
Dark mode Light / Dark / System toggle JS toggle Varies Varies
i18n Built-in Astro i18n Plugin / manual Built-in Plugin
AI-agent ready llms.txt No No No
Build tool Astro (npm) Astro (npm) Hugo (Go binary) Jekyll (Ruby)
Content format Markdown Markdown / MDX Markdown Markdown
Setup complexity npm install → write Install → configure → write Install Go → configure → write Install Ruby → configure → write
Deploy Cloudflare Pages (built-in) Varies Varies GitHub Pages

Features

  • Cross-platform typography -- Serif headings (ui-serif / Georgia) paired with clean body text (system-ui + CJK fallbacks), beautiful and consistent across macOS, Windows, Linux, and Android
  • Dark mode -- Light / Dark / System toggle with localStorage persistence, carefully tuned for reading comfort in both modes
  • Near-zero JavaScript -- Only ~0.5 KB inline script for theme toggle, no bundled JS
  • Tailwind CSS v4 -- Utility-first styling with @theme design tokens, easy to customize
  • Astro Content Collections -- Type-safe Markdown posts with frontmatter validation
  • RSS feed -- Built-in /rss.xml via @astrojs/rss
  • Sitemap -- Auto-generated via @astrojs/sitemap
  • SEO -- Open Graph meta tags, canonical URLs, per-post descriptions
  • Responsive -- Mobile-friendly layout that preserves reading rhythm across screen sizes
  • Draft support -- Set draft: true in frontmatter to hide posts from listing and feed
  • Cloudflare Pages ready -- Deploy workflow included with preview URLs on PRs, push to main and it's live
  • i18n -- Built-in Astro i18n routing with language switcher (English, 简体中文, 繁體中文)
  • llms.txt -- AI-agent-friendly /llms.txt endpoint for LLM discoverability
  • Google Analytics -- Optional, zero-config via PUBLIC_GA_ID env var, runs in a Partytown Web Worker
  • Tested -- Unit tests (Vitest) + E2E tests (Playwright), integrated into CI

Quick Start

Use as a GitHub template

  1. Click "Use this template""Create a new repository"
  2. Clone your new repo:
git clone https://github.com/YOUR_USERNAME/YOUR_REPO.git
cd YOUR_REPO
  1. Install dependencies:
npm install
  1. Configure your site:
# astro.config.mjs -- set your site URL
site: 'https://YOUR_USERNAME.github.io'

# src/config.ts -- set title and nav links
  1. Start writing:
npm run dev
  1. Deploy: push to main, GitHub Actions builds and deploys automatically.

Manual setup

git clone https://github.com/justinhuangcode/astro-theme-note.git my-blog
cd my-blog
rm -rf .git && git init
npm install
npm run dev

Post Format

Create Markdown files in src/content/posts/:

---
title: Your Post Title
date: 2026-01-01
description: Optional description for SEO
tags: [optional, tags]
draft: false
---

Your content here.
Field Type Required Description
title string Yes Post title
date date Yes Publication date (YYYY-MM-DD)
description string No Used in RSS feed and meta tags
tags string[] No Post tags
draft boolean No true hides from listing and feed (default: false)

Commands

Command Description
npm run dev Start local dev server
npm run build Build static site to dist/
npm run preview Preview production build locally
npm test Run unit and component tests (Vitest)
npm run test:e2e Run E2E tests (Playwright)

Configuration

Site settings (src/config.ts)

export const SITE = {
  title: 'Note',
  description: 'A minimal blog',
};

export const ANALYTICS = {
  googleId: import.meta.env.PUBLIC_GA_ID || '',
};

export const NAV_LINKS = [
  { labelKey: 'nav.blog' as const, href: '/' },
  { labelKey: 'nav.about' as const, href: '/about' },
];

Astro config (astro.config.mjs)

import tailwindcss from '@tailwindcss/vite';
import partytown from '@astrojs/partytown';

export default defineConfig({
  site: 'https://your-domain.pages.dev', // Required for RSS and sitemap
  vite: {
    plugins: [tailwindcss()],
  },
  integrations: [sitemap(), partytown()],
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'zh-hans', 'zh-hant'],
    routing: { prefixDefaultLocale: false },
  },
});

Project Structure

src/
├── config.ts              # Site title, description, nav links
├── content.config.ts      # Content Collections schema
├── i18n/
│   ├── ui.ts              # Translation strings & language definitions
│   └── utils.ts           # i18n helpers (getLangFromUrl, useTranslations, etc.)
├── layouts/
│   └── Layout.astro       # Global layout (head, nav, theme & language switcher)
├── pages/
│   ├── index.astro        # Home (English, default locale)
│   ├── about.astro        # About page
│   ├── 404.astro          # Not found page
│   ├── rss.xml.ts         # RSS feed (English)
│   ├── llms.txt.ts        # AI-agent-friendly llms.txt (all languages)
│   ├── posts/
│   │   └── [id].astro     # Post detail (English)
│   ├── zh-hans/           # Simplified Chinese pages
│   │   ├── index.astro
│   │   ├── about.astro
│   │   ├── rss.xml.ts
│   │   └── posts/[id].astro
│   └── zh-hant/           # Traditional Chinese pages
│       ├── index.astro
│       ├── about.astro
│       ├── rss.xml.ts
│       └── posts/[id].astro
├── content/
│   └── posts/
│       ├── *.md           # English posts (default)
│       ├── zh-hans/*.md   # Simplified Chinese posts
│       └── zh-hant/*.md   # Traditional Chinese posts
└── styles/
    └── global.css         # Tailwind CSS v4 @theme tokens + base styles
public/
└── favicon.svg            # Site favicon
tests/
├── unit/                  # Unit tests (Vitest)
├── component/             # Component tests (Vitest)
└── e2e/                   # E2E tests (Playwright)
.github/
└── workflows/
    └── ci.yml         # CI tests + Cloudflare Pages deployment

Deployment

Cloudflare Pages (default)

The included workflow (.github/workflows/ci.yml) deploys to Cloudflare Pages automatically:

  • Push to main → production deployment (your-project.pages.dev)
  • Pull request → preview deployment with unique URL, posted as a PR comment

Setup:

  1. Create a Cloudflare Pages project (name: astro-theme-note)
  2. Add repository secrets: CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID
  3. Push to main -- the site deploys automatically

Google Analytics (optional)

Analytics is disabled by default. To enable it, add a repository variable (not secret) in your GitHub repo:

  1. Go to Settings > Secrets and variables > Actions > Variables
  2. Click New repository variable
  3. Name: PUBLIC_GA_ID, Value: your Measurement ID (e.g. G-XXXXXXXXXX)

The gtag script runs inside a Partytown Web Worker, so it won't block your page rendering.

For local development, you can pass the variable directly:

PUBLIC_GA_ID=G-XXXXXXXXXX npm run dev

Or hardcode it in src/config.ts:

export const ANALYTICS = {
  googleId: 'G-XXXXXXXXXX',
};

Other platforms

Since the output is static HTML in dist/, you can deploy anywhere:

npm run build
# Upload dist/ to Netlify, Vercel, GitHub Pages, or any static host

Design Philosophy

  1. Typography is the design -- Serif headings in ui-serif / Georgia, clean body text in system-ui, and a carefully tuned reading rhythm. The typeface is the visual identity.
  2. Text is beautiful -- No hero images, no gradients, no animations. Well-set text on a quiet page is the most elegant interface.
  3. Works everywhere -- Cross-platform font stacks with CJK-aware fallbacks (PingFang SC, Microsoft YaHei). No web fonts to load, no FOIT, no layout shift. Beautiful on every OS.
  4. Crafted, not complex -- Tailwind CSS v4 @theme design tokens make it easy to customize without learning a framework. Two files to edit: config.ts and astro.config.mjs.

Acknowledgments

Inspired by yinwang.org.

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

License

MIT

About

An Astro theme that believes text itself is beautiful. ✍️

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors