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

Troubleshooting Problems with Angular ng-include

I'm having trouble with including a file using ng-include. I've tried various variations, but it keeps returning a 404 error in the console. The directory structure is as follows: -App --Layout ---Partials ----Navigation.tpl.html(File) --Layout. ...

Tips for appending the id of an active element to a URL

My goal was to include the id value of the active element in a URL and then redirect to that URL with a button click. HTML <div class="icon" tabindex="0" id="company"> <img src="company.png"> </div> <button type="submit" onclick= ...

Confirm the value of $index and apply a specific style

Trying to figure out how to highlight a table row using AngularJS within a directive. Here is some pseudo code I came up with: if(highlight.indexOf($index) != -1) set .highlight css class Below is an example of my code snippet: $scope.highlight = [0, ...

Convert TypeScript-specific statements into standard JavaScript code

For my nextjs frontend, I want to integrate authentication using a keycloak server. I came across this helpful example on how to implement it. The only issue is that the example is in typescript and I need to adapt it for my javascript application. Being u ...

Sending the parameter with the URL and receiving the response in return

Can the result be retrieved by calling a URL and sending specific parameters with it? For instance, if I pass two numbers along with the URL, can I receive the sum in return? The addition operation is carried out on the page being called upon. ...

Are foreign characters the culprit behind the JSON parsing problem?

I am encountering an issue while attempting to parse a field containing JSON data returned from an API. The data includes various unusual characters like East Asian symbols and curly quotes, causing this error to appear. I am unsure of how to resolve it - ...

Encountering a persistent Unhandled rejection Error while utilizing NodeJs with Bluebird library

Currently in the process of developing a daemon that listens to TCP connections, sends commands, and listens for events. I made the decision to utilize bluebird to eliminate callbacks, but I'm encountering an issue. I can't seem to catch a rejec ...

Processing two Array Objects can be achieved without resorting to the EVAL function

I have two objects that I need to process. obj1 contains an array of objects with formulas. obj2 holds the values needed for the calculations. I am looking for a way to process and calculate both objects in order to obtain a result where the keys present ...

Want to learn about Google Apps Script Web App? Join us to dive into AJAX, leverage

I'm attempting to follow the steps outlined in "Example 3: Web Response" on "this SparkFun tutorial" After implementing the code on script.google.com, I encountered an issue where I couldn't see the pin readings. Can someone provide assistance w ...

Multer is experiencing difficulties in uploading files, yet it is not displaying any error messages

When setting up an application to create courses with images, I encountered an issue while using multer for image uploading. Despite adding multer to my route with upload.single('images'), the uploaded images were not appearing in the designated ...

Update the text input field from a different webpage

I am working with two PHP pages, let's call them page1.php and page2.php. On page1.php, there is a textbox with a default value of 0, while on page2.php, there is a button. I have these two pages open in different tabs in a browser. My goal is to have ...

Preventing an infinite re-render loop caused by event listeners in React

One functional component is causing me some trouble: export default function Nav({photo}) { const [isOpen, setIsOpen] = useState(false) const [width, setWidth] = useState(window.innerWidth); const breakpoint = 768; useEffect(() => { ...

Having trouble establishing a connection between MongoDB and a Node.js Express server on my local machine

While attempting to establish a connection between mongoDB and nodejs express using the post method, I added a logger that should display a message confirming that the database is connected once nodejs listens to mongoDB. However, I encountered an issue wh ...

Updating the query parameters/URL in Node.js's request module

In my Express.js application, I am utilizing the npm request module to interact with an internal API. The options passed to the request function are as follows: requestOptions = { url : http://whatever.com/locations/ method : "GET", json : {}, qs : { ...

Using a curly brace in a React variable declaration

After completing a react tutorial, I started customizing the code to suit my requirements. One specific section of the code involved a component that received a parameter called label. render() { const { label } = this.props; ... } For instance, I re ...

Leveraging colons in the process of object destructuring

I'm still trying to wrap my head around all the wonders of ES6. Ran across this snippet in an online article and I'm puzzled by how PrivateRoute is deconstructing the input props. What exactly is the purpose of component: Component here? const P ...

Could you please ensure that the animation activates upon hovering over the "a" element?

Utilizing bootstrap, I have created the following code. I am looking to add functionality that triggers an animation upon mouseover of an img or a element, and stops the animation upon mouseleave. .progress-bar { animation: pr 2s infinite; } @keyfr ...

What is the best way to import two components with the same name from different libraries?

How can I import the Tooltip component from two different libraries without encountering naming conflicts? For example: import { Tooltip as LeafletTooltip } from "react-leaflet"; import { Tooltip as RechartsTooltip } from "recharts"; By renaming the impo ...

JavaScript is throwing an error when clicking on functions and managing the z-index property

I am experiencing difficulties with my website code. I have defined all the necessary functions and CSS, but I keep encountering errors such as "clicked is not defined," even though it is clearly present in the script. The goal of the code is to bring the ...

Add a style to every div except for the final one

I've attempted to add a unique style to all divs with the same class within a parent div, except for the last one. Strangely, my code doesn't seem to work as expected for this particular case. Can anyone spot what I might be overlooking? Right no ...