Personal homepage and blog built with Hakyll and Nix.
- Bilingual support (English/Chinese)
- Server-side KaTeX math rendering
- Server-side Mermaid diagram rendering
- Dark/light theme with system preference detection
- RSS feeds per language
- Fully reproducible builds via Nix
- Nix with flakes enabled
# Build the complete website
nix build
# Output is in ./result/
ls result/# Run the site generator with watch mode (auto-rebuild on changes)
nix run . -- watch
# The site will be available at http://127.0.0.1:8000# Enter a development shell with all tools (HLS, cabal, ormolu, etc.)
nix develop
# Then you can use cabal for incremental builds during development
cabal build# Clean build artifacts
nix run . -- clean
# Check site for broken links
nix run . -- check
# Rebuild from scratch
nix run . -- rebuild.
├── content/ # Markdown content
│ ├── posts/ # Blog posts (folder per post)
│ │ └── {slug}/
│ │ ├── index.en.md
│ │ └── index.zh.md
│ ├── index.en.md # English homepage
│ └── index.zh.md # Chinese homepage
├── templates/ # Hakyll templates
├── static/ # Static assets
│ ├── scss/ # Sass stylesheets
│ └── js/ # JavaScript
├── src/ # Haskell source
├── config.yaml # Site configuration
└── flake.nix # Nix flake
Create a new post by adding a folder under content/posts/:
mkdir -p content/posts/my-new-postThen create index.en.md (and optionally index.zh.md):
---
title: "My New Post"
date: 2025-01-19
language: en
canonical: true
math: false
mermaid: false
---
Your content here...| Field | Description |
|---|---|
title |
Post title |
date |
Publication date (YYYY-MM-DD) |
language |
Content language (en or zh) |
canonical |
true if this is the source language |
math |
true to enable KaTeX rendering |
mermaid |
true to enable Mermaid diagrams |
If you see an error like Data.Binary.Get.runGet at position X: not enough bytes during watch mode, run:
nix run . -- cleanThis is a known Hakyll behavior that can occur when the build process is interrupted mid-write (e.g., Ctrl+C at an unlucky moment) or after template changes. The clean command removes the _cache/ directory and resolves the issue.
- Code (src/, app/, integration-tests/, templates/, static/): MIT
- Content (content/): CC BY-NC-SA 4.0