Phase 7 - Code Examples
Content Examples
Section titled “Content Examples”The template has no pages content collection — static pages (home, about, privacy, terms)
are .astro files in src/pages/, and src/content.config.ts defines the projects, blog,
navigation, bio, experience, and adr collections. Use the page examples below as draft
copy for those .astro pages (or add your own collection if you prefer MDX-managed pages).
Homepage Content
Section titled “Homepage Content”---# Draft copy for src/pages/index.astrotitle: "Home"description: "I create fast, accessible, and beautiful web experiences that users love"---
# Crafting Digital Experiences That Matter
I'm a web developer specializing in **performance-focused** websites that don't compromise on design or accessibility. With expertise in modern frameworks and a passion for clean code, I help businesses create web experiences that engage users and drive results.
## What Sets My Work Apart
### ⚡ Lightning FastEvery site I build scores 95+ on Lighthouse. Your users won't wait, and neither should you.
### ♿ Accessible FirstWCAG AA compliance isn't an afterthought. Everyone deserves a great web experience.
### 📱 Truly ResponsiveFrom phones to ultrawide monitors, your site adapts beautifully to every screen.
## Ready to Build Something Amazing?
Whether you need a portfolio site, business platform, or complex web application, I'm here to help bring your vision to life.
[View My Work](./projects) [Get In Touch](./contact)About Page Content
Section titled “About Page Content”---# Draft copy for src/pages/about.astrotitle: "About"description: "Learn about my journey in web development and the values that drive my work"image: "./images/profile.jpg"---
# About Me
Hi, I'm **[Your Name]**, a web developer based in [Location] with a passion for creating exceptional digital experiences.
## My Journey
I discovered web development [X years ago] and immediately fell in love with the blend of creativity and logic it requires. What started as curiosity about how websites work evolved into a career focused on pushing the boundaries of what's possible on the web.
## What I Do
I specialize in:
- **Frontend Development**: Astro and Preact for modern web apps- **Performance Optimization**: Making sites lightning fast- **Accessibility**: Ensuring everyone can use what I build- **UI/UX Design**: Creating interfaces that delight users
## My Approach
I believe great websites are:
1. **Fast** - Performance is a feature2. **Accessible** - The web is for everyone3. **Beautiful** - Good design matters4. **Maintainable** - Clean code saves time
## Beyond Code
When I'm not coding, you'll find me [hobbies/interests]. I'm also passionate about [causes/interests], and I try to contribute to open source projects whenever possible.
## Let's Connect
I'm always interested in new projects and opportunities. Whether you need a website, want to collaborate, or just want to chat about web development, I'd love to hear from you.
[Email Me](mailto:your@email.com) [LinkedIn](https://linkedin.com/in/yourprofile) [GitHub](https://github.com/yourusername)Project Case Study
Section titled “Project Case Study”---title: "E-commerce Platform Redesign"description: "Increased conversion rates by 40% through performance optimization and UX improvements"date: 2024-06-15client: "TechStyle Fashion"duration: "3 months"role: "Lead Frontend Developer"cover: "./images/projects/ecommerce-cover.jpg"coverAlt: "Screenshot of the redesigned e-commerce platform showing the modern, clean interface"featured: truetags: ["E-commerce", "Performance", "Preact"]technologies: ["Preact", "TypeScript", "Node.js", "PostgreSQL", "Redis", "Cloudflare"]outcomes: - metric: "Page Load Time" value: "-65%" description: "Reduced from 4.2s to 1.5s" - metric: "Conversion Rate" value: "+40%" description: "Increased from 2.1% to 2.9%" - metric: "Mobile Traffic" value: "+85%" description: "Better mobile experience drove more users"externalUrl: "https://example.com"sortOrder: 1---
## Project Overview
TechStyle Fashion came to me with a problem: their e-commerce platform was losing customers due to slow load times and a dated user interface. Mobile users were particularly affected, with conversion rates 60% lower than desktop.
## The Challenge
The existing platform faced several critical issues:
- **Performance**: 4.2 second average load time- **Mobile Experience**: Not truly responsive, difficult navigation- **Technical Debt**: jQuery spaghetti code, no build process- **Accessibility**: Failed WCAG guidelines
<Callout type="stat"> 60% of mobile users abandoned their carts due to performance issues</Callout>
## My Approach
### 1. Performance Audit
I began with a comprehensive performance audit using:- Lighthouse CI for continuous monitoring- WebPageTest for real-world performance data- Chrome DevTools for bottleneck identification
Key findings:- Render-blocking resources totaling 800KB- Unoptimized images (average 500KB each)- No caching strategy- Third-party scripts blocking main thread
### 2. Technical Strategy
Based on the audit, I developed a phased approach:
```typescript// Example: Implementing code splitting for route-based chunksconst routes = [ { path: '/', component: lazy(() => import('./pages/Home')) }, { path: '/products/:id', component: lazy(() => import('./pages/ProductDetail')) }];```
### 3. Implementation Highlights
#### Image Optimization Pipeline
* Implemented automatic WebP/AVIF generation* Lazy loading with native loading attribute* Responsive images with proper srcset
#### Performance Improvements
* Code splitting reduced initial bundle by 70%* Service worker for offline functionality* Edge caching with Cloudflare Workers
#### Mobile-First Redesign
* Touch-optimized interface elements* Simplified checkout process (3 steps → 1 step)* Bottom sheet navigation pattern
<Figure src="./images/projects/ecommerce-mobile.jpg" alt="Mobile interface showing the streamlined checkout process" caption="The new one-step checkout process increased mobile conversions by 125%" />
## Technical Deep Dive
### State Management
Moved from prop drilling to Zustand for cleaner state management:
```typescriptconst useCartStore = create((set) => ({ items: [], addItem: (item) => set((state) => ({ items: [...state.items, item] })), removeItem: (id) => set((state) => ({ items: state.items.filter(item => item.id !== id) }))}));```
### Performance Monitoring
Implemented RUM (Real User Monitoring) to track Core Web Vitals:
```typescript// Tracking Core Web Vitalsnew PerformanceObserver((list) => { for (const entry of list.getEntries()) { analytics.track('web-vitals', { metric: entry.name, value: entry.value, rating: entry.rating }); }}).observe({ entryTypes: ['web-vital'] });```
## Results & Impact
The redesign exceeded all target metrics:
<Grid cols={2}> <Card> ### Before
* Load Time: 4.2s * Conversion: 2.1% * Bounce Rate: 68% * Mobile Revenue: 22% </Card>
<Card> ### After
* Load Time: 1.5s (-65%) * Conversion: 2.9% (+40%) * Bounce Rate: 41% (-40%) * Mobile Revenue: 48% (+118%) </Card></Grid>
## Client Testimonial
> "The transformation was incredible. Not only did our conversion rates improve dramatically, but our customer satisfaction scores reached an all-time high. The attention to performance and user experience made all the difference.">> — Sarah Chen, CTO at TechStyle Fashion
## Key Takeaways
1. **Performance is a feature**: Every 100ms improvement in load time increased conversions by 1%2. **Mobile-first pays off**: Designing for mobile constraints led to better desktop experience too3. **Accessibility helps everyone**: Keyboard navigation improvements helped power users too4. **Measure everything**: RUM data guided continuous improvements post-launch
## Technologies Used
* **Frontend**: Preact, TypeScript, Zustand* **Styling**: Tailwind CSS, CSS animations* **Backend**: Node.js, Express, PostgreSQL* **Infrastructure**: Cloudflare Workers, Redis* **Testing**: Playwright, Vitest, Lighthouse CI* **Monitoring**: Datadog RUM, Sentry
[View Live Site](https://example.com)Blog Post Example
Section titled “Blog Post Example”---title: "Web Performance in 2024: What Really Matters"description: "Core Web Vitals are just the beginning. Here's what you need to know about modern web performance."date: 2024-11-20updated: 2024-11-25tags: ["Performance", "Web Development", "Core Web Vitals"]author: "Your Name"cover: "./images/blog/performance-hero.jpg"coverAlt: "Dashboard showing performance metrics and Core Web Vitals scores"canonicalUrl: "https://yourdomain.com/blog/web-performance-2024"relatedPosts: ["optimizing-images-astro", "lazy-loading-patterns"]---
Performance isn't just about speed—it's about creating experiences that feel instant and effortless. In 2024, with users expecting native-app-like performance from web apps, the stakes have never been higher.
## The State of Web Performance
Recent data from HTTP Archive shows that the median website now ships **2.2MB of JavaScript**, up from 1.8MB just two years ago. Yet, Core Web Vitals pass rates have actually improved. How? Developers are getting smarter about *when* and *how* we load resources.
<Callout type="info"> 75% of websites now pass Core Web Vitals thresholds, up from 40% in 2022</Callout>
## What's Changed Since Last Year
### 1. INP Replaces FID
Interaction to Next Paint (INP) is now a Core Web Vital, replacing First Input Delay. This change reflects a shift toward measuring the *entire* interaction, not just the delay before processing begins.
```javascript// Old way: Optimizing for FIDbutton.addEventListener('click', () => { // Quick acknowledgment requestAnimationFrame(() => { // Heavy work here });});
// New way: Optimizing for INPbutton.addEventListener('click', async () => { // Show immediate feedback button.classList.add('loading');
// Break up work await scheduler.yield(); await processData(); await scheduler.yield(); await updateUI();
button.classList.remove('loading');});```
### 2. The Rise of Edge Computing
Edge functions have moved from "nice to have" to essential for performance:
* **Personalization** without client-side JS* **A/B testing** at the edge* **Geographic content** delivery* **Authentication** closer to users
### 3. Framework Performance Wars
The battle between frameworks has shifted from bundle size to runtime performance:
| Framework | Bundle Size | Hydration Time | INP Score ||-----------|------------|----------------|-----------|| Astro | 0KB\* | N/A | Excellent || Qwik | 1KB | ~0ms | Excellent || React RSC | 64KB | 50ms | Good || Next.js | 82KB | 120ms | Fair || Angular | 130KB | 200ms | Poor |
\*With zero JavaScript by default
## Modern Performance Patterns
### Pattern 1: Speculation Rules API
Prefetch pages intelligently based on user behavior:
```html<script type="speculationrules">{ "prerender": [ { "source": "list", "urls": ["/products", "/about"] } ], "prefetch": [ { "source": "document", "where": { "and": [ { "href_matches": "/*" }, { "not": { "href_matches": "/logout" }} ] } } ]}</script>```
### Pattern 2: Islands of Interactivity
Ship HTML by default, enhance with JavaScript only where needed:
```astro<!-- Static by default --><article class="product-card"> <h2>{product.name}</h2> <p>{product.description}</p>
<!-- Interactive island --> <AddToCart client:visible productId={product.id} /></article>```
### Pattern 3: Optimistic UI Updates
Make apps feel instant with optimistic updates:
```typescriptasync function updateCart(item: CartItem) { // Update UI immediately setCart(prev => [...prev, item]);
try { // Sync with server await api.addToCart(item); } catch (error) { // Revert on failure setCart(prev => prev.filter(i => i.id !== item.id)); showError("Failed to add item"); }}```
## Performance Budgets That Work
Instead of arbitrary limits, tie budgets to business metrics:
```javascript// performance-budget.jsexport const budgets = { 'product-page': { lcp: 2000, // 2s LCP = 15% higher conversion inp: 100, // 100ms INP = 8% lower bounce rate cls: 0.05, // 0.05 CLS = 12% longer sessions size: { js: 150_000, // 150KB JavaScript css: 50_000, // 50KB CSS images: 800_000, // 800KB images } }};```
## Real-World Optimization Wins
### Case Study: E-commerce Category Pages
**Problem**: 4.5s LCP on category pages with 100+ products
**Solution**:
1. Implemented virtual scrolling2. Lazy loaded images below fold3. Used CSS containment for paint optimization4. Moved filters to URL params (no JS required)
**Result**: 1.8s LCP, 35% increase in products viewed
```css/* CSS Containment for product grid */.product-grid { contain: layout style paint; content-visibility: auto; contain-intrinsic-size: 0 500px;}```
## Tools & Monitoring in 2024
### Essential Tools
1. **[Unlighthouse](https://unlighthouse.dev/)** - Bulk Lighthouse testing2. **[Speedlify](https://speedlify.netlify.app/)** - Competitive monitoring3. **[Treo](https://treo.sh/)** - Real user monitoring4. **[WebPageTest](https://webpagetest.org/)** - Detailed analysis
### Monitoring Stack
```typescript// monitoring.tsimport { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
function sendToAnalytics({name, value, rating}) { // Batch metrics for efficiency navigator.sendBeacon('/analytics', JSON.stringify({ metric: name, value: Math.round(value), rating, url: location.href, connectionType: navigator.connection?.effectiveType }));}
onCLS(sendToAnalytics);onINP(sendToAnalytics);onLCP(sendToAnalytics);onFCP(sendToAnalytics);onTTFB(sendToAnalytics);```Image Optimization
Section titled “Image Optimization”1. Image Pipeline Setup
Section titled “1. Image Pipeline Setup”import sharp from 'sharp';import { glob } from 'glob';import path from 'path';import fs from 'fs/promises';
const FORMATS = ['avif', 'webp', 'jpg'] as const;const WIDTHS = [320, 640, 960, 1280, 1920, 2560];
async function optimizeImage(inputPath: string) { const outputDir = path.dirname(inputPath).replace('/original', '/optimized'); const filename = path.basename(inputPath, path.extname(inputPath));
await fs.mkdir(outputDir, { recursive: true });
for (const width of WIDTHS) { for (const format of FORMATS) { const outputPath = path.join( outputDir, `${filename}-${width}w.${format}` );
await sharp(inputPath) .resize(width, null, { withoutEnlargement: true, fit: 'inside' }) .toFormat(format, { quality: format === 'avif' ? 50 : 80, effort: format === 'avif' ? 4 : 6 }) .toFile(outputPath); } }
console.log(`✅ Optimized: ${filename}`);}
// Process all images. `images/original/` is a staging folder you create at the// repo root — the template itself co-locates content images with their entries// (e.g. src/content/blog/<post>/) and optimizes them via astro:assets.const images = await glob('images/original/**/*.{jpg,jpeg,png}');await Promise.all(images.map(optimizeImage));2. Art Direction for Images
Section titled “2. Art Direction for Images”---import { getImage } from 'astro:assets';
export interface Props { src: ImageMetadata; alt: string; sizes?: string; loading?: 'eager' | 'lazy'; artDirection?: { media: string; src: ImageMetadata; }[];}
const { src, alt, sizes = '100vw', loading = 'lazy', artDirection = []} = Astro.props;
// Generate optimized versionsconst avif = await getImage({ src, format: 'avif' });const webp = await getImage({ src, format: 'webp' });const fallback = await getImage({ src, format: 'jpg' });---
<picture> <!-- Art direction sources --> {artDirection.map(async ({ media, src: artSrc }) => { const artAvif = await getImage({ src: artSrc, format: 'avif' }); const artWebp = await getImage({ src: artSrc, format: 'webp' });
return ( <> <source media={media} type="image/avif" srcset={artAvif.src} /> <source media={media} type="image/webp" srcset={artWebp.src} /> </> ); })}
<!-- Default sources --> <source type="image/avif" srcset={avif.src} sizes={sizes} /> <source type="image/webp" srcset={webp.src} sizes={sizes} />
<!-- Fallback --> <img src={fallback.src} alt={alt} loading={loading} decoding="async" width={src.width} height={src.height} /></picture>Note: Astro’s built-in
<Picture>component fromastro:assetscovers the multi-format (AVIF/WebP + fallback) case out of the box — a custom component like this is only warranted when you need art direction with different source images per breakpoint.
3. Social Media Images
Section titled “3. Social Media Images”import { createCanvas, loadImage } from 'canvas';import fs from 'fs/promises';
interface OGImageOptions { title: string; subtitle?: string; backgroundImage?: string; brandColor?: string;}
async function generateOGImage({ title, subtitle, backgroundImage, brandColor = '#0066CC'}: OGImageOptions): Promise<Buffer> { const canvas = createCanvas(1200, 630); const ctx = canvas.getContext('2d');
// Background if (backgroundImage) { const bg = await loadImage(backgroundImage); ctx.drawImage(bg, 0, 0, 1200, 630);
// Overlay for text readability ctx.fillStyle = 'rgba(0, 0, 0, 0.6)'; ctx.fillRect(0, 0, 1200, 630); } else { // Gradient background const gradient = ctx.createLinearGradient(0, 0, 1200, 630); gradient.addColorStop(0, brandColor); gradient.addColorStop(1, adjustColor(brandColor, -30)); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 1200, 630); }
// Title ctx.fillStyle = '#FFFFFF'; ctx.font = 'bold 72px Inter'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle';
// Word wrap for long titles const words = title.split(' '); const lines: string[] = []; let currentLine = '';
words.forEach(word => { const testLine = currentLine + word + ' '; const metrics = ctx.measureText(testLine);
if (metrics.width > 1000 && currentLine !== '') { lines.push(currentLine.trim()); currentLine = word + ' '; } else { currentLine = testLine; } }); lines.push(currentLine.trim());
// Draw title lines const lineHeight = 90; const startY = subtitle ? 250 : 315;
lines.forEach((line, i) => { ctx.fillText(line, 600, startY + (i * lineHeight)); });
// Subtitle if (subtitle) { ctx.font = '36px Inter'; ctx.fillStyle = 'rgba(255, 255, 255, 0.9)'; ctx.fillText(subtitle, 600, 450); }
// Brand mark ctx.font = 'bold 24px Inter'; ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'; ctx.textAlign = 'left'; ctx.fillText('yourdomain.com', 60, 570);
return canvas.toBuffer('image/png');}
// Generate OG images for all contentconst content = [ { title: 'Web Developer & Designer', subtitle: 'Creating fast, beautiful web experiences' }, { title: 'E-commerce Platform Redesign', subtitle: 'Case Study' }, { title: 'Web Performance in 2024', subtitle: 'Blog Post' },];
for (const item of content) { const buffer = await generateOGImage(item); await fs.writeFile( `public/og/${slugify(item.title)}.png`, buffer );}Meta Descriptions & SEO
Section titled “Meta Descriptions & SEO”SEO Component
Section titled “SEO Component”---export interface Props { title: string; description: string; image?: string; type?: 'website' | 'article' | 'profile'; publishedTime?: Date; modifiedTime?: Date; author?: string; tags?: string[]; noindex?: boolean;}
const { title, description, image = '/og/default.png', type = 'website', publishedTime, modifiedTime, author, tags, noindex = false} = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);const imageURL = new URL(image, Astro.site);---
<!-- Primary Meta Tags --><title>{title}</title><meta name="title" content={title} /><meta name="description" content={description} /><link rel="canonical" href={canonicalURL} />
{noindex && <meta name="robots" content="noindex, nofollow" />}
<!-- Open Graph --><meta property="og:type" content={type} /><meta property="og:url" content={canonicalURL} /><meta property="og:title" content={title} /><meta property="og:description" content={description} /><meta property="og:image" content={imageURL} /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="630" />
<!-- Twitter --><meta property="twitter:card" content="summary_large_image" /><meta property="twitter:url" content={canonicalURL} /><meta property="twitter:title" content={title} /><meta property="twitter:description" content={description} /><meta property="twitter:image" content={imageURL} />
<!-- Article specific -->{type === 'article' && ( <> {publishedTime && ( <meta property="article:published_time" content={publishedTime.toISOString()} /> )} {modifiedTime && ( <meta property="article:modified_time" content={modifiedTime.toISOString()} /> )} {author && <meta property="article:author" content={author} />} {tags?.map(tag => ( <meta property="article:tag" content={tag} /> ))} </>)}
<!-- Schema.org --><script type="application/ld+json" set:html={JSON.stringify({ "@context": "https://schema.org", "@type": type === 'article' ? 'BlogPosting' : 'WebPage', headline: title, description: description, image: imageURL.toString(), url: canonicalURL.toString(), ...(publishedTime && { datePublished: publishedTime.toISOString() }), ...(modifiedTime && { dateModified: modifiedTime.toISOString() }), ...(author && { author: { "@type": "Person", name: author } })})} />Meta Description Guidelines
Section titled “Meta Description Guidelines”# Meta Description Best Practices
## Character Limits- **Optimal**: 150-160 characters- **Minimum**: 120 characters- **Maximum**: 160 characters (truncated after)
## Writing Formula1. **Start with action verb** (Discover, Learn, Create, Build)2. **Include primary keyword** naturally3. **Add unique value proposition**4. **Include call-to-action** if space allows
## Examples by Page Type
### Homepage"I create lightning-fast, accessible websites that delight users and drive results. Specializing in Astro, Preact, and modern web development. Let's build something amazing."
### Service Page"Need a blazing-fast website? I build performance-focused web applications using Astro, Preact, and modern tools. 100% Lighthouse scores guaranteed. Get a free consultation."
### Blog Post"Core Web Vitals got you down? Learn proven strategies to achieve Performance ≥ 95, Accessibility 100, Best-Practices 100, SEO 100, optimize INP, and create instant-feeling web experiences. Code examples included."
### Project Case Study"See how I helped TechStyle Fashion increase conversions by 40% through performance optimization and UX improvements. Detailed case study with metrics and technical insights."
### About Page"Hi, I'm [Name], a web developer passionate about performance and accessibility. Learn about my journey, skills, and approach to creating exceptional digital experiences."Navigation & Footer Content
Section titled “Navigation & Footer Content”Navigation Data
Section titled “Navigation Data”Header navigation lives in the navigation collection as src/content/navigation/header.json.
The collection schema (src/content.config.ts) accepts a flat items array of
{ label, href, isExternal?, icon?, order } — nothing else validates.
{ "items": [ { "label": "Home", "href": "/", "order": 1 }, { "label": "Blog", "href": "/blog/", "order": 2 }, { "label": "Projects", "href": "/projects/", "order": 3 }, { "label": "About", "href": "/about/", "order": 4 }, { "label": "Contact", "href": "/contact/", "order": 5 }, { "label": "GitHub", "href": "https://github.com/your-username/your-repo", "isExternal": true, "icon": "github-logo", "order": 6 } ]}Footer Content
Section titled “Footer Content”There is no footer.json — footer links are defined in code. Edit the footerLinks array in
src/components/structural/Footer.astro, and configure the docs/social columns via
siteLinks and socialLinks in src/config.ts (empty values auto-hide their sections):
// src/components/structural/Footer.astro (frontmatter excerpt)const footerLinks = [ { label: "Home", href: withBase("/") }, { label: "Blog", href: withBase("/blog/") }, { label: "Projects", href: withBase("/projects/") }, { label: "About", href: withBase("/about/") }, { label: "Contact", href: withBase("/contact/") },];Legal Pages
Section titled “Legal Pages”Privacy Policy
Section titled “Privacy Policy”---# Draft copy for src/pages/privacy.astro (a page you create)title: "Privacy Policy"description: "How we collect, use, and protect your information"noindex: true---
# Privacy Policy
## Introduction
Your privacy is important to us. This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you visit our website.
## Information We Collect
### Information You Provide- **Contact Information**: Name, email address when you use our contact form- **Project Details**: Information about your project needs when requesting a quote
### Automatically Collected Information- **Analytics Data**: Page views, session duration, bounce rate (via privacy-focused analytics)- **Technical Data**: Browser type, device type, screen resolution- **No Cookies**: This site does not use tracking cookies
## How We Use Your Information
We use collected information to:- Respond to your inquiries- Send project proposals and quotes- Improve our website and services- Analyze website performance
## Data Security
We implement appropriate technical and organizational security measures to protect your personal information.
## Third-Party Services
We use the following third-party services:- **Cloudflare**: Content delivery and DDoS protection- **Plausible Analytics**: Privacy-focused website analytics (no cookies)
## Your Rights
You have the right to:- Access your personal data- Correct inaccurate data- Request deletion of your data- Opt-out of communications
## Contact
For privacy concerns, contact: privacy@yourdomain.comTerms of Service
Section titled “Terms of Service”---# Draft copy for src/pages/terms.astro (a page you create)title: "Terms of Service"description: "Terms and conditions for using this website"noindex: true---
# Terms of Service
## Acceptance of Terms
By accessing this website, you agree to be bound by these Terms of Service.
## Intellectual Property
All content on this website is protected by copyright and other intellectual property laws.
## Use License
You may:- View and download materials for personal, non-commercial use- Share links to our content
You may not:- Modify or copy materials without permission- Use materials for commercial purposes- Remove any copyright notices
## Disclaimer
The information on this website is provided "as is" without warranties of any kind.
## Limitation of Liability
We shall not be liable for any damages arising from the use or inability to use materials on this website.
## Contact
For questions about these terms: legal@yourdomain.com404 Error Page
Section titled “404 Error Page”The template ships a minimal src/pages/404.astro; this is a richer version you can replace
it with.
---import BaseLayout from '@/layouts/BaseLayout.astro';import Container from '@/components/structural/Container.astro';import Section from '@/components/structural/Section.astro';import Button from '@/components/atoms/Button.astro';
const popularPages = [ { title: 'Homepage', href: '/', description: 'Start from the beginning' }, { title: 'Projects', href: '/projects', description: 'View my recent work' }, { title: 'Blog', href: '/blog', description: 'Read my latest articles' }, { title: 'Contact', href: '/contact', description: 'Get in touch' }];---
<BaseLayout title="404 - Page Not Found" description="The page you're looking for doesn't exist" noindex={true}> <Section size="xl"> <Container size="sm" class="text-center"> <div class="mb-8"> <div class="text-8xl font-bold text-primary-600 dark:text-primary-400"> 404 </div> <h1 class="mt-4 text-3xl font-bold">Page Not Found</h1> <p class="mt-4 text-lg text-foreground/80"> Sorry, we couldn't find the page you're looking for. It might have been moved, deleted, or never existed. </p> </div>
<div class="mb-12"> <Button href="./" size="lg"> Go Back Home </Button> </div>
<div class="border-t border-border pt-12"> <h2 class="text-xl font-semibold mb-6">Popular Pages</h2> <div class="grid gap-4 text-left max-w-md mx-auto"> {popularPages.map(page => ( <a href={page.href} class="block p-4 rounded-lg border border-border hover:border-primary-600 dark:hover:border-primary-400 transition-colors" > <div class="font-medium">{page.title}</div> <div class="text-sm text-foreground/60">{page.description}</div> </a> ))} </div> </div> </Container> </Section>
<script> // Log 404s for monitoring if (typeof window !== 'undefined') { const referrer = document.referrer || 'direct'; const path = window.location.pathname;
// Send to analytics if (window.analytics) { window.analytics.track('404_error', { path, referrer, timestamp: new Date().toISOString() }); } } </script></BaseLayout>Microcopy Guidelines (Showcase)
Section titled “Microcopy Guidelines (Showcase)”UI Text Patterns
Section titled “UI Text Patterns”export const microcopy = { // Buttons buttons: { primary: 'Get Started', secondary: 'Learn More', submit: 'Send Message', loading: 'Please Wait...', success: 'Success!', error: 'Try Again' },
// Form labels forms: { name: { label: 'Your Name', placeholder: 'John Doe', error: 'Please enter your name' }, email: { label: 'Email Address', placeholder: 'john@example.com', error: 'Please enter a valid email' }, message: { label: 'Your Message', placeholder: 'Tell me about your project...', error: 'Please enter a message' } },
// Status messages status: { loading: 'Loading content...', error: 'Something went wrong. Please try again.', offline: 'You appear to be offline. Check your connection.', success: 'Thank you! I\'ll get back to you soon.' },
// Empty states empty: { projects: 'No projects found. Check back soon!', posts: 'No posts match your search. Try different keywords.', comments: 'Be the first to comment!' }};