astro-template/SETUP.md
Nicholai d384abea33 feat: add initial scaffolding, configuration, and documentation
- Create .gitignore, .env.example, README.md, LICENSE
- Add astro.config.mjs and template.config.json
- Scaffold .vscode extensions, launch, and settings
- Add CLAUDE.md with development commands and guidelines
- Include public assets, fonts, and media files
- Add src components, layouts, pages, and utils
- Add cursor rules and worktrees configuration
- Add package.json, pnpm-lock.yaml, and tsconfig.json
2025-12-27 04:37:55 -07:00

10 KiB

Setup Guide

Complete step-by-step guide to setting up and customizing your Astro portfolio template.

Table of Contents

  1. Initial Setup
  2. Template Personalization
  3. Content Customization
  4. Media Assets
  5. Design Customization
  6. Deployment
  7. Optional Features
  8. Troubleshooting

Initial Setup

Prerequisites

Before you begin, make sure you have:

  • Node.js 18 or later - Download here
  • pnpm (recommended) - Install with npm install -g pnpm
  • Git - Download here
  • A code editor (VS Code recommended)

Installation

  1. Clone or download the template

    git clone <repository-url>
    cd astro-template
    
  2. Install dependencies

    pnpm install
    
  3. Verify installation

    pnpm dev
    

    Open http://localhost:4321 - you should see the template with placeholder content.

Template Personalization

Run the setup wizard to personalize all template files:

node init-template.js

The wizard will ask for:

  • Your name and profession
  • Site URL and description
  • Contact information (email, location)
  • Social media links
  • Company/branding details
  • Cloudflare project name

Review the summary and confirm to apply changes.

Option 2: Manual Configuration

Edit template.config.json with your information, then run:

node init-template.js --config

What Gets Updated

The setup script updates:

  • src/consts.ts - Site-wide constants
  • src/components/BaseHead.astro - SEO and structured data
  • src/components/Navigation.astro - Branding
  • src/components/Footer.astro - Contact and social links
  • src/content/sections/hero.mdx - Hero section
  • src/content/sections/experience.mdx - Work history
  • src/content/pages/contact.mdx - Contact page
  • astro.config.mjs - Site URL
  • wrangler.jsonc - Cloudflare project name
  • package.json - Package name

Content Customization

Homepage Sections

Edit files in src/content/sections/:

Hero Section (hero.mdx)

---
headlineLine1: "YOUR NAME"
headlineLine2: "HERE"
portfolioYear: "Portfolio 2025"
location: "Your City, State"
locationLabel: "Location"
bio: "Your professional bio..."
---

Experience (experience.mdx)

---
sectionTitle: "Experience"
sectionSubtitle: "History"
sectionLabel: "/// Your professional journey."
entries:
  - systemId: "SYS.01"
    status: "ACTIVE"
    dates: "2020 — PRESENT"
    company: "Company Name"
    role: "Your Role"
    tags: ["Skill 1", "Skill 2"]
    description: "What you do..."
    achievements:
      - label: "Projects"
        text: "Notable projects..."
    link:
      url: "https://company.com"
      text: "Visit Website"
---

Skills (skills.mdx)

---
sectionTitle: "Technical"
sectionSubtitle: "Arsenal"
description: "Your skills and specialties"
skills:
  - id: "01"
    domain: "Primary Skill"
    tools: "Tool 1 • Tool 2 • Tool 3"
    proficiency: "Expert"
---
---
role: "Your Role"
client: "Client Name"
year: "2024"
region: "Global"
projectTitle: "Project"
projectSubtitle: "Name"
projectDescription: "Brief description..."
stats:
  - label: "Category"
    value: "Value"
videoUrl: "/media/your-video.mp4"
linkUrl: "/blog/your-case-study/"
---

Blog Posts

Creating a New Post

  1. Create a new MDX file in src/content/blog/:

    touch src/content/blog/my-new-post.mdx
    
  2. Add frontmatter and content:

    ---
    title: 'Your Post Title'
    description: 'Brief description for SEO'
    pubDate: 'Dec 27 2024'
    heroImage: '../../assets/hero-image.avif'
    featured: false
    category: 'Tutorial'
    tags: ['Web Dev', 'Astro']
    ---
    
    ## Introduction
    
    Your content here...
    
  3. The file name becomes the URL slug:

    • my-new-post.mdx/blog/my-new-post/

Blog Frontmatter Fields

Required:

  • title - Post title
  • description - SEO description
  • pubDate - Publication date

Optional:

  • heroImage - Header image path
  • featured - Set to true to feature on blog index
  • category - For filtering
  • tags - Array of tags
  • updatedDate - Last update date

Example Blog Post Template

See dev/blog_template.mdx for a complete example.

Contact Page

Edit src/content/pages/contact.mdx:

---
pageTitleLine1: "Get In"
pageTitleLine2: "Touch"
availabilityText: "Available for new projects"
email: "your@email.com"
location: "Your City"
coordinates: "XX.XXXX° N, XX.XXXX° W"
socialLinks:
  - name: "LinkedIn"
    url: "https://linkedin.com/in/yourprofile"
formLabels:
  name: "/// Your Name"
  email: "/// Your Email"
  subject: "/// Subject"
  message: "/// Message"
  submit: "Send Message"
subjectOptions:
  - value: "project"
    label: "Project Inquiry"
---

Media Assets

Images

Placeholder Images to Replace

See public/media/PLACEHOLDER_ASSETS.md for a complete list.

Priority replacements:

  1. Default OG image: src/assets/nicholai-medium-portrait.avif
  2. Blog post hero images
  3. Featured project video
  4. Favicons

Adding Your Images

  1. For blog/content images (optimized by Astro):

    • Place in src/assets/
    • Reference: ../../assets/image-name.jpg
  2. For videos/large files (static):

    • Place in public/media/
    • Reference: /media/filename.mp4

Converting to AVIF

AVIF provides superior compression. Convert your images:

# Convert all images
pnpm convert:avif:all

# Convert specific formats
pnpm convert:avif:jpeg
pnpm convert:avif:png

# Custom quality (0-100)
node src/utils/convert-to-avif.js --jpeg --quality 80

Favicons

Generate a complete favicon set:

  1. Use favicon.io or RealFaviconGenerator
  2. Replace files in public/:
    • favicon.ico
    • favicon-32.png
    • favicon-192.png
    • apple-touch-icon.png
    • favicon.svg

Design Customization

Color Scheme

Edit CSS custom properties in src/styles/global.css:

:root {
  /* Background colors */
  --theme-bg-primary: #0B0D11;
  --theme-bg-secondary: #12141A;

  /* Text colors */
  --theme-text-primary: #E8E9ED;
  --theme-text-muted: #9CA3B3;

  /* Accent colors */
  --brand-accent: #3D8374;
}

Typography

Fonts are loaded in src/components/BaseHead.astro. To change:

  1. Update Google Fonts link (line 124-137)
  2. Update font families in global.css

Design System

Full design documentation in dev/design.json:

  • Color palettes
  • Typography scales
  • Spacing system
  • Grid system
  • Component patterns

Deployment

Cloudflare Pages (Default)

Option 1: CLI Deployment

pnpm deploy

Option 2: Git Integration

  1. Push your code to GitHub/GitLab
  2. Go to Cloudflare Pages Dashboard
  3. Connect your repository
  4. Configure build settings:
    • Build command: pnpm build
    • Build output directory: dist
    • Root directory: /
    • Node version: 18 or later
  5. Deploy!

Environment Variables

For Cloudflare Pages deployment:

  1. Go to your project settings → Environment Variables
  2. Add any required variables (e.g., API keys for forms)

Custom Domain

  1. In Cloudflare Pages, go to Custom Domains
  2. Add your domain
  3. Follow DNS configuration instructions

Other Platforms

Vercel:

# Change adapter
pnpm remove @astrojs/cloudflare
pnpm add @astrojs/vercel

Update astro.config.mjs:

import vercel from '@astrojs/vercel/serverless';

export default defineConfig({
  adapter: vercel(),
  // ...
});

Netlify:

pnpm remove @astrojs/cloudflare
pnpm add @astrojs/netlify

Static (no adapter): Remove the adapter from astro.config.mjs for pure static site generation.

Optional Features

AI-Powered Git Commits

  1. Get an API key from OpenRouter.ai

  2. Create src/utils/.env:

    OPENROUTER_API_KEY=your_key_here
    
  3. Stage changes and run:

    pnpm commit
    

The script generates a commit message, lets you edit it, and optionally pushes.

Analytics

Add analytics to src/components/BaseHead.astro:

<!-- Example: Plausible -->
<script defer data-domain="yoursite.com" src="https://plausible.io/js/script.js"></script>

Contact Form Integration

The template includes a contact form. To make it functional:

Option 1: Cloudflare Forms (Recommended)

  • Forms are built-in with Cloudflare Pages
  • View submissions in your Cloudflare Dashboard

Option 2: External Service

Update the form action in src/pages/contact.astro.

Troubleshooting

Build Errors

"Cannot find module..."

# Reinstall dependencies
rm -rf node_modules pnpm-lock.yaml
pnpm install

TypeScript errors

# Generate types
pnpm cf-typegen

Dev Server Issues

Port already in use

# Use a different port
pnpm dev -- --port 3000

Changes not reflecting

  • Hard reload: Ctrl+Shift+R (Windows) / Cmd+Shift+R (Mac)
  • Clear .astro cache and restart

Image Issues

Images not loading

  • Check file paths (relative vs absolute)
  • Ensure images are in correct directory
  • Restart dev server

AVIF conversion fails

# Install Sharp dependencies
pnpm install sharp

Deployment Issues

Build fails on Cloudflare

  • Check Node version (should be 18+)
  • Verify pnpm build works locally
  • Check build logs for specific errors

404 on deployed site

  • Verify build output directory is dist
  • Check routing/links are correct
  • Clear Cloudflare cache

Next Steps

  1. Test your site locally: pnpm dev
  2. Build for production: pnpm build
  3. Preview build: pnpm preview
  4. Deploy: pnpm deploy
  5. Update dev/continuity.md with your changes

Support


Need help? Check the existing blog posts for examples of how to use various features.