Portfolio Template

Portfolio Template

A reusable Next.js 13 portfolio template — App Router, TypeScript, Framer Motion animations, and secure contact form via React Email + Resend. Used by me at whyian.dev.

Type
Web
Role
Solo
Status
Archived
Tech
Next.js 13 TypeScript Tailwind CSS Framer Motion React Email Resend
Started
Sep 2023

Overview

A fully responsive Next.js 13 portfolio template built around the then-new App Router, with TypeScript from day one, Framer Motion animations, and a working contact form wired to Resend. I use it at whyian.dev. The repo is public so anyone can fork it as a starting point for their own personal site.

Features

  • Latest Next.js 13 — App Router, Server Actions, and the split between Client and Server components built in from the start.
  • TypeScript end-to-end — every component, hook, and API route is typed, so refactoring is fearless.
  • Tailwind CSS + light/dark mode — clean responsive UI that adapts to system preference.
  • Framer Motion — smooth scroll-driven and hover animations for section transitions, card reveals, and subtle micro-interactions.
  • Secure email via React Email + Resend — the contact form composes an email template with React.Email, sends it through Resend, and validates input server-side so the form can’t be abused.
  • Custom React hooks — small utility hooks for scroll position, section-in-view detection, and active-section tracking.
  • Performance — Lighthouse 95+, average load time under 100ms on the deployed version.
  • 100% responsive — works cleanly down to 360px mobile.

Stack

  • Framework: Next.js 13 with App Router
  • Language: TypeScript 5
  • Styling: Tailwind CSS with a custom design system
  • Animation: Framer Motion
  • Email: React.Email for templating, Resend for delivery
  • Hosting: Vercel

Notable bits

  • Server Actions for the contact form — no separate API route, the form just posts to a server action that validates and calls Resend. Cleaner code, one less abstraction layer.
  • Scroll-driven section tracking — a custom useActiveSection hook observes scroll position and highlights the current section in the nav, using IntersectionObserver so it’s cheap.
  • Dark mode as a design constraint, not an afterthought — every color in the palette was chosen to look right in both themes, not just flipped via an inverted filter.