Skip to content

About

My personal website built with TypeScript, Next.js, and TailwindCSS

Topics

Resources

Stars

844 stars

Watchers

2 watching

Forks

Latest commit

 

History

5,170 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project Cover

nelsonlai.dev

Framework Language License

Welcome to my personal blog and portfolio website! This repository contains a modern Next.js application where I share my thoughts, projects, and insights.

Features

Core Technologies

  • Next.js 16 with App Router and React Compiler
  • React 19
  • TypeScript with strict configuration
  • Tailwind CSS v4 for styling
  • MDX for content (Content Collections)
  • Drizzle ORM with Zod schemas
  • next-intl for internationalization (6 locales)
  • oRPC for the type-safe API layer

UI/UX

  • Base UI for accessible UI components
  • Responsive design
  • Light/Dark mode
  • Image zoom in blog posts
  • Shiki for code syntax highlighting
  • Motion for animations
  • Table of contents for blog posts
  • Keyboard-driven command menu

Site Features

  • Guestbook
  • Admin dashboard with live stats
  • Account settings

Blog Features

  • Comment system
  • Like functionality
  • Post view counter
  • Blog post search
  • RSS feed
  • Sitemap

Performance & SEO

  • Lighthouse score of nearly 100
  • SEO optimized with meta tags and JSON-LD
  • Dynamic open graph images using next/og

Development Experience

  • Vitest for unit testing
  • Playwright for E2E testing
  • Oxlint configuration
  • Oxfmt code formatting
  • Knip for unused code detection
  • CSpell for spell checking
  • i18n-check for translation validation
  • Lefthook
  • Conventional commit
  • GitHub Actions CI

Authentication & Data

  • Better Auth
  • Redis caching with Upstash
  • Upstash for API rate limiting
  • t3-env for environment variables
  • Umami Analytics
  • Cloudflare R2 for image storage
  • Resend for transactional emails

Email Templates

Comment Notification

Comment notification template

Reply Notification

Reply notification template

Getting Started

Prerequisites

Project Structure

nelsonlai.dev/
├── .github/          # CI workflows and shared actions
├── .vscode/          # Editor settings and recommended extensions
├── public/           # Static assets (images, fonts, videos)
├── src/
│   ├── app/          # Next.js app router pages
│   ├── assets/       # Shared assets
│   ├── components/   # React components
│   ├── constants/    # Application constants
│   ├── content/      # MDX blog posts and content
│   ├── contexts/     # React contexts
│   ├── db/           # Database schema and migrations
│   ├── emails/       # Email templates
│   ├── hooks/        # Custom React hooks
│   ├── i18n/         # Internationalization
│   ├── lib/          # Utility libraries
│   ├── mdx-plugins/  # Custom Rehype and Remark plugins
│   ├── orpc/         # oRPC API routes
│   ├── styles/       # Global styles
│   ├── tests/        # Unit and E2E tests
│   └── utils/        # Utility functions
├── docker-compose.yml
└── package.json

Development

To run this project locally, you need to set up the development environment.

Setup

  1. Clone the repository:
git clone https://github.com/nelsonlaidev/nelsonlai.dev
  1. Navigate to the project directory:
cd nelsonlai.dev
  1. Install dependencies using pnpm:
pnpm install

Environment Setup

  1. Create .env.local using the variables documented in .env.schema. For the local Docker services, start with:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/nelsonlaidev
UPSTASH_REDIS_REST_URL=http://localhost:8079
UPSTASH_REDIS_REST_TOKEN=local-uprest-token-7f3c9a2e6b1d4f80
IP_ADDRESS_SALT=
BETTER_AUTH_SECRET=

Generate separate random values of at least 32 characters for IP_ADDRESS_SALT and BETTER_AUTH_SECRET (for example, with openssl rand -hex 32). Keep an existing IP_ADDRESS_SALT stable to preserve anonymous identifiers. Optional integrations can be left unset.

Varlock validates configuration against .env.schema, loads .env.local automatically, and generates env.d.ts. Next.js uses the official Varlock integration. Database scripts, test runners, and Knip load configuration through varlock/auto-load in their Node.js entry points; external CLIs such as React Email use varlock run. Application code reads typed values directly from varlock/env.

Validate your environment before continuing:

pnpm env:check
  1. Run required services using Docker:
docker compose up -d
  1. Run the database migrations:
pnpm db:migrate
  1. Seed the database:
pnpm db:seed
  1. Run the app:
pnpm dev          # Run the development server
# or
pnpm email:dev    # Run the email preview server separately

The services will be available at the following URLs:

Service URL
App localhost:3000
React Email localhost:3001
Database localhost:5432
Redis localhost:6379
Redis serverless localhost:8079

Available Scripts

# Development
pnpm dev                # Start development server
pnpm email:dev          # Run email preview server

# Build & Production
pnpm build              # Build for production
pnpm start              # Start production server
pnpm analyze            # Analyze bundle size
pnpm build:mdx          # Build MDX collections
pnpm typegen            # Generate types

# Quality & Testing
pnpm env:check          # Validate environment variables
pnpm check              # Run all quality checks (lint, typecheck, format, etc.)
pnpm lint               # Run Oxlint
pnpm lint:fix           # Auto-fix lint issues
pnpm lint:spell         # Run spell check
pnpm typecheck          # Run TypeScript type checking
pnpm format             # Format code with Oxfmt
pnpm format:check       # Check formatting
pnpm knip               # Find unused dependencies/exports
pnpm check:i18n         # Validate translations
pnpm test:unit          # Run unit tests
pnpm test:unit:coverage # Run unit tests with coverage
pnpm test:e2e           # Run Playwright E2E tests
pnpm test:e2e:install   # Install Playwright browsers

# Database
pnpm db:generate        # Generate database migrations
pnpm db:migrate         # Run database migrations
pnpm db:seed            # Seed the database
pnpm db:push            # Push schema changes directly to DB
pnpm db:reset           # Reset database
pnpm db:studio          # Open Drizzle Studio

# Emails & Cleanup
pnpm email:export       # Export email templates
pnpm clean              # Clean build artifacts

Credits

This project has been made possible thanks to the wonderful open-source community. Special thanks to:

This project also uses/adapts the following open-source projects:

The following projects were referenced for inspiration:

Author

Donation

If you find this project helpful, consider supporting me by sponsoring the project.

License

This project is open source and available under the MIT License.


Made with ❤️ in Hong Kong

About

My personal website built with TypeScript, Next.js, and TailwindCSS

Topics

Resources

Stars

844 stars

Watchers

2 watching

Forks

Sponsor this project

Used by

Contributors

Languages