When working on complex interfaces for marketing agencies or e-commerce brands, the difference between a "good" site and a "great" site usually comes down to architecture. With the shift to Next.js App Router, the way we handle state, layouts, and server-side data has completely changed.
In this post, I want to outline my standard setup for a high-performance web application, starting from the folder structure to the deployment pipeline.
The Folder Structure
Colocation is key. Instead of putting all components in one folder and all styles in another, I structure by feature. Here is a simplified version of my typical /src directory:
src/
├── app/
│ ├── (marketing)/
│ │ ├── page.tsx
│ │ └── layout.tsx
│ ├── (dashboard)/
│ │ └── layout.tsx
├── components/
│ ├── ui/ # Generic reusable components (Buttons, Inputs)
│ └── features/ # Feature-specific components
└── lib/
├── utils.ts
└── api.ts
Server Components by Default
By default, I leave every component as a Server Component. The moment you add 'use client' to the top of a file, you are sending that JavaScript to the user's browser.
"Push your client components to the leaves of your component tree. Don't make the entire layout a client component just because a button deep inside it needs state."
Managing State
For most portfolios and agency sites, Redux is overkill. I rely heavily on React Context for global UI state (like dark mode or the mobile menu you see on this very site) and Zustand if the application requires complex data manipulation.
Conclusion
Web development is constantly evolving, but prioritizing clean architecture ensures your code doesn't become a nightmare to maintain six months down the line. Whether I am building a simple landing page or a full society management system, these principles remain the same.