|
| 1 | +# Dev Proxy Website — Copilot Instructions |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +Static marketing/docs website for [Dev Proxy](https://github.com/dotnet/dev-proxy) (an API simulator). Built with **Astro 5**, **Tailwind CSS v4**, and **TypeScript**. Deployed to `https://devproxy.net`. |
| 6 | + |
| 7 | +## Architecture |
| 8 | + |
| 9 | +- **Astro content collections** drive both content areas: |
| 10 | + - `src/content/blog/` — Markdown blog posts with YAML frontmatter (title, description, date, author, tags) |
| 11 | + - `src/content/samples/` — **Auto-generated** from `pnp/proxy-samples` GitHub repo. Never edit these manually. |
| 12 | +- **Collection schemas** defined in `src/content.config.ts` using Zod |
| 13 | +- **Single shared layout** at `src/layouts/Layout.astro` (nav, footer, dark/light theme toggle, SEO meta) |
| 14 | +- **Pages** use file-based routing with `[slug].astro` dynamic routes for blog and samples |
| 15 | +- **One reusable component**: `src/components/SampleGallery.astro` (client-side search over data attributes) |
| 16 | + |
| 17 | +## Content Pipeline |
| 18 | + |
| 19 | +### Samples (auto-generated — do not hand-edit) |
| 20 | + |
| 21 | +`npm run fetch-samples` (runs `scripts/fetch-samples.ts`) shallow-clones `pnp/proxy-samples`, reads each sample's `assets/sample.json`, converts to Markdown with YAML frontmatter, rewrites relative image paths to raw GitHub URLs, and writes to `src/content/samples/`. This runs automatically before `dev` and `build`. |
| 22 | + |
| 23 | +### Blog posts |
| 24 | + |
| 25 | +Blog posts live in `src/content/blog/`. Required frontmatter: |
| 26 | + |
| 27 | +```yaml |
| 28 | +--- |
| 29 | +title: "Post title" |
| 30 | +description: "Short description for cards and SEO" |
| 31 | +date: 2025-09-23 |
| 32 | +author: "Author Name" |
| 33 | +tags: ["release"] |
| 34 | +--- |
| 35 | +``` |
| 36 | + |
| 37 | +The `scripts/import-blog-posts.ts` is a one-time migration script (imports from a local backup dir). Not part of regular workflow. |
| 38 | + |
| 39 | +## Styling Conventions |
| 40 | + |
| 41 | +- **Tailwind CSS v4** via Vite plugin (not PostCSS). Config in `astro.config.mjs`. |
| 42 | +- **CSS custom properties** for theming — defined in `src/styles/global.css` under `:root` (light) and `.dark` (dark). Use `var(--bg-primary)`, `var(--text-muted)`, `var(--border-primary)`, etc. in inline styles. |
| 43 | +- **Purple brand palette**: `--color-purple-400/500/600` and Tailwind's `text-purple-400`, `bg-purple-600`, etc. |
| 44 | +- Rich text rendered via `.prose-content` class (custom typography styles in `global.css`, not `@tailwindcss/typography`) |
| 45 | +- Inline `style` attributes with CSS variables for theme-aware colors; Tailwind classes for layout/spacing/transitions |
| 46 | + |
| 47 | +## Key Patterns |
| 48 | + |
| 49 | +- **`import.meta.env.BASE_URL`** — Always use this for internal links (configured as `/` in `astro.config.mjs`). Example: `` href={`${import.meta.env.BASE_URL}blog/`} `` |
| 50 | +- **Slug handling** — Collection entry IDs include `.md` extension. Strip it for URLs: `post.id.replace(/\.md$/, '')` |
| 51 | +- **Dark mode** — Applied via `.dark` class on `<html>`. Toggled client-side with `localStorage.setItem('theme', ...)`. Inline script in Layout prevents flash. |
| 52 | +- **Animations** — Hero uses CSS `@keyframes` with staggered `animation-delay`. Sections use `IntersectionObserver` adding `.visible` class for scroll-triggered reveals. |
| 53 | +- **Date formatting** — Use `en-GB` locale: `date.toLocaleDateString('en-GB', { year: 'numeric', month: 'long', day: 'numeric' })` |
| 54 | + |
| 55 | +## Pull Requests |
| 56 | + |
| 57 | +When submitting a PR, always include a screenshot of the affected page(s) showing the visual result of the change. This is a website — reviewers need to evaluate the visual impact quickly. |
| 58 | + |
| 59 | +## Development |
| 60 | + |
| 61 | +```bash |
| 62 | +npm install # Install dependencies |
| 63 | +npm run dev # Fetch samples + start dev server (localhost:4321) |
| 64 | +npm run build # Fetch samples + production build to ./dist/ |
| 65 | +npm run preview # Preview production build locally |
| 66 | +``` |
| 67 | + |
| 68 | +`npm run dev` and `npm run build` both run `fetch-samples` first, which requires `git` on PATH and network access. |
| 69 | + |
| 70 | +## File Structure Quick Reference |
| 71 | + |
| 72 | +| Path | Purpose | |
| 73 | +|------|---------| |
| 74 | +| `src/content.config.ts` | Zod schemas for blog + samples collections | |
| 75 | +| `src/layouts/Layout.astro` | Shared shell: nav, theme toggle, footer | |
| 76 | +| `src/pages/index.astro` | Marketing homepage | |
| 77 | +| `src/pages/blog/index.astro` | Blog listing (latest featured, grid for rest) | |
| 78 | +| `src/pages/blog/[slug].astro` | Individual blog post with reading time | |
| 79 | +| `src/pages/samples/index.astro` | Sample gallery with client-side search | |
| 80 | +| `src/pages/samples/[slug].astro` | Individual sample detail page | |
| 81 | +| `src/styles/global.css` | Theme variables, Tailwind import, `.prose-content` | |
| 82 | +| `scripts/fetch-samples.ts` | Pulls samples from GitHub at build time | |
0 commit comments