React

How to structure a Next.js App Router project in 2026

Where to put pages, components, blocks and utilities in an App Router project. A structure that holds when the project grows, without ceremonial folders.

Key points

  • The App Router organises URLs and server/client boundaries, not the design system.
  • Keep `components/ui` for primitives and `components/blocks` for composed sections.
  • Every extra folder must remove a risk: if it does not, it is ceremony.

A project structure is not judged by folder depth. It is judged by one question: where do I look to tell whether a file can run on the server or the client? The App Router answers with boundaries, not with fashions.

A structure that holds

app/
  (marketing)/
    page.tsx
    pricing/page.tsx
  (app)/
    dashboard/
      layout.tsx
      page.tsx
  layout.tsx
components/
  ui/        # primitive: button, input, dialog
  blocks/    # sezioni: hero, pricing, navbar
  app/       # composizioni legate al prodotto
lib/
  utils.ts
  tokens.css
hooks/
public/

`(marketing)` and `(app)` are route groups: they add no URL segment, but they separate layouts and boundaries. They earn their place when the two halves have different navigation and caching needs.

What each folder is for

FolderContentsRule
app/Routes, layouts, loading, errorOnly URLs and boundaries
components/ui/Primitives with no product logicNo data fetching
components/blocks/Composed sectionsExplicit props, no global fetch
components/app/UI tied to a featureMay know the domain
lib/Utilities and configurationPure functions where possible

Server and client: the boundary that matters

A component is a server component by default. Put `"use client"` as low as possible, on the component that actually holds state or events. Put it on the layout and the whole tree becomes client, and you lose the framework's advantage.

  • The layout can stay on the server: pass data to client components as props.
  • An interactive dialog is a client component; the page that hosts it can stay on the server.
  • Fetches belong in the server component or in a dedicated route, not inside `components/ui`.

Where catalogue components fit

Install primitives into `components/ui` and blocks into `components/blocks`. Do not mix the two: a primitive has a stable API, a block is a composition you adapt to the context.

The EneUI catalogue indexes 111,985 components from 1,472 libraries and 1,556 blocks (31 October 2026). Installing a block does not mean adopting a library: the code lands in your repository and follows your structure.

The mistakes that cost the most

  • One folder per file type (`containers`, `views`, `screens`) with no rule that separates them.
  • `"use client"` on the root layout.
  • Duplicate fetches between layout and page.
  • UI components that import product stores or contexts.

Frequently asked questions

`src/` or the root?

It makes no difference to Next.js. Pick one convention and do not duplicate it: two code trees are the real cost.

Where do I put shadcn components?

In `components/ui`. They are primitives, not sections, and keeping them apart from blocks avoids cross imports.

Are route groups mandatory?

No. They help when two areas of the site need different layouts or caching. If that is not your case, do not add them.

Can I fetch in a client component?

You can, but you lose server rendering and add loading states. Prefer the server component and pass the data down as props.

How do I organise tests?

Next to the component for unit tests, in a `tests/` folder for end-to-end flows. The position matters less than the distinction.