# Changelog Page — Free Astro Template

A standalone, self-hosted changelog page for SaaS products, dev tools, and indie apps. Ships with typed MDX content collections, RSS feed, per-entry permalinks, year archive pages, client-side tag + year filtering, and a Buttondown email subscribe form.

Live demo: [templates.allanninal.dev/changelog-page/](https://templates.allanninal.dev/changelog-page/)

---

## Features

- **Astro 4 + Tailwind CSS 3** — static output, zero server required
- **MDX content collection** with Zod schema — bad dates and unknown tags caught at build
- **RSS feed** at `/rss.xml` via `@astrojs/rss` — wired, no configuration needed
- **Per-entry permalinks** — `/changelog/[slug]/` generated statically
- **Year archive pages** — `/changelog/2026/` generated at build time from collection
- **5-tag system** with WCAG AA contrast — New, Improvement, Fix, Breaking, Security
- **Client-side filter** (tag chips + year selector + text search) — zero framework, ~25 lines of vanilla JS
- **Buttondown email subscribe form** — pure HTML POST, works without JS
- **Light + dark mode** — system default, user toggle, persisted to localStorage
- **Schema.org JSON-LD** — `Blog` + `SoftwareApplication` on index, `BlogPosting` + `BreadcrumbList` on entries
- **Playwright test suite** — pages, interactions, responsive, theme, a11y (axe), links, Lighthouse CI

---

## Stack

| Package | Version |
|---|---|
| `astro` | ^4.16 |
| `@astrojs/mdx` | ^3 |
| `@astrojs/rss` | ^4 |
| `@astrojs/sitemap` | ^3 |
| `@astrojs/tailwind` | ^5 |
| `tailwindcss` | ^3 |
| `@fontsource/inter-tight` | ^5 |
| `@fontsource/jetbrains-mono` | ^5 |

---

## Quick start

```bash
# 1. Download the source ZIP from the live demo and unzip:
unzip changelog-page-source.zip -d my-changelog && cd my-changelog

# 2. Install
npm install

# 3. Develop
npm run dev

# 4. Build
npm run build

# 5. Preview the build locally
npm run preview
```

---

## Deploy to GitHub Pages (3 steps)

1. Download the source ZIP from [templates.allanninal.dev/changelog-page/](https://templates.allanninal.dev/changelog-page/)
2. Unzip into a new folder, `git init`, push to a new GitHub repo of your own
3. Repo Settings → Pages → Source: **GitHub Actions**

The included `.github/workflows/pages.yml` resolves base path from your repo name automatically. Push to `main` and your site is live at `https://<your-username>.github.io/<your-repo-name>/`.

### Custom domain

Set `PUBLIC_BASE_PATH=/` and `PUBLIC_SITE_URL=https://your-domain.com` as GitHub repository variables (Settings → Secrets and variables → Actions → Variables). The workflow reads them at build time.

### Alternate deploys

- **Vercel:** `vercel --prod` (auto-detects Astro)
- **Netlify:** drag the `dist/` folder to Netlify Drop, or connect your repo
- **Cloudflare Pages:** connect repo, build command `npm run build`, output dir `dist`

---

## Customize

### Add a changelog entry

Create a new `.mdx` file in `src/content/changelog/` with filename `YYYY-MM-DD-slug.mdx`:

```mdx
---
date: 2026-04-15
version: "v3.0.0"
title: "Your release title"
tags: ["New"]
summary: "One-sentence summary of what shipped (max 160 chars)."
draft: false
---

Your release notes body in MDX. Supports inline `code`, fenced code blocks, and all standard Markdown.
```

Valid tags: `New`, `Improvement`, `Fix`, `Breaking`, `Security`, `Deprecated`.

### Change the product name

1. `src/components/SiteHeader.astro` — update the product name and logomark SVG
2. `src/pages/index.astro` — update the h1, description, and JSON-LD `name`
3. `src/pages/rss.xml.ts` — update the feed title and description
4. `src/components/SiteFooter.astro` — update the Buttondown handle (`inkframe` → your handle)

### Change colors

Edit the CSS variables in `src/styles/global.css` under `:root` (light) and `[data-theme="dark"]` (dark). The variable names map directly to the Tailwind configuration in `tailwind.config.mjs`.

### Change fonts

Replace `@fontsource/inter-tight` in `package.json` and update the `@import` lines in `src/styles/global.css`. Update `font-family` in `tailwind.config.mjs` to match.

### Wire the email form to your own provider

In `src/components/SiteFooter.astro`, find the `<form>` element and update the `action` attribute:

```html
<!-- Buttondown -->
<form action="https://buttondown.email/api/emails/embed-subscribe/YOUR-USERNAME" ...>

<!-- ConvertKit -->
<form action="https://app.convertkit.com/forms/YOUR-FORM-ID/subscriptions" ...>

<!-- Mailchimp -->
<form action="https://YOUR-DOMAIN.us1.list-manage.com/subscribe/post?u=...&id=..." ...>
```

---

## Testing

Run the full test suite:

```bash
npm run test:all
# Equivalent to:
npm run build          # Clean Astro build
npm run test           # Playwright: pages, interactions, responsive, theme, a11y, links, template-info
npm run test:links     # Linkinator: crawl dist/ for broken internal links
npm run test:lighthouse # Lighthouse CI: Perf/A11y/BP/SEO >= 95 on 3 pages
```

### What each suite covers

| Suite | File | What it tests |
|---|---|---|
| Pages | `tests/pages.spec.ts` | Every route returns 200, has h1 + header + footer, zero console errors |
| Interactions | `tests/interactions.spec.ts` | Theme toggle, 5 tag chips, year selector, search input, Buttondown form, share links, RSS link |
| Responsive | `tests/responsive.spec.ts` | Every route x 4 viewports (375/768/1280/1920) — no horizontal overflow |
| Theme | `tests/theme.spec.ts` | Every route in light + dark — data-theme set correctly |
| A11y | `tests/a11y.spec.ts` | axe-core WCAG 2.1 AA on every route in both themes, zero violations |
| Links | `tests/links.spec.ts` | No broken internal links, external `_blank` links have `noopener`, no private repo deep-links |
| TemplateInfo | `tests/template-info.spec.ts` | Download bar renders with correct ZIPs + gallery + LinkedIn, zero github.com links inside |

### Adding a test for a new page

Add the route to `tests/helpers.ts` `ROUTES` array. The responsive, theme, and a11y suites pick it up automatically.

### Adding a test for a new interaction

Add a `test(...)` block to `tests/interactions.spec.ts`.

---

## Donations and support

This template is free and MIT-licensed — use it for personal, commercial, or client work, no permission needed.

- The repo's GitHub "Sponsor" button is driven by `.github/FUNDING.yml`. Edit the `ko_fi` handle or delete the file to repoint/hide it.
- The footer Ko-fi attribution link is controlled by `PUBLIC_AUTHOR_DONATE_URL` in `.env.example`. Set it blank to hide: `PUBLIC_AUTHOR_DONATE_URL=`.
- To add your own donate/support link as a prominent in-page CTA, set `PUBLIC_USER_DONATE_URL` in your deploy environment.

---

## License

MIT. See [LICENSE](./LICENSE).

Template by [Allan Ninal](https://www.linkedin.com/in/allanninal/) — part of the [365 free templates](https://templates.allanninal.dev) project.
