Reviewed-on: #1
nicholai-work-2026
Personal portfolio and blog site built with Astro.
Tech Stack
- Astro - Static site framework
- React - Interactive components
- Tailwind CSS - Styling
- MDX - Markdown with JSX support
- Cloudflare Pages - Hosting & deployment
- TypeScript - Type safety
Development
# Install dependencies
pnpm install
# Start dev server
pnpm dev
# Build for production
pnpm build
# Preview production build
pnpm preview
# Deploy to Cloudflare Pages
pnpm deploy
Creating Blog Posts
Blog posts are created as MDX files in the src/content/blog/ directory. The file name becomes the URL slug (e.g., my-post.mdx → /blog/my-post/).
Step 1: Create the MDX File
Create a new .mdx file in src/content/blog/:
src/content/blog/my-new-post.mdx
Step 2: Add Frontmatter
Every blog post requires frontmatter at the top of the file. Here's the complete schema:
---
title: 'Your Post Title'
description: 'A brief description that appears in listings and meta tags'
pubDate: 'Jan 15 2025'
heroImage: '../../assets/your-image.jpg'
featured: true
category: 'Case Study'
tags: ['VFX', 'Houdini', 'Nuke']
---
Required Fields
title(string) - The post titledescription(string) - Brief description for listings and SEOpubDate(string) - Publication date in any format (e.g.,'Jan 15 2025','2025-01-15')
Optional Fields
heroImage(image path) - Hero image for the post. Use relative path from the MDX file:- Images in
src/assets/:'../../assets/image.jpg' - Images in
public/media/: Use absolute path in content:/media/image.jpg
- Images in
featured(boolean, default:false) - Set totrueto feature on blog index pagecategory(string) - Category for filtering (e.g.,'Case Study','Tutorial','Thoughts')tags(array of strings) - Tags for categorization and related postsupdatedDate(string) - Optional update date
Step 3: Write Your Content
Write your content using Markdown or MDX syntax. You can use:
- Standard Markdown (headings, lists, links, etc.)
- JSX components and HTML
- Custom styling with Tailwind classes
Example: Adding Videos
<div class="video-container my-10">
<video controls class="w-full border border-white/10">
<source src="/media/my-video.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
<p class="text-slate-500 text-sm mt-3 font-mono">/// VIDEO CAPTION</p>
</div>
Example: Image Grids
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 my-10">
<div class="video-container">
<video controls class="w-full border border-white/10">
<source src="/media/video-1.mp4" type="video/mp4" />
</video>
<p class="text-slate-500 text-sm mt-3 font-mono">/// CAPTION 1</p>
</div>
<div class="video-container">
<video controls class="w-full border border-white/10">
<source src="/media/video-2.mp4" type="video/mp4" />
</video>
<p class="text-slate-500 text-sm mt-3 font-mono">/// CAPTION 2</p>
</div>
</div>
Step 4: Adding Images
Option 1: Images in src/assets/
For images processed by Astro (optimization, etc.):
- Place image in
src/assets/ - Reference in frontmatter:
heroImage: '../../assets/my-image.jpg' - Use in content with Astro's Image component (import required)
Option 2: Images in public/media/
For static assets (videos, large images):
- Place file in
public/media/ - Reference with absolute path:
/media/my-video.mp4 - No import needed, works directly in HTML/MDX
Step 5: File Naming
- Use kebab-case:
my-awesome-post.mdx - The filename (without extension) becomes the URL slug
- Example:
gstar-raw-olympics.mdx→/blog/gstar-raw-olympics/
Complete Example
Here's a complete example blog post:
---
title: 'My Awesome Project'
description: 'A deep dive into the technical pipeline behind this amazing project.'
pubDate: 'Jan 15 2025'
heroImage: '../../assets/project-hero.jpg'
featured: true
category: 'Case Study'
tags: ['VFX', 'Houdini', 'Pipeline']
---
## Introduction
This is the introduction to my project.
## The Challenge
Here's what we were trying to solve.
<div class="video-container my-10">
<video controls class="w-full border border-white/10">
<source src="/media/project-video.mp4" type="video/mp4" />
</video>
<p class="text-slate-500 text-sm mt-3 font-mono">/// PROJECT VIDEO</p>
</div>
## Technical Approach
### Key Features
- Feature one
- Feature two
- Feature three
## Results
The project was a success!
Blog Features
- Automatic sorting - Posts are sorted by
pubDate(newest first) - Featured posts - First post with
featured: trueappears in hero section - Related posts - Automatically finds related posts by category or shared tags
- Category filtering - Users can filter posts by category on the blog index
- Previous/Next navigation - Automatic navigation between posts
- RSS feed - Available at
/rss.xml
Project Structure
src/
├── assets/ # Images processed by Astro
├── components/ # Reusable components
├── content/
│ ├── blog/ # Blog posts (MDX files)
│ ├── pages/ # Page content
│ └── sections/ # Homepage sections
├── layouts/ # Page layouts
├── pages/ # Routes
└── styles/ # Global styles
Deployment
The site is deployed to Cloudflare Pages. The pnpm deploy command builds the site and deploys it using Wrangler.
Deployment happens automatically on push to the main branch (if configured in Cloudflare Pages dashboard).
Description
Languages
Astro
58.1%
MDX
19%
HTML
13.1%
CSS
5.9%
TypeScript
3.5%
Other
0.4%