blog.hangerthem.com/README.md
HangerThem 61ea416ab8 chore: README, dependency cleanup and shared components
- Replace the create-next-app README with real project docs (features,
  env vars, frontmatter schema, Markdown extensions, deployment)
- Drop ESLint (unused by any script; oxlint is the linter) and the
  unrelated 'hast' package; move oxlint, oxfmt and puppeteer to
  devDependencies (locked versions unchanged)
- Extract PostList, used by the tag and category pages
- Use shared Intl formatters for post dates, pinned to Europe/Prague so
  the build server's timezone can't shift dates
- Use <h1> for the tag/category page headings (same styling)
- Remove math/mermaid flags from posts that don't use them; fix a typo
  in the Tessera cover alt text
2026-10-19 14:25:58 +02:00

81 lines
3.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ephemeris
Source of [blog.hangerthem.com](https://blog.hangerthem.com) — my personal blog and portfolio. Posts are plain Markdown files rendered to static HTML at build time by a custom [unified](https://unifiedjs.com/) pipeline.
## Features
- **Fully static** — every post, tag and category page is pre-rendered with Next.js (App Router, React Server Components)
- **Custom Markdown extensions** via small rehype plugins in [`lib/`](lib/):
- Callouts: `> [!TIP]`, `> [!WARNING]`, `> [!INFO]`, `> [!QUOTE]`
- Highlights: `==marked text==`
- Definition lists (a term line followed by `: definition` lines)
- Code blocks with language label, line numbers and a copy button
- **Math** with KaTeX and **diagrams** with Mermaid, rendered to SVG at build time — no client-side JS for either
- **Table of contents** generated from `h2`/`h3` headings with scroll-spy
- **SEO** — canonical URLs, Open Graph/Twitter cards, generated OG images, JSON-LD, sitemap, robots.txt and an Atom feed
- Works without JavaScript; JS-only UI (like copy buttons) is hidden when it's unavailable
## Stack
Next.js 16 · React 19 · TypeScript · Tailwind CSS 4 · unified (remark/rehype) · highlight.js · KaTeX · Mermaid (via Puppeteer) · Bun · oxlint/oxfmt
## Getting started
```bash
bun install
SITE_URL=http://localhost:3000 bun dev
```
| Script | Purpose |
| ------------------ | ------------------------------------ |
| `bun dev` | Development server |
| `bun run build` | Production build (static generation) |
| `bun start` | Serve the production build |
| `bun run lint` | oxlint + formatting check |
| `bun run lint:fix` | Auto-fix lint issues and format |
### Environment variables
| Variable | Required | Description |
| ---------------- | -------- | ---------------------------------------------------------------- |
| `SITE_URL` | yes | Public origin, e.g. `https://blog.hangerthem.com` |
| `SOURCE_COMMIT` | no | Commit hash shown in the sidebar (falls back to `git rev-parse`) |
| `GIT_ORIGIN_URL` | no | Repository URL; enables the "Source Code" link and commit link |
## Writing posts
Posts live in [`content/posts/`](content/posts/); the file name is the URL slug. Standalone pages (About, Projects, Setup) live in [`content/pages/`](content/pages/).
```yaml
---
title: 'Tessera: A Privacy-First Card Wallet'
description: 120–160 characters work best for search results.
date: 2026-09-18 12:00:00 +0200
updated: 2026-09-18 12:30:00 +0200 # optional
category: Projects
tags: [projects, pwa, privacy]
coverImage: tessera-cover.png # optional, from public/posts/, 1200×630 recommended
coverImageAlt: Tessera logo next to two loyalty cards
math: true # optional, enables KaTeX
mermaid: true # optional, enables Mermaid diagrams
draft: true # optional, only rendered in development
---
```
Frontmatter is validated at build time, so a missing or malformed field fails the build with the file name instead of producing a broken page.
Images go in [`public/posts/`](public/posts/) and are referenced by file name: `![Alt text](image.png "Optional caption")`.
## Project structure
```
app/ Routes, metadata, feed, sitemap and OG image generation
components/ UI split into content/, layout/, post/ and ui/
content/ Markdown posts and pages
lib/ Markdown pipeline, rehype plugins, tag/category helpers
public/posts/ Post images
```
## Deployment
Deployed with [Nixpacks](https://nixpacks.com/) (see [`nixpacks.toml`](nixpacks.toml)). Mermaid diagrams are rendered with headless Chromium during the build, so the build environment needs Chromium's system libraries and network access to fetch the Mermaid script.