A minimal dev portfolio with a built-in blog — Next.js App Router, Tailwind v4, shadcn/ui, and a headless Fumadocs content pipeline for writing posts in MDX.
- Next.js 16 (App Router, Turbopack) + React 19
- Tailwind CSS v4
- shadcn/ui — components in
src/components/uiare generated by the shadcn CLI; treat them as vendored, not hand-edited - Fumadocs — headless MDX loader for the blog (no Fumadocs UI theme; pages are rendered with this site's own components)
pnpm install
pnpm devOpen http://localhost:3000.
Everything you're likely to want to change lives in src/config/:
author.ts— your name, role, blurb, location, avatar, and time zonesocials.ts— your links; themailto:entry renders as a hover-to-copy email instead of amailto:linkwork.ts— work historyprojects.ts— featured projectssite.ts— site title, description, URL, keywords, and your GitHub username (used for the contributions graph)
A few other things to swap:
- Avatar — set
AUTHOR.avatarUrlinsrc/config/author.ts - OG image — replace the file behind
SITE_CONFIG.ogImageinsrc/config/site.ts
Add a .mdx file to content/blog/ with frontmatter:
---
title: Your post title
description: A short summary (optional)
date: "2026-01-15"
author: Your Name
tags:
- meta
published: true
---
Your content here.title,dateare required;description,author,tagsare optional.publisheddefaults totrue— set it tofalseto keep a draft out of the sorted post list without deleting the file.- Posts are sorted newest-first and the home page teases the latest three.
src/components/ui/**is shadcn-generated — regenerate with the shadcn CLI rather than hand-editing.- The GitHub contributions graph calls an unofficial API and fails closed: if it errors or returns no data, that section just doesn't render.