Phase 1 - Code Examples
Code Examples
Section titled “Code Examples”Content Collections Configuration
Section titled “Content Collections Configuration”import { defineCollection, z } from 'astro:content';
// Portfolio/Case Studies Schemaconst projectsCollection = defineCollection({ type: 'content', schema: ({ image }) => z.object({ title: z.string(), description: z.string().max(160), // SEO meta description date: z.date(), draft: z.boolean().default(false), featured: z.boolean().default(false), cover: image(), coverAlt: z.string(), tags: z.array(z.string()), client: z.string().optional(), duration: z.string().optional(), role: z.string().optional(), technologies: z.array(z.string()), outcomes: z.array(z.object({ metric: z.string(), value: z.string(), description: z.string().optional() })).optional(), externalUrl: z.string().url().optional(), sortOrder: z.number().default(0) })});
// Blog Posts Schemaconst blogCollection = defineCollection({ type: 'content', schema: ({ image }) => z.object({ title: z.string(), description: z.string().max(160), date: z.date(), updated: z.date().optional(), draft: z.boolean().default(false), cover: image().optional(), coverAlt: z.string().optional(), tags: z.array(z.string()).default([]), author: z.string().default('Your Name'), readingTime: z.number().optional(), // Will calculate canonicalUrl: z.string().url().optional(), relatedPosts: z.array(z.string()).optional() // slugs })});
// Navigation/Site Dataconst navigationCollection = defineCollection({ type: 'data', schema: z.object({ items: z.array(z.object({ label: z.string(), href: z.string(), isExternal: z.boolean().default(false), icon: z.string().optional(), order: z.number() })) })});
// Bio/About Contentconst bioCollection = defineCollection({ type: 'content', schema: ({ image }) => z.object({ name: z.string(), title: z.string(), location: z.string().optional(), avatar: image(), social: z.object({ github: z.string().url().optional(), linkedin: z.string().url().optional(), twitter: z.string().url().optional(), email: z.string().email().optional() }).optional(), skills: z.array(z.object({ category: z.string(), items: z.array(z.string()) })).optional() })});
export const collections = { projects: projectsCollection, blog: blogCollection, navigation: navigationCollection, bio: bioCollection};URL Structure Strategy
Section titled “URL Structure Strategy”export const urlPatterns = { home: '/', projects: '/projects', project: (slug: string) => `/projects/${slug}`, blog: '/blog', blogPost: (slug: string) => `/blog/${slug}`, blogTag: (tag: string) => `/blog/tag/${tag}`, about: '/about', contact: '/contact',
// Archive patterns blogArchive: (year: number, month?: number) => month ? `/blog/${year}/${String(month).padStart(2, '0')}` : `/blog/${year}`} as const;
// Slug generation utilitiesexport function generateSlug(title: string): string { return title .toLowerCase() .replace(/[^\w\s-]/g, '') // Remove special chars .replace(/\s+/g, '-') // Replace spaces with hyphens .replace(/-+/g, '-') // Remove consecutive hyphens .trim();}
// Type-safe URL builderexport function getProjectUrl(project: { slug: string }): string { return urlPatterns.project(project.slug);}MDX Components Configuration
Section titled “MDX Components Configuration”import { Code } from '@astrojs/starlight/components';import { Image } from 'astro:assets';import Callout from './Callout.astro';import Grid from './Grid.astro';import Figure from './Figure.astro';
export const mdxComponents = { // Enhanced code blocks pre: Code,
// Responsive images with captions img: Image, Figure,
// Layout components Grid, Callout,
// Typography enhancements a: (props: any) => <a {...props} class="link" />, blockquote: (props: any) => <blockquote {...props} class="blockquote" />};Content Fixtures
Section titled “Content Fixtures”***
title: "E-commerce Platform Redesign"description: "Increased conversion rate by 40% through user-centered design"date: 2024-06-15draft: falsefeatured: truecover: "./images/ecommerce-cover.jpg"coverAlt: "Screenshot of redesigned e-commerce platform"tags: ["UX Design", "Preact", "Performance"]client: "TechCorp Inc"duration: "3 months"role: "Lead Frontend Developer"technologies: ["Preact", "TypeScript", "Tailwind CSS", "Astro"]outcomes: - metric: "Conversion Rate" value: "+40%" description: "Improved checkout flow and product pages" - metric: "Page Load Time" value: "-60%" description: "Optimized assets and lazy loading"sortOrder: 1
***
## Project Overview
<Callout type="success">This project demonstrates modern e-commerce best practices with significant measurable improvements.</Callout>
The client needed a complete redesign of their aging e-commerce platform...
## Technical Approach
<Grid cols={2}> <div> ### Frontend Architecture - Component-based design system - Progressive enhancement - Optimistic UI updates </div> <div> ### Performance Strategy - Code splitting by route - Image optimization pipeline - Edge caching with Cloudflare </div></Grid>
<Figure src="./images/architecture-diagram.png" alt="System architecture diagram" caption="High-level architecture showing service boundaries"/>Content Model Changelog
Section titled “Content Model Changelog”# Content Model Changelog
## [1.0.0] - 2024-01-15
### Added- Initial content collections: - `projects`: Portfolio case studies - `blog`: Blog posts with MDX support - `navigation`: Site navigation data - `bio`: Author/about information
### Schema Decisions- All content has `draft` field for preview- Projects have `sortOrder` for manual ordering- Blog posts track `updated` date separately- Tags are arrays of strings (not references)
## Migration Notes- When adding fields, provide defaults- Breaking changes require data migration scripts- Always test with `astro check` after changesValidation Script
Section titled “Validation Script”import { getCollection } from 'astro:content';
async function validateContent() { try { // Check all collections const projects = await getCollection('projects'); const posts = await getCollection('blog');
// Validate drafts aren't published const publishedDrafts = [...projects, ...posts] .filter(item => item.data.draft && !item.id.includes('draft'));
if (publishedDrafts.length > 0) { console.error('❌ Draft content in main folders:', publishedDrafts); process.exit(1); }
// Check for required images const missingImages = projects .filter(p => !p.data.cover);
if (missingImages.length > 0) { console.warn('⚠️ Projects missing cover images:', missingImages); }
console.log('✅ Content validation passed'); } catch (error) { console.error('❌ Content validation failed:', error); process.exit(1); }}
validateContent();