This file provides guidance to AI agents when working with code in this repository.
- Prefer
jqover Python for JSON processing in shell commands
- Use direct, concise language without unnecessary adjectives or adverbs
- Avoid flowery or marketing-style language ("tremendous", "dramatically", "revolutionary", etc.)
- Don't use vague superlatives ("comprehensive", "complete", "full", "entire", "thorough", "detailed")
- Don't include flattery or excessive praise ("excellent!", "perfect!", "great job!")
- State facts and findings directly without embellishment
- Skip introductory phrases like "I'm excited to", "I'd be happy to", "Let me dive into"
- Avoid concluding with summary statements unless specifically requested
- When presenting options or analysis, lead with the core information, not commentary about it
This is the source code for ddev.com, a static website built with Astro and hosted on Cloudflare Pages. The site features a blog, documentation, sponsor information, and project resources for DDEV, a local development environment tool.
Use DDEV for all development tasks:
ddev start- Start project with all dependenciesddev npm run dev- Start development server with hot reloadingddev npm run build- Build production site to./dist/ddev npm run preview- Preview built site locallyddev npm run prettier- Check code formattingddev npm run prettier:fix- Auto-fix formatting issuesddev npm run textlint- Check content for writing issuesddev npm run textlint:fix- Auto-fix content issues
- Dev server:
https://<projectname>.ddev.site:4321 - Built site:
https://<projectname>.ddev.site
Before committing changes, always run:
ddev npm run prettier:fix- Fix formattingddev npm run textlint:fix- Check content qualityddev start- Ensure environment is working- Spellcheck and check links in any new content
When making commits after major changes, use AI-assisted commit messages that include:
- Clear description of changes made
- End with:
🤖 Developed with assistance from [Claude Code](https://claude.ai/code) - Include:
Co-Authored-By: Claude <noreply@anthropic.com>
Only commit when explicitly requested by the user.
Use descriptive branch names that include:
- Date in YYYYMMDD format
- Your GitHub username
- Brief description of the work
Format: YYYYMMDD_<username>_<short_description>
Examples:
20250919_rfay_update_quickstart20250919_username_fix_blog_styling20250919_contributor_add_sponsor
- Never add trailing whitespace - Blank lines must be completely empty (no spaces or tabs)
- Match existing indentation style exactly (spaces vs tabs, indentation depth)
- Preserve the file's existing line ending style
- Run linting tools to catch whitespace issues before committing
- Astro - Static site generator
- Tailwind CSS - Utility-first CSS framework
- Tailwind Typography - Typography plugin
- Heroicons - Icon library
- Textlint - Content linting
- Giscus - GitHub-based commenting system
├── cache/ # GitHub API response cache for local development
├── public/ # Static assets copied to dist/
│ ├── logos/ # Sponsor and technology logos (prefer SVG)
│ └── _redirects # Cloudflare Pages redirects
├── src/
│ ├── components/ # Reusable Astro components
│ ├── content/ # Content collections (blog, authors)
│ ├── layouts/ # Page layout wrapper
│ ├── lib/ # Utilities (GitHub API, search, read time)
│ ├── pages/ # Direct route mapping (.astro files)
│ └── styles/ # Global PostCSS styles
├── .env.example # Environment variables template
├── astro.config.mjs # Astro configuration
├── package.json # Dependencies and scripts
└── tailwind.config.cjs # Tailwind configuration
The site uses Astro's Content Collections with strict schema validation:
- Blog posts:
src/content/blog/*.md- Markdown with frontmatter, validated against categories and author schemas - Authors:
src/content/authors/*.md- Author profiles with name, firstName, and optional avatarUrl - Static pages:
src/pages/*.astro- Direct route mapping
Blog posts require:
- Valid author (must exist in authors collection)
- Categories from predefined list: Announcements, Community, DevOps, Performance, Guides, Newsletters, TechNotes, Training, Videos
- pubDate as Date object
- Optional featureImage with alt text
For special markdown formatting features (callout boxes, code blocks, etc.), see MARKDOWN_FORMATTING.md.
- Internal blog links: Use markdown filename references (e.g.,
[link text](filename.md)) for links between blog posts. Astro automatically resolves these to proper URLs. - Other internal links: Use root-relative paths (e.g.,
[Contact](/contact)) for links to other site pages - External links: Use full URLs for links outside the site
The site fetches dynamic data from GitHub API:
- Requires
GITHUB_TOKENenvironment variable - Uses local
cache/directory to reduce API calls during development - Token needs:
repo,read:org,read:user,read:projectscopes
Featured sponsors are managed in src/featured-sponsors.json with specific schema for logos, URLs, and types. This data generates sponsor displays and SVG badges used in the main DDEV repository.
- Run
ddev startto start and set up the project's dependencies - Open
https://<projectname>.ddev.site:4321in your browser - To rebuild static site:
ddev npm run build - Static site available at: https://.ddev.site
- Run
nvm useto use appropriate Node.js version - Run
npm installto install dependencies - Run
npm run devto start development server - Visit
http://localhost:4321/
For dynamic GitHub data (not required for blog posts):
- Run
cp .env.example .env - Create classic GitHub access token with scopes:
repo,read:org,read:user,read:project - Add token to
.envasGITHUB_TOKEN=your_token_here
Template for new blog posts in src/content/blog/:
---
title: "Post Title"
pubDate: 2023-01-01
summary: Brief description
author: Author Name
featureImage:
src: /img/blog/kebab-case.jpg
alt: Descriptive alt text
caption: Optional caption
credit: Optional credit
categories:
- Category Name
---
Post content here...Categories: Announcements, Community, DevOps, Performance, Guides, Newsletters, TechNotes, Training, Videos
Images: Production-ready, <2MB, reasonable dimensions, optimized
Add new authors to src/content/authors/ with schema:
- name (must match blog post frontmatter)
- firstName
- avatarUrl (optional)
Add .astro files to src/pages/ where filename becomes URL slug.
- Configuration in
.textlintrc - Runs against
src/content/** - Enforces consistent language and terminology
- Run
ddev npm run textlintbefore committing
- Configuration in
.prettierrc - Auto-formats code
- Run
ddev npm run prettier:fixbefore committing - VS Code: Auto-format on save enabled
- GitHub Actions tests on every push to main
- Cloudflare Pages automatically builds and deploys from main branch
- Preview builds created for all PR branches
- Redirects managed via
public/_redirectsfile
Production requires GITHUB_TOKEN environment variable in Cloudflare Pages settings.
- Always preserve existing code style and component patterns
- Blog images should be production-ready: optimized, < 2MB, reasonable dimensions
- All content goes through textlint validation for consistency
- The site is configured for DDEV development with special CORS and host settings
- Use kebab-case for blog post filenames
- Prefer SVG logos in
public/logos/ - Internal blog links use markdown filename references
- External links use full URLs