Skip to main content
Learn how to create, format, and publish blog posts in this Next.js portfolio.

Quick Start

1

Create a markdown file

Create a new .md file in src/content/blog/ with a descriptive slug:
touch src/content/blog/my-new-post.md
The filename (without .md) becomes the URL slug: /blog/post/my-new-post
2

Add frontmatter

Add YAML frontmatter at the top of the file with post metadata (see format below).
3

Write content

Write your post content using markdown syntax below the frontmatter.
4

Build and deploy

The post will be automatically generated at build time using Next.js static generation.

Frontmatter Format

Every blog post must start with YAML frontmatter enclosed by ---:
---
title: "My Post Title"
description: "Brief description for SEO and cards"
date: "Jan 30, 2026"
readTime: "5 min read"
image: "/blogs/my-image.jpeg"
slug: "my-new-post"
---

Field Reference

FieldTypeRequiredDescription
titlestringPost title displayed in listing and individual page
descriptionstringBrief description for SEO and post cards
datestringPublication date (e.g., “Jan 30, 2026” or “August 14, 2025”)
readTimestringEstimated reading time (e.g., “5 min read”)
imagestringPath to hero image (relative to public folder)
slugstringURL slug (should match filename without .md)
authorstringAuthor name (defaults to “Luan Nguyen”)
tagsarrayArray of tags for categorization
categorystringPost category (e.g., “Career & Experience”, “Technology”)
excerptstringCustom excerpt for SEO (auto-generated if not provided)
The slug field should match your filename without the .md extension. For example, if your file is my-post.md, the slug should be my-post.

Real Example

Here’s a real post from the portfolio: File: src/content/blog/intern-experience-aws.md
---
title: "My Internship Experience at AWS ☁️"
description: ""
date: "August 14, 2025"
readTime: "9 min read"
image: "/blogs/aws.jpeg"
slug: "intern-experience-aws"
author: "Luan Nguyen"
tags:
  ["AWS", "Internship", "Software Engineering", "Bedrock", "Seattle", "Career"]
category: "Career & Experience"
excerpt: "From onboarding challenges to building a proof-of-concept that increased throughput by 10%, here's my complete AWS internship journey."
---

_Note: I did sign an NDA, so I can't go too deep into certain details._

## Internship Search

I received my SDE Intern offer on January 1st, 2025, and accepted it just three days later...

## Seattle

Seattle was beautiful in the summer. It felt like a city built for exploration...

## Project

Here's the juicy part of the experience:

I was the first intern out of four to join the team...

Image Guidelines

Storing Images

Store blog images in the public/blogs/ directory:
public/
└── blogs/
    ├── aws.jpeg
    ├── openai-townhall.jpeg
    ├── figma-office.png
    └── ...

Using Images

Reference images in frontmatter and markdown:
# Hero image for the post
image: "/images/blog/my-image.jpeg"
Images are automatically optimized with Next.js Image component features including lazy loading, hover effects, and responsive sizing.

Image Styling

Images in blog posts receive automatic styling:
  • Rounded corners with shadow effects
  • Hover zoom animation (1.05x scale)
  • Figure captions using the alt text
  • Max width of 2xl for optimal readability
  • Lazy loading for performance
File: src/lib/blog.ts:193

Content Writing Tips

1

Start with an engaging opening

Use quotes, personal anecdotes, or thought-provoking questions to hook readers.
_"When people talk about traveling to the past, they worry about 
radically changing the present..."_
2

Use headings for structure

Break content into sections with ## (h2) and ### (h3) headings.
3

Add visuals

Include relevant images throughout your post to break up text and illustrate points.
4

Keep it personal

This is a personal portfolio blog - share experiences, learnings, and reflections.

Build Process

Blog posts are processed at build time:
1

File Reading

getSortedPostsData() reads all .md files from src/content/blog/File: src/lib/blog.ts:28
2

Frontmatter Parsing

gray-matter extracts YAML frontmatter and contentFile: src/lib/blog.ts:43
3

Markdown Processing

remark converts markdown to HTML with remark-htmlFile: src/lib/blog.ts:84
4

Custom Styling

applyCustomStyling() adds Spotify-themed CSS classesFile: src/lib/blog.ts:91
5

Static Generation

Next.js generates static HTML for each post at build time

Testing Your Post

Before deploying:
# Start the dev server
npm run dev

# Navigate to your post
open http://localhost:3000/blog/post/your-slug
If your post doesn’t appear, check that:
  • The file has a .md extension
  • Frontmatter is properly formatted with --- delimiters
  • The slug field matches your filename
  • All required fields are present

Common Issues

Post Not Appearing

# Check the file exists
ls src/content/blog/

# Verify frontmatter syntax
head -20 src/content/blog/your-post.md

Build Errors

Common causes:
  • Invalid YAML in frontmatter
  • Missing required fields
  • Special characters in title not escaped
  • Malformed image paths

Styling Issues

The markdown processor sanitizes HTML, so:
  • Don’t use raw HTML tags (use markdown instead)
  • Custom CSS classes won’t work in markdown
  • Use standard markdown syntax for best results

Next Steps

Markdown Support

Learn about supported markdown syntax and features

Blog Overview

Review blog architecture and components

Build docs developers (and LLMs) love