A guide to organizing page components across multiple `/pages` directories in a Next.js application

As I delve into my first project using Next.js, I find that my pages directory has expanded significantly. Now, I am keen on organizing my pages by grouping them into modules, resulting in a structure like 'src/modules/*/pages/*'.

In my quest for solutions, I stumbled upon exportPathMap, a function that can be integrated into my next.config.js file to create custom paths for my pages. However, the thought of having to add a new path for each page seems quite tedious. What I desire is to provide Next with a singular expression such as 'src/modules/*/pages/*', allowing it to automatically resolve the pages and routes (similar to mapping entities in an ormconfig.json file when working with TypeORM).

One approach could involve grouping my page components directly within the pages directory, like pages/a-module/*. Yet, this does not address the segregation of components, hooks, and other logic into distinct modules. Another option might entail utilizing Node's fs module to navigate through my project's file structure and map the page folders. Nevertheless, I prefer to avoid this method if possible.

Answer №1

If you want to simplify your directory structure, consider using symbolic links (symlinks). Instead of creating a symlink for every nested path within each module, only create symlinks for the modules themselves. For example:

├── modules
│   ├── bar
│   │   └── pages
│   │       ├── first.js
│   │       └── second.js
│   └── foo
│       └── pages
│           ├── first.js
│           └── second.js
├── pages
│   ├── _app.js
│   ├── bar -> ../modules/bar/pages
│   ├── foo -> ../modules/foo/pages
│   ├── index.js

This setup would result in routes such as:

/bar/first
/bar/second
/foo/first
/foo/second

However, be cautious as this approach may introduce clutter into your modules folder similar to what you previously had in the pages directory. Remember that not all component content needs to reside directly in the pages files. You can keep it separate like so:

// pages/foo/first.js
import FirstContent from '../../modules/FirstContent'

export default function First() {
  return <FirstContent />
}

Answer №2

The Next.js team has intentionally prohibited this action for specific reasons addressed in this article and in the related discussions. Before attempting to manipulate the file structure in any way, it is recommended to review the conversations to fully understand the implications.

Answer №3

In agreement with @Roman Mkrtchian, it is advisable not to proceed in this manner. I recommend organizing your files into modules by structuring them similar to the following:

src
├── modules
│    ├── foo
│    |   └── pages
|    |       ├── one
|    |       |   ├── index.jsx
|    |       |   └── styles.js <- Use for `styled-components` or a css file
|    |       └── two
|    |           ├── index.jsx
|    |           └── styles.js
|    └── bar
|        └── pages
|            └── three
|                ├── index.jsx
|                └── styles.js 
├── shared
└── ...

An alternative approach can be considered. As pointed out by @erich2k8, not all component content needs to reside within files inside /pages. You could maintain a similar structure but place /pages directly under src:

src
├── modules
├── shared
└── pages
    ├── foo
    |   ├── one.jsx
    |   └── two.jsx
    └── bar
        └── three.jsx

For example, within src/pages/foo/one.jsx, you would import src/modules/foo/pages/one like so:

import OneContent from '../../modules/foo/pages/one';

const One = () => <OneContent />;

export default One;

While it may require creating new files for each page within /modules, this approach avoids potential difficulties with Next behavior.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

retrieving the value of a field within an array

Here is my code snippet: <div class="label">{{ item.data[0] }}</div> and in the view, this is what I have: { "id": 6, "firtname": "JHON ", "lastname": "SCALA", "fullname& ...

What could be causing my controller method in TypeScript to throw an error message unexpectedly?

Hey there. I'm diving into TypeScript and currently working on converting an Express backend to TS. Everything was smooth sailing until I encountered some unexpected issues. Specifically, the lines const hasVoted = poll.votedBy.some((voter): boolean = ...

Acquiring radio button input in PHP

I have 2 radio buttons within a form, <label><input type="radio" onclick="this.form.submit()" name="shfaq<?php echo $i; ?>" value="1" id="radiobuttonsondazh_0" <?php if($result['live']==1) echo 'checked'; ?> /> ...

Utilize JavaScript to submit the FORM and initiate the 'submit' Event

Hey there! Here's the code I've been working on: HTML : <html> <body> <form enctype="multipart/form-data" method="post" name="image"> <input onchange="test();" ...

The beauty of crafting intricate forms with Angular's reactive nested

In my Angular project, I am exploring the concept of nesting multiple reactive forms within different components. For instance, I have a component called NameDescComponent that includes a form with two inputs - one for name and one for description, along ...

The installation of AngularJS libraries via npm was unsuccessful

After installing mean.io and running sudo npm install, I followed the commands in sequence: sudo npm install -g meanio mean init yourNewApp cd yourNewApp sudo npm install -g bower sudo npm install The process was supposed to download and install AngularJ ...

Switch button displaying stored data in sessionStorage

I am facing an issue with my small toggle button in AngularJS. I have set up sessionStorage to store a value (true or false), and upon page load, I retrieve this value from sessionStorage to display the toggle button accordingly. Depending on the value sto ...

The Dropdownlist jQuery is having trouble retrieving the database value

Within my database, there is a column labeled Sequence that contains integer values. For the edit function in my application, I need to display this selected number within a jQuery dropdown list. When making an AJAX call, I provide the ProductId parameter ...

Verifying that a parameter is sent to a function triggering an event in VueJS

One of the components in my codebase is designed to render buttons based on an array of objects as a prop. When these buttons are clicked, an object with specific values is passed to the event handler. Here's an example of how the object looks: { boxe ...

Managing time-intensive web service operations using JavaScript callbacks

One of the operations in my Web application involves a function that returns a value, which then needs to be passed to a web service method running separately from the application. This web service operation takes some time to complete and therefore must r ...

How to switch the code from using $.ajax() to employing $.getJSON in your script

How can I convert this code from using AJAX to JSON for better efficiency? AJAX $('#movie-list').on('click', '.see-detail', function() { $.ajax({ url: 'http://omdbapi.com', dataType: 'json', d ...

Is it feasible to embed Instagram in an iframe without using the API?

Is there an alternative method to embed Instagram using iframe without the need for an API? ...

Troubleshooting: How to Fix Missing Sum Display in HTML Input Fields

I am new to the world of website programming and I am currently working on creating a basic sum equation using two input fields from the client-side. <!DOCTYPE html> <html> <head> </head> ...

Add the $scope ng-click event to a previously hidden element once it becomes visible

If you need a clearer explanation, feel free to ask. I have incorporated a global search function into the header of my website. I am looking to show a separate input box for mobile search that utilizes the same ng-click event, but the input field remains ...

What is the best way to conceal a header on a single page within a Next.js application?

Currently working on a Next.js application, I've developed a <Header /> component and integrated it into the _app.tsx file. However, I'm looking to have it displayed on all pages except for one. Is there a way to achieve this? ...

The attempt to retrieve the image from the specified URL at https://res.cloudinary.com/<------.jpg> was unsuccessful with a 404 error

Currently, I am in the process of developing a project using NextJS and Strapi. For my media library, I have decided to use Cloudinary. However, upon attempting to display an image from Cloudinary, I encountered an error where the image is not showing up a ...

There is a button on my website that uses a small piece of Javascript to post a tweet, but unfortunately, it is not functional on mobile devices

Check out this link to view the demonstration - http://codepen.io/illpill/pen/VbeVEq function sendTweet(message, author) { window.open('https://twitter.com/intent/tweet?hashtags=thequotemachine&text=' + encodeURIComponent('"' + m ...

The JavaScript-generated form element will not be included in the data submitted through the POST method

While it may appear that this question has been asked before, my specific inquiry seems to be unique as I have not found a similar answer in other threads. Therefore, I am initiating a new discussion. My issue revolves around a form which contains a link ...

Discovering the oldest date in an array with JavaScript

Is there a way to identify the earliest date, also known as the minimum date, within an array using JavaScript? For instance: ["10-Jan-2013", "12-Dec-2013", "1-Sep-2013", "15-Sep-2013"] The desired output would be: ...

The information is retrieved from the backend system, yet it fails to appear on the user interface

I am currently working on an ECommerce project that involves various operations like displaying, creating, and deleting products, as well as showing specific product information. However, my main issue lies in the display of data. In the App file, the da ...