Introduction
Welcome to my Next.js Portfolio Website – a project that highlights both my technical expertise and commitment to modern web development. Built with Next.js 15, this site goes beyond a basic showcase; it reflects a focus on performance, accessibility, and delivering a refined user experience.
As a fullstack developer, I aim to build solutions that are technically robust and visually polished. This portfolio leverages a carefully curated tech stack, including TypeScript for type safety, Tailwind CSS for responsive design, and Radix UI for accessible components. It strategically combines Static Site Generation (SSG) and Server-Side Rendering (SSR) to maximize performance across devices.
Key Highlights:
- Type-safe development with TypeScript and Zod for validation
- Content management via MDX with component-based markdown
- PostHog analytics for web analytics insights
- Clean Git workflow using Husky and lint-staged
- Performance tuning with Next.js’s latest features
- SEO-optimized with dynamic OG image generation
This is not just a personal site—it's a living project that evolves with my growth in fullstack development. I treat it as a platform to implement best practices, explore new tools, and optimize for performance and user experience.
Key Stats
- Built with Next.js 15 and TypeScript
- 90+ Lighthouse performance score
- 100% accessibility score with Radix UI
- Fully SEO-ready with automated Open Graph image generation
Definitions, Acronyms, and Abbreviations
- Radix UI – Accessible, unstyled React UI primitives
- shadcn/ui – Styled Radix-based component library using Tailwind
- Zod – TypeScript-first validation library
- Biome – Fast formatter/linter replacing ESLint + Prettier
- Ultra Cite - Ultracite is a highly opinionated preset for Biome, designed to help you and your AI models write consistent and type-safe code without the hassle of configuration.
- lint-staged – Runs linters on staged Git files
- Husky – Git hooks manager
- MDX – Markdown + JSX hybrid for rich content
- PostHog – Open-source product analytics
- Tailwind CSS – Utility-first CSS framework
- SEO – Search Engine Optimization
- Cache Components – Cache Components is a new approach to rendering and caching in Next.js that provides fine-grained control over what gets cached and when, while ensuring a great user experience through Partial Pre-rendering (PPR)
- unstable_ViewTransition – View Transition is an experimental flag that activates React 19's new View Transitions API.
- Open Graph image – Social media preview image defined by
meta og:image
Technical Stack
- Framework: Next.js 16 (App Router) with TypeScript
- UI:
- Tailwind CSS
- Radix UI
- shadcn/ui
- Content Management:
MDX+gray-matter,sugar-high - State Management: React Hooks
- Forms: React Hook Form + Zod
- Animations: Framer Motion, View Transitions
- Analytics: PostHog
- Tooling:
- Biome (formatter/linter)
- Ultracite (rule preset)
- Husky + lint-staged
- TypeScript
- Bun (runtime & package manager)
@t3-oss/envfor environment validation
- Security:
- ReCaptcha
- Arcjet (email checks, rate limiting)
- Cloudflare (DDoS protection)
- Rendering: SSR + SSG (hybrid architecture)
Functional Requirements
Content Management
- MDX-Based Content Creation: Content is managed and rendered dynamically using MDX, allowing for rich, component-based markdown.
- Dynamic Blog & Project Creation: Easily create and manage blog posts and project showcases with a flexible structure.
- Content Categorization: Content can be categorized into types such as blogs, projects, terms of service, and privacy policy.
- Metadata Management: Each piece of content supports metadata like title, summary, tags, author, and publish date to enrich the content experience.
Navigation & Routing
- Dynamic Route Generation: Routes for content pages are generated dynamically based on content metadata, ensuring scalability and maintainability.
- Category-Based Content Organization: Categories such as "blogs", "projects", etc., are used for logical grouping of content for easier navigation.
- Static & Dynamic Routing: The project makes full use of Next.js's App Router, ensuring both static and dynamic routing options for optimal flexibility.
User Interface
- Responsive Design: The website is designed to be fully responsive, adapting seamlessly to all screen sizes, from mobile to large desktops.
- Accessible UI Components: Accessibility is a priority, using Radix UI components that ensure the app is usable for everyone.
- Animated Transitions: Smooth transitions and interactions are implemented using Framer Motion for enhanced user engagement.
- Skeleton Screens: During content loading, skeleton screens are displayed to provide a visual cue and improve user experience.
Analytics & Tracking
- User Interaction Tracking: PostHog is integrated to track user interactions and provide insights into user behavior.
- Usage Metrics: Website usage statistics are collected and analyzed to identify areas for improvement.
- Engagement Monitoring: User engagement, behavior, and retention are closely monitored to ensure a delightful experience.
SEO & Social Media
- Dynamic Open Graph Images: Automatic generation of Open Graph images ensures enhanced social media sharing with accurate previews.
- Automated SEO Metadata: The project generates SEO-optimized metadata automatically for each page, boosting search engine rankings.
- RSS Feed Generation: RSS feeds are dynamically created for blog posts, making it easier for users to follow updates.
- Meta Tags for SEO: Proper meta tags are implemented to ensure visibility and proper ranking on search engines.
Non-Functional Requirements
Performance
- Lighthouse Score: The project maintains a Lighthouse performance score of 90+, ensuring fast load times and a smooth user experience.
- Accessibility: Achieves 100% accessibility with Radix UI, providing a seamless experience for users with disabilities.
- Hybrid Rendering Strategy:
- 85% of pages are rendered using Static Site Generation (SSG) for maximum speed.
- 15% of pages use Server-Side Rendering (SSR) for dynamic content like the RSS feed and Open Graph images.
- Caching: The use of caching mechanisms has reduced SSR response times by 60% for frequently accessed content.
Security
- DDoS Protection: Cloudflare is used to secure the website against DDoS attacks and malicious traffic.
- Email Security: Arcjet is integrated to perform email security checks, ensuring proper validation.
- Rate Limiting: API endpoints are protected using rate limiting to prevent abuse and ensure fair usage.
- Secure Environment Variables: All environment variables are validated to prevent misconfigurations or leaks.
Maintainability
- Type-Safe Development: The codebase strictly adheres to TypeScript best practices, ensuring type safety and reducing runtime errors.
- Folder Structure: A well-organized folder structure ensures easy scalability and maintenance as the project grows.
- Code Formatting & Linting: Biome is used for code formatting and linting, ensuring consistency and clean code.
- Git Hooks: Husky and lint-staged are used for pre-commit hooks to maintain high code quality during development.
Scalability
- Module-based architecture: Adopts a Domain-Driven Design approach, where related functionality is encapsulated in specific modules.
- Module structure: Each module resides in the
src/modulesfolder, with all components, views, actions, and sections related to a specific feature grouped together. - Example (Home module): All components related to the Home page (or the root route
/) are contained within thesrc/modules/homedirectory.- Includes UI components, home sections, views, and actions.
- Separation of concerns: Ensures clear division of functionality, making it easier to scale and maintain individual features.
- Scalability: Each module can be developed, tested, and scaled independently, promoting flexibility and efficiency in development.
src/modules # Modules structure├── blogs # Blogs module│ ├── ui # Blog ui components collection│ │ ├── components # Blog ui components (domain specific atomic & molecules level )│ │ ├── sections # Blog ui sections (organisms level)│ │ └── views # Blog ui views (templates level)│ └── blog-constants.ts # Blog constants├── categories # Categories module│ └── ui # Categories ui components collection│ ├── components # Categories ui components (domain specific atomic & molecules level )│ ├── sections # Categories ui sections (organisms level)│ └── views # Categories ui views (templates level)├── contact # Contact module│ ├── actions # Contact server actions│ ├── email-template # Contact email template│ ├── schema # Contact form schema│ └── ui # Contact ui components collection├── content # Content module│ └── ui # Content ui components collection│ ├── components # Content ui components (domain specific atomic & molecules level )│ ├── sections # Content ui sections (organisms level)│ └── views # Content ui views (templates level)├── home # Home module│ ├── ui # Home ui components collection│ │ ├── components # Home ui components (domain specific atomic & molecules level )│ │ ├── sections # Home ui sections (organisms level)│ │ └── views # Home ui views (templates level)│ └── home-constants.ts # Home constants├── newsletter # Newsletter module│ ├── actions # Newsletter server actions│ ├── schema # Newsletter form schema│ └── ui # Newsletter ui components collection└── projects # Projects module├── ui # Projects ui components collection└── project-constants.ts # Projects constants
Accessibility
- WCAG Compliance: The website follows WCAG guidelines to ensure accessibility for all users.
- Keyboard Navigation: The app supports full keyboard navigation, ensuring users with disabilities can interact with all content.
- ARIA Attributes: Proper ARIA attributes are used across the UI for better screen reader support.
Development & Build
- Fast Development Environment: The project uses the Bun runtime for fast and efficient development.
- Automated Build & Deployment: Continuous Integration (CI) and Continuous Deployment (CD) pipelines ensure automatic builds and deployments.
- Environment-Specific Configurations: The project supports environment-specific configurations for different stages of the development lifecycle.
Image Optimization
- Responsive Image Delivery: The project uses next/image for responsive image delivery, ensuring optimal image sizes for different devices.
- LQIP: Low Quality Image Placeholders (LQIP) are used to improve the perceived load time for images.
- Image Caching: Images are optimized for fast loading and caching to reduce server load.
Caching
- Server-Side Caching: unstable_cache is implemented for SSR routes, improving response times and reducing server load.
- Content Revalidation: Revalidation strategies are employed to ensure cached content is updated regularly and doesn't become stale.
- Cache Invalidation: Efficient cache invalidation processes ensure that updates to content are reflected in real time.
Folder Structure
portfolio # Project root├── .husky/ # Husky hooks├── .vscode/ # VSCode configuration├── content/ # Content folder (MDX files)├── node_modules/ # Node modules├── public/ # Public folder├── src/ # Source folder│ ├── app/ # App folder (Next.js pages, API routes, etc.)│ ├── components/ # Components folder (Shared Atomic level (shadcn), Molecules level ui components & Providers)│ ├── env/ # Environment folder (Server & client side environment variables)│ ├── hooks/ # Hooks folder│ ├── lib/ # Lib folder│ └── modules/ # Modules folder├── .env # Environment variables├── biome.json # Biome configuration (Formatting, Linting, etc.)├── bun.lock # Bun lock file├── next.config.ts # Next.js configuration├── package.json # Package.json├── tsconfig.json # TypeScript configuration└── README.md # README file
Code Samples
Content Type Definition
export type Content = {metadata: ContentMetadata;content: string;};export type ContentMetadata = {title?: string;summary?: string;image?: string;imageSizes?: string;tags?: string[];author?: string;publishedAt?: string;slug: string;category: string;};export type ContentType =| "projects"| "blogs"| "terms-of-services"| "privacy-policy";
Static Site Generation
import { getContents } from "@/lib/mdx-utils";export async function generateStaticParams() {const contents = await getContents("blogs");return contents.map((content) => ({category: content.metadata.category,}));}
Caching with Nextjs's 'use cache'
export async function getContents(dir: ContentType,limit?: number): Promise<Content[]> {"use cache";cacheTag(`contents-${dir}-${limit}`);cacheLife({revalidate: REVALIDATION_INTERVAL.THREE_HOURS,stale: REVALIDATION_INTERVAL.ONE_HOUR,expire: REVALIDATION_INTERVAL.THREE_DAYS,});return getMdxData(dir, limit);}
Performance Optimizations
- ~85% of pages statically generated at build time via SSG
- SSR used for dynamic routes (e.g., RSS feeds, OG images)
unstable_cachereduces SSR response time by ~60%- Client-side rendering limited to ~15% (e.g., forms, pagination)
- React Suspense for deferred loading of non-critical UI
- Skeleton screens for better perceived performance
- Optimized images using:
next/imagefor responsive delivery- LQIP placeholders via
@plaiceholder/next