- 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
10 KiB
Setup Guide
Complete step-by-step guide to setting up and customizing your Astro portfolio template.
Table of Contents
- Initial Setup
- Template Personalization
- Content Customization
- Media Assets
- Design Customization
- Deployment
- Optional Features
- 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
-
Clone or download the template
git clone <repository-url> cd astro-template -
Install dependencies
pnpm install -
Verify installation
pnpm devOpen http://localhost:4321 - you should see the template with placeholder content.
Template Personalization
Option 1: Interactive Setup (Recommended)
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 constantssrc/components/BaseHead.astro- SEO and structured datasrc/components/Navigation.astro- Brandingsrc/components/Footer.astro- Contact and social linkssrc/content/sections/hero.mdx- Hero sectionsrc/content/sections/experience.mdx- Work historysrc/content/pages/contact.mdx- Contact pageastro.config.mjs- Site URLwrangler.jsonc- Cloudflare project namepackage.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"
---
Featured Project (featured-project.mdx)
---
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
-
Create a new MDX file in
src/content/blog/:touch src/content/blog/my-new-post.mdx -
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... -
The file name becomes the URL slug:
my-new-post.mdx→/blog/my-new-post/
Blog Frontmatter Fields
Required:
title- Post titledescription- SEO descriptionpubDate- Publication date
Optional:
heroImage- Header image pathfeatured- Set totrueto feature on blog indexcategory- For filteringtags- Array of tagsupdatedDate- 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:
- Default OG image:
src/assets/nicholai-medium-portrait.avif - Blog post hero images
- Featured project video
- Favicons
Adding Your Images
-
For blog/content images (optimized by Astro):
- Place in
src/assets/ - Reference:
../../assets/image-name.jpg
- Place in
-
For videos/large files (static):
- Place in
public/media/ - Reference:
/media/filename.mp4
- Place in
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:
- Use favicon.io or RealFaviconGenerator
- Replace files in
public/:favicon.icofavicon-32.pngfavicon-192.pngapple-touch-icon.pngfavicon.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:
- Update Google Fonts link (line 124-137)
- 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
- Push your code to GitHub/GitLab
- Go to Cloudflare Pages Dashboard
- Connect your repository
- Configure build settings:
- Build command:
pnpm build - Build output directory:
dist - Root directory:
/ - Node version: 18 or later
- Build command:
- Deploy!
Environment Variables
For Cloudflare Pages deployment:
- Go to your project settings → Environment Variables
- Add any required variables (e.g., API keys for forms)
Custom Domain
- In Cloudflare Pages, go to Custom Domains
- Add your domain
- 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
-
Get an API key from OpenRouter.ai
-
Create
src/utils/.env:OPENROUTER_API_KEY=your_key_here -
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
.astrocache 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 buildworks 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
- Test your site locally:
pnpm dev - Build for production:
pnpm build - Preview build:
pnpm preview - Deploy:
pnpm deploy - Update
dev/continuity.mdwith your changes
Support
- Astro Documentation: docs.astro.build
- Cloudflare Pages: developers.cloudflare.com/pages
- Tailwind CSS: tailwindcss.com/docs
Need help? Check the existing blog posts for examples of how to use various features.