OWolf

2024-10-19 Web Development

Organizing Your Next.js 14+ Project: File Colocation and Best Practices with the App Router

By O. Wolfson

With the release of Next.js 14 and the continued refinement of the App Router, the framework provides more robust conventions for project organization, specifically focusing on file colocation. File colocation is a key pattern that Next.js developers can leverage to streamline their code structure, making it easier to maintain and scale applications.

This article explores best practices for organizing your Next.js 14+ project, particularly focusing on file colocation with the App Router.


What is File Colocation?

File colocation refers to the practice of keeping related files close together within the directory structure. In a Next.js project, this means grouping together components, styles, tests, and sometimes even data-fetching logic within the same directory as the page or component that uses them. The goal is to create a more modular, understandable structure, reducing the need to jump between distant files.

Next.js 14+ and the App Router enhance file colocation by allowing you to place files directly alongside their related routes, simplifying the organization and allowing for easy discovery of relevant code.


Project Structure in Next.js 14+ with the App Router

The App Router in Next.js 14 introduces a new way to structure your application, where the app/ directory becomes the central point for all routing. Here's a general example of a project structure:

bash
my-nextjs-app/
│
├── app/
│   ├── actions/
│   ├── (auth)/
│   │   ├── login/
│   │   │   ├── page.tsx
│   │   │   └── login.module.css
│   ├── dashboard/
│   │   ├── page.tsx
│   │   ├── component.tsx
│   │   ├── component.test.tsx
│   │   └── dashboard.module.css
│   └── layout.tsx
│
├── components/
│   └── Header.tsx
│
├── public/
│   └── images/
├── utils/
└── styles/

This structure illustrates how colocation works with the App Router:

  • Pages and Routes: The app/ directory handles routing based on its folder structure. For example, the app/(auth)/login/page.tsx file automatically becomes the route for /login.

  • Colocation of Components, Styles, and Tests: Notice that components like component.tsx, styles like dashboard.module.css, and tests like component.test.tsx are colocated within the dashboard/ route. This keeps all the relevant code close to the page where it's used.

  • Layout Files: The layout.tsx file in the app/ directory defines shared layouts for your app, colocating layout code close to the routes it affects.


Benefits of File Colocation in Next.js 14+

  1. Enhanced Discoverability: When you colocate files, it becomes easier to locate the code that belongs to a specific page or feature. If you're working on the /dashboard page, all the related files (components, styles, tests, etc.) are stored in the same directory.

  2. Modular Organization: By grouping related files together, you create self-contained modules. This can improve reusability, as each module is self-sufficient, with all dependencies local to that directory.

  3. Simplified Maintenance: Colocated files reduce the cognitive overhead of managing large applications. When you need to make changes to a feature or fix bugs, you don't have to navigate between distant directories.

  4. Logical Grouping: With Next.js 14+, your application’s structure reflects the actual routing and user experience. The routes in the app/ directory closely mirror the application’s URL structure, making it easier for new developers to understand the flow of the app.


Key Features of File Colocation in the App Router

1. Page and Layout Files

In Next.js 14+, the App Router treats any page.tsx file as a route handler, and you can colocate other files like components and styles next to it. Additionally, layout files, such as layout.tsx, can be used to define reusable layouts for nested routes.

For example:

bash
app/
├── dashboard/
│   ├── page.tsx       # This is the /dashboard page
│   ├── layout.tsx     # Optional layout for the dashboard section
│   ├── component.tsx  # A specific component used only in the dashboard
│   └── dashboard.module.css # CSS specific to the dashboard page

This colocates everything related to the dashboard/ page in one folder, minimizing separation between related logic.

2. Server Actions

In Next.js 14+, Server Actions can be colocated as well. These actions, which handle server-side functionality (such as form submissions or database interactions), can be placed directly in a actions/ directory under app/.

Example:

bash
app/
├── dashboard/
│   ├── actions/
│   │   └── submitAction.ts  # Handles form submission for dashboard
│   ├── page.tsx

By colocating actions with the route that uses them, you ensure server-side logic is tightly coupled with the front-end UI code.

3. Dynamic Routes

File colocation is also compatible with dynamic routes. If your app uses dynamic segments in its URLs (e.g., /users/[id]), you can colocate logic for specific dynamic pages:

bash
app/
├── users/
│   ├── [id]/
│   │   ├── page.tsx   # Handles /users/:id
│   │   └── user.module.css  # Styles specific to the user page

This structure keeps the logic for dynamic routes in a logical, organized structure.


When to Use Colocation (and When Not To)

While colocation is an excellent practice for most use cases, there are times when it may not be the best fit. Here’s a quick guide:

  • Use Colocation:

    • When the files are directly related to a single page or feature.
    • For small to medium-sized components or helper functions that are not reused globally.
    • For specific styles, tests, or server actions that are only relevant to a single route.
  • Avoid Colocation:

    • For global components or utilities that are reused across multiple pages (e.g., header, footer, shared services). These should be placed in dedicated directories like components/ or utils/ to avoid duplication.
    • For global styles that apply across the entire application, which should be stored in a central styles/ directory.
    • For large, shared logic that needs to be accessible throughout the app, which should be organized in modules outside the app/ directory.

Conclusion

In Next.js 14+, file colocation is not only encouraged but is also a natural fit with the App Router. By grouping files together based on their functionality and proximity to routes, you can maintain a clean, modular structure that scales well as your application grows. Colocation makes code easier to discover, enhances modularity, and simplifies maintenance, helping to make your Next.js project more organized and efficient.