changelog
A Visual Production Guide
A playbook for maintaining changelog entries. Every component is rendered live below with copy-pasteable code.
Quick-start checklist
- Decide which entry type you're creating (standard, text-only, or major feature).
-
Create a directory under
src/content/changelog/named with the patternYYYY-MM-DD-slug(e.g.2026-04-15-passphrase-hints). -
Add an
index.mdxfile with the required frontmatter (see template below). -
Capture your screenshot at 1280×800 and save it as
hero.pngin the same directory. - Write 2-4 sentences describing the user benefit.
- Import any components you need at the top of the MDX file.
- Commit, push, rebuild.
Entry types at a glance
Start here. Pick the tier that matches your change, then follow the links to the components you'll need.
Standard entry (~5 min)
- One hero screenshot
- ScreenshotFrame component
- 2-4 sentence description
- One Callout if needed
Text-only entry (~3 min)
- No
imagein frontmatter - For backend, security, or performance changes
- Callout for key takeaway
- Keep it concise
Major feature (~15 min)
- Hero screenshot + BeforeAfter
- 15-30s video walkthrough
- Longer narrative, multiple sections
- Set
featured: true
Frontmatter template
Copy this into your index.mdx and fill in the fields. The image, featured, highlightedLinkUrl, highlightedLinkText, planned, and highlights fields are optional.
---
title: "Plain-language headline focused on user benefit"
date: 2026-04-01
description: "2-4 sentence summary shown on the index card and RSS feed."
category: "release" # release | news | operations | security
image: "./hero.png" # optional — relative to this directory
imageAlt: "Descriptive alt text for the hero image"
featured: false # true → richer treatment on index
highlightedLinkUrl: "https://github.com/onetimesecret/onetimesecret/releases/tag/v1.0"
highlightedLinkText: "GitHub release notes"
planned: false # true → appears in Planned tab only
highlights: # optional bullet list shown on the index card
- { icon: check, text: "Something done, shipped, or fixed" }
- { icon: info, text: "Neutral supporting detail" }
- { icon: warn, text: "Caution or behaviour change" }
- { icon: ask, text: "Open question or planned / pending work" }
---
import Callout from "@/components/changelog/Callout.astro";
import ScreenshotFrame from "@/components/changelog/ScreenshotFrame.astro";
Your markdown content starts here. Category badges
Every entry gets exactly one category. Pick the one that best describes the change from the customer's perspective.
Release — A new version of the software shipping.
News — Announcements: region launches, documentation moves, partnerships, policy changes, company updates.
Operations — Infrastructure and service events: regional rollouts, upgrades, deployments, incident resolutions.
Security — Security advisories, vulnerability disclosures, and protective measures worth their own visibility.
Highlight bullets
The optional highlights field renders a short bullet list
on the index card. Each item picks one of four icons. Stick to the
legend — the colour is canonical, don't re-tint.
check — green
Something done, verified, shipped, or fixed.
info — sky
Neutral supporting detail. The "for instance" bullet.
warn — amber
Caution, constraint, or behaviour change worth flagging.
ask — violet
Open question or planned / pending work. Pair with planned: true.
Live preview
- Passphrase hint shipped behind feature flag
- Defaults to off for self-hosted instances
- Old API field renamed; clients must update
- Localized hint strings still pending translation
highlights:
- { icon: check, text: "Passphrase hint shipped behind feature flag" }
- { icon: info, text: "Defaults to off for self-hosted instances" }
- { icon: warn, text: "Old API field renamed; clients must update" }
- { icon: ask, text: "Localized hint strings still pending translation" } Screenshot workflow (~5 min)
Most entries need one screenshot. Follow these steps for consistent results every time.
- Deploy the feature to staging or production.
- Open the relevant page in Chrome. Set the viewport to 1280×800 via DevTools (Device toolbar → Responsive → 1280 × 800) .
-
Screenshot the key UI state.
- macOS: Cmd+Shift+4 (region) or DevTools → Capture screenshot
- Linux/Windows: DevTools → Ctrl+Shift+P → "Capture full size screenshot"
-
Save the file as
hero.pnginside your entry directory. - Wrap it in a ScreenshotFrame component for consistent browser-chrome framing.
Component: ScreenshotFrame
Wraps a raw screenshot in a browser-window frame with traffic-light dots and an address bar. Use this for most entries — it adds visual polish without any extra work.
Live preview
import ScreenshotFrame from "@/components/changelog/ScreenshotFrame.astro";
<ScreenshotFrame
image={import("./hero.png")}
alt="What the screenshot shows"
caption="Optional caption below the frame."
/> Component: BeforeAfter
Side-by-side comparison (stacked on mobile). Use when a change is best
understood by contrasting the old and new states. Save two images — before.png and
after.png — in your entry directory.
Live preview
import BeforeAfter from "@/components/changelog/BeforeAfter.astro";
<BeforeAfter
before={import("./before.png")}
after={import("./after.png")}
beforeAlt="Description of the before state"
afterAlt="Description of the after state"
caption="Optional caption below both images."
/> Component: VideoEmbed
Responsive video player for walkthroughs. Supports local MP4 files or
privacy-respecting YouTube embeds via
youtube-nocookie.com (no tracking cookies, GDPR-friendly).
Use for major features where a static screenshot doesn't capture the interaction.
Recording tips (macOS)
- Cmd+Shift+5 → Record Selected Portion
- Set the recording region to 1280×800
- Keep it to 15-30 seconds — show the core flow, skip setup
- Trim in QuickTime (Edit → Trim), export as MP4
- Save as
walkthrough.mp4in the entry directory
Live preview (YouTube embed via youtube-nocookie.com)
import VideoEmbed from "@/components/changelog/VideoEmbed.astro";
<!-- Local MP4 (place file in public/videos/changelog/) -->
<VideoEmbed src="/videos/changelog/walkthrough.mp4" caption="Quick walkthrough." />
<!-- YouTube (embedded via youtube-nocookie.com for privacy) -->
<VideoEmbed
youtube="VIDEO_ID"
title="Descriptive title for accessibility"
caption="Optional caption."
aspectRatio="16/9"
/> Component: Callout
Highlighted box for supplementary information. Three variants for different contexts. Choose the type that matches the tone of the message.
Live preview — info variant
Live preview — tip variant
Live preview — warning variant
import Callout from "@/components/changelog/Callout.astro";
<Callout type="info">Informational note.</Callout>
<Callout type="tip">Helpful suggestion.</Callout>
<Callout type="warning">Important caveat.</Callout> Screenshot consistency rules
Full example: standard entry
Here's a complete MDX file you can copy as a starting point. Create a
directory, drop in hero.png, and paste this as index.mdx.
---
title: "Set a custom expiration for your secret links"
date: 2026-04-15
description: "You can now choose exactly when a secret link expires — from 5 minutes to 14 days. Previously the default was fixed at 7 days."
category: "release"
image: "./hero.png"
imageAlt: "The new expiration picker showing time presets"
featured: false
highlightedLinkUrl: "https://github.com/onetimesecret/onetimesecret/releases/tag/v1.0"
highlightedLinkText: "GitHub release notes"
---
import ScreenshotFrame from "@/components/changelog/ScreenshotFrame.astro";
import Callout from "@/components/changelog/Callout.astro";
We've added a flexible expiration picker to the secret creation form.
You can now choose exactly when your secret link expires, from as short
as 5 minutes to as long as 14 days.
<ScreenshotFrame
image={import("./hero.png")}
alt="Expiration picker with time presets"
caption="Choose a preset or type a custom duration."
/>
## How it works
When creating a secret, click the expiration dropdown to see preset
options (5 min, 1 hour, 1 day, 7 days, 14 days). Pick the one that
fits your use case.
<Callout type="tip">
For highly sensitive information, use the shortest expiration that
gives your recipient enough time to open the link.
</Callout>
This feature is available to all users, including free accounts. File structure reference
Each entry is a directory with an index.mdx and co-located
images. The directory name becomes the URL slug. Text-only entries can be
standalone .mdx files.
src/content/changelog/
2026-04-15-custom-expiration/ ← directory name = URL slug
index.mdx ← entry content (required)
hero.png ← hero image (optional)
before.png ← for BeforeAfter (optional)
after.png ← for BeforeAfter (optional)
2026-03-24-burn-after-reading.mdx ← text-only (standalone file)
2026-06-01-api-v2.mdx ← planned item (planned: true)
...