2026-02-24 02:34:21 -08:00
2026-02-13 12:14:16 -08:00
2026-02-13 12:14:16 -08:00
2026-03-11 17:38:58 -07:00
2026-02-12 23:22:13 -08:00
2026-02-08 23:12:47 -08:00
2026-02-08 23:12:47 -08:00
2026-02-24 02:38:39 -08:00
2026-02-12 23:22:13 -08:00
2026-02-13 12:14:16 -08:00
2026-02-13 12:14:16 -08:00
2026-02-13 12:14:16 -08:00
2026-02-08 23:12:47 -08:00
2026-03-02 22:23:08 -08:00
2026-02-13 12:14:16 -08:00
2026-02-08 23:12:47 -08:00

cooking

A content-first personal recipe site.

Live site: recipes.whitney.rip

Stack

  • Next.js, TypeScript + Tailwind CSS
  • MDX with YAML frontmatter metadata.
  • next-mdx-remote/rsc + remark-gfm for server-side compilation/rendering.
  • No database — recipes are checked into the repo.

Project Structure

app/
  page.tsx                    # Homepage
  recipes/
    page.tsx                  # Recipe listing with search/filter
    [category]/[slug]/
      page.tsx                # Recipe detail page

components/                   # UI components
lib/
  recipes.ts                  # Recipe loader (reads from public/recipes/)

public/
  assets/                     # Site-level data.
  authors.json                # Author metadata
  recipes/                    # All recipe content (MDX + images colocated)
    [category]/
      [slug]/
        [slug].mdx
        assets/
          hero.jpg

Adding a Recipe

  1. Create a folder: public/recipes/[category]/[recipe-slug]/
  2. Add [recipe-slug].mdx with frontmatter and content
  3. Create an assets/ subfolder and add images
  4. Reference images with relative paths: ./assets/image.jpg

Frontmatter

---
title: "Recipe Title"
slug: "recipe-slug"
date: "YYYY-MM-DD"
lastUpdated: "YYYY-MM-DD"
category: "mains"
tags: ["italian", "chicken"]
cookTime: 45
prepTime: 20
servings: 4
author: "PWS"
description: "Short description for SEO and previews"
featured: false
display: true
displayPhoto: "./assets/hero.jpg"
---

display: false hides a recipe without deleting it. Author IDs reference public/authors.json. Categories and tags are free-form strings — no taxonomy file to keep in sync.

Content Structure

Wrap recipe content in <RecipeCard>## headings inside it become tabs:

Intro prose (rendered above the card).

<RecipeCard>

## Photos
![Finished dish](./assets/hero.jpg)
*Caption text*

## Ingredients
- 1 cup short grain rice

## Instructions
1. Rinse and cook.

## Notes
Optional tips.

## References
Optional credits.
</RecipeCard>

Development

npm install
npm run dev       # 3000
npm run build
npm run lint

Deployment

docker compose down && docker system prune -f && docker compose up -d --build && docker logs -f recipes
Description
Content-first recipe site.
Readme 128 MiB
Languages
MDX 67.2%
TypeScript 32%
Dockerfile 0.4%
CSS 0.3%
JavaScript 0.1%