Adding content
Every recipe below is a git-tracked file edit. Run npm run dev while you work
so you see the result live, then commit and push to publish (see
Local dev and deploy). Full field reference lives in
Content collections.
A new FSAE build-log post
Section titled “A new FSAE build-log post”-
Create
src/content/fsae/<slug>.mdx. The slug becomes the URL, so keep it short and hyphenated, e.g.bms-can-integration.mdxrenders at/fsae/bms-can-integration. -
Add the frontmatter. Required:
title,date,subsystem(firmware|manufacturing|autonomous),summary. Setsubsystemcorrectly: it color-codes the post everywhere it appears. -
Write the body in MDX. To use content components, import them at the top:
---title: BMS to CAN Integrationdate: 2025-03-02subsystem: firmwareseason: 2025 Seasonsummary: "Bringing the battery-management data onto the car's CAN bus."tags: [BMS, CAN, Firmware]draft: false---import Gallery from '../../components/content/Gallery.astro';The BMS talks isoSPI internally, but the rest of the car speaks CAN...<Gallery labels={['SCOPE · isoSPI', 'BUS · CAN TRACE']} cols={2} /> -
(Optional) Add a
hero/coverimage (co-locate the file and reference it, e.g.cover: ./can-trace.jpg) or aheroVideo(public/path). Setdraft: trueto keep it out of the build until it is ready.
A new project
Section titled “A new project”-
Create
src/content/projects/<slug>.mdx, e.g.spectrum-analyzer.mdxrenders at/projects/spectrum-analyzer. -
Add the frontmatter. Required:
title,date,kind,summary. Common optional fields:stack[],links.repo,links.demo,order(lower sorts first on the index),featured.---title: Music Spectrum Analyzerdate: 2025-02-10kind: Embedded · DSPstack: [STM32, C, FFT, Altium, SolidWorks]summary: "A 28-band acrylic spectrum analyzer driven by FFT DSP on an STM32."order: 1featured: truelinks:repo: https://github.com/CPollreis/spectrum-analyzerdraft: false---import Gallery from '../../components/content/Gallery.astro';I wanted to actually see music on the wall... -
Write the MDX body. Add a
video(YouTube/Vimeo URL) for a lead demo video, or acover/heroimage for the header.
A new photography moment: photo
Section titled “A new photography moment: photo”-
Create
src/content/photography/<NN-slug>.md. The numeric prefix keeps the files ordered on disk; theorderfield controls actual display order. -
Add photo frontmatter (no MDX body needed).
storyis the caption shown in the lightbox.---title: Cold Startkind: photodate: 2025-01-12story: First frost test of the season, breath fogging the viewfinder.location: Winnipeg, MBcamera: Sony α7 IIIlens: 35mm f/1.8iso: "400"aperture: f/2.0focal: 35mmimage: ./cold-start.jpgratio: 3/2order: 9--- -
Drop the image next to the Markdown file and reference it with a relative path (
image: ./cold-start.jpg).astro:assetsoptimizes it automatically. Leaveimageout to render an on-brand placeholder for now.
A new photography moment: video
Section titled “A new photography moment: video”-
Create
src/content/photography/<NN-slug>.mdwithkind: video. -
Point
videoat apublic/path, and providefps/qualityfor the tech readout. Optionally add animageto use as the poster frame.---title: Green Over Superiorkind: videodate: 2024-05-11story: The G5 aurora storm. The whole sky moved like curtains.location: Lake Superior, MNcamera: Sony α7 IIIfps: "24"quality: 4K UHDvideo: /videos/green-over-superior.mp4image: ./green-over-superior-poster.jpgratio: 16/9order: 1--- -
Export the clip as two files with the same basename and put both in
public/videos/:public/videos/green-over-superior.webm(VP9/AV1)public/videos/green-over-superior.mp4(H.264)
Reference the
.mp4in frontmatter (video: /videos/green-over-superior.mp4). The gallery derives the.webmsibling and lists it first, so Firefox decodes the webm in software while other browsers use the mp4. Shipping only the mp4 works everywhere except it can stutter or fail to decode on Firefox/macOS, so always ship the pair. More detail in Media guidelines and thefootage.tssection of Architecture.In the archive grid, video moments autoplay muted while scrolled into view and pause off-screen (an IntersectionObserver in
src/pages/photography/index.astromanages them); the tile still opens the lightbox like any photo.
How the archive grid places a moment
Section titled “How the archive grid places a moment”The /photography archive is a modular “Feature Lead” grid: the packer in
src/components/photography/archiveGrid.ts reads the whole collection (sorted
by order) and fills repeating 2-row bands on a 4-column grid, so there is no
layout file to edit when the collection grows. Two frontmatter fields decide a
moment’s shape:
| Frontmatter | Shape in the grid |
|---|---|
vertical ratio (3/4, 2/3, 9/16) |
Tall: one column wide, the full band height - exactly twice the height of a 3/2 still. |
feature: true (non-vertical ratios) |
Lead: an oversized 2x2 cell. At most one per band, and leads alternate left/right from band to band. |
| anything else | Still: a standard cell; stills stack two per column. |
Practical notes:
- Give each band at most one
feature: truemoment if you care exactly where leads land; extra features simply lead later bands. - The typographic index tile (“12 moments · 2021 - 2026 · …”) is generated automatically from whatever cells the final band leaves open. Its counts update on their own; never edit it by hand.
- On small screens the same tiles reflow into a 2-column dense grid and the index tile hides itself.
- To reorder the archive, change
ordervalues (and ideally theNN-filename prefix to match); the packer re-lays everything out at build time.
Verifying before you publish
Section titled “Verifying before you publish”npm run devand open the relevant page to confirm it renders.npm run buildrunsastro check, which fails loudly on a bad enum, a missing required field, or a broken image reference. A green build means the content is valid.