Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to change where Next looks for pages? #4789

Closed
bing1021 opened this issue Jul 17, 2018 · 32 comments
Closed

How to change where Next looks for pages? #4789

bing1021 opened this issue Jul 17, 2018 · 32 comments

Comments

@bing1021
Copy link

Every .js file in pages becomes a route, can i change it?

I want use src/pages

@egorovli
Copy link

AFAIK, you cannot. You can disable file system routing via next.config.js.

@egorovli
Copy link

According to docs, dir specifies the location of the project, so the correct way would be to set it to ./src:

const next = require('next')({
  dev,
  dir: './src'
})

But it's only used in a programmatic API (with a custom server) and will affect the presumed location of other files as well (like next.config.js and static directory, I believe).

@brainkim
Copy link
Contributor

No idea what these other comments are saying but you can configure which directory next.js looks for pages from the command-line:

$ next ./src
$ next dev ./src
$ next build ./src
$ next start ./src -p 8080

@timneutkens
Copy link
Member

You can't change the directory, and we're not planning to change this, please search for an issue on the issue tracker (including closed issues) in the future before posting an issue, as this question has come up quite a few times.

@Carduelis
Copy link

@timneutkens don't be like maintainer of moment.js, who rejected optimization for client-side apps, what is led to custom configs in a lot of projects, even in CRA.
A lot of project boilerplates has an src folder, where files lay.

@cryptiklemur
Copy link
Contributor

As this is currently the first result on google when searching for this, maybe it would be beneficial to explain the reasoning behind that decision @timneutkens ?

@msegers
Copy link

msegers commented Jan 2, 2019

As stated by @brainkim jus append your package json scripts with ./src. What you also might want to do is configure the next dist folder (I wanted dist in root).

Note that we prepend the folder with ../.

// src/next.config.js
module.exports = {
  distDir: '../dist'
}
// package.json
  "scripts": {
    "dev": "next ./src",
    "build": "next build ./src",
    "start": "next start ./src",
    ..
  },

@ivan-kleshnin
Copy link
Contributor

ivan-kleshnin commented Jan 10, 2019

@msegers I'm trying to follow this setup and getting tons of errors like this:

Cannot find module 'next/document'
Cannot find module 'next/error'
...

on HTTP request (no errors at the import phase). Any idea how to fix that?

The requirement of having pages at root really drives me nuts – for anything realistically big, things start to pile up at the root uncontrollably: styles, components, client store, config files, etc. Wish there were a workaround.

Addition: tried to symlink pages to client/pages. Most of the stuff seems working, except Hot Reload. Sad :(

@folofse
Copy link

folofse commented Mar 4, 2019

@msegers Suggestion worked for me.

If you use next-i18next make sure you set the correct localePath in the NextI18 config:localePath: 'src/static/locales/',

Like this :

NextI18NextInstance = new NextI18Next({
  defaultLanguage: 'en',
  otherLanguages: ['en'],
  debug: true,
  localePath: 'src/static/locales/',
});

@malimccalla
Copy link

There seems to be quite an appetite for this - would love to be able to configure where my top level pages are looked for.

@slaterbbx
Copy link
Contributor

slaterbbx commented Mar 26, 2019

@malimccalla You can, check out here: https://github.com/slaterbbx/fullstackinator

Caveat

You can't change the name of the folder as far as I know, needs to stay "pages"

How

Look in the client folder, notice there are a few key things needed to make this happen. The example I show is for a custom server scenario + typescript, but its basically the same thing, the core things are.

  1. In the scripts in package.json, make sure to point to the folder ( next ./client ) instead of just ( next ) for "npm run dev" / do the same for build script
  2. In that folder ( ./client ) you will need a next.config.js file. Then simply have in it the following:
module.exports = {
    distDir: '../.next' // so that you can tell it to go up a folder for the dev and prod files.
}

If you have any questions, feel free to shoot me an email or here is fine too.

UPDATE: I just noticed that above @brainkim gives the exact same explanation.. Sorry, I will leave this though because the linked example shows a much more complex use case for anyone seeking such an example.

@malimccalla
Copy link

malimccalla commented Mar 26, 2019

Thanks for this @slaterbbx

My issue is that I am trying to co-locate conceptually related code. I have the following structure

├── components
|   ├──  GridItem.tsx
|   ├──  Avatar.tsx
|   └──  Button.tsx
├── pages
|   └── profile
|       └── components
|       |   ├── CoverPhoto.tsx
|       |   └── UserInterests.tsx
|       ├── data.ts
|       ├── styles.ts
|       └── index.tsx

The issue with this approach (as pointed out by @timneutkens) is that all the files within pages are treated as webpack entry points so in turn considered for the commonchunks config. As it currently stands Next only supports top level page components within pages. If I could configure where pages are looked for I could keep this (reasonable?) structure. I imagine something like this in the config

pages: ["./pages/*/index.tsx"]

It could also be used for projects that store pages in multiple locations

pages: ["./pages/*", "./admin-pages/*"]

or projects that want to store their top level components in a folder named something differently

pages: ["./views/*"]

or projects that just want to customise the path

pages: ["./src/custom/path/to/pages/*"]

I believe this is a fair feature to have and it does not feel like a radical pattern (yarn workspaces use the same pattern to locate workspaces, a pattern Next.js itself implements).

@slaterbbx
Copy link
Contributor

@malimccalla ah, yea, totally understand your grief, I also desire a fully flexible solution. Possibly something worth contributing an effort too, but I have read that they are not interested in offering a solution ( somewhere, but don't quote me on that ) so I fear that investing such time into such a feature could be a lost cause. Unless of course they confirm that they would be interested in such a contribution, then again, might be a project to consider undertaking 🙋‍♂️

@joncursi
Copy link

@malimccalla were you able to get next to play nicely with your desired project structure, or did you end up flattening out your pages directory and storing the page sub-components elsewhere?

@malimccalla
Copy link

malimccalla commented May 20, 2019

@joncursi I managed to work around by renaming pages directory to views and then creating a new pages directory thats sole purpose is exporting the top level page components.

for example pages/profile.tsx now looks like this:

export { default } from "../views/profile"  

it's by no means ideal but allows me to keep my desired project structure

@AmazingTurtle
Copy link

AmazingTurtle commented May 31, 2019

@folofse changing the i18n localePath works when it comes to scanning the directory. But when resolving language files it is removing src again. What to do?

I enabled debug to provide the logs as follows (i18next)

...
  localePath: 'src/static/locales',
  localeStructure: '{{lng}}/{{ns}}',
  localeSubpaths: 'foreign',
  backend:
   { loadPath:
      'V:/dev/some-project/static/locales/{{lng}}/{{ns}}.json',
     addPath:
      'V:/dev/some-project/static/locales/{{lng}}/{{ns}}.missing.json' },
  allLanguages: [ 'de', 'de' ],

loadPath is set to *\static\locales but it should be *\src\static\locales.

@armenr
Copy link

armenr commented Jul 10, 2019

Question:

We have a custom server file in /projectRoot/next-web/server.js

It mounts /projectRoop/next-renderer-universal/client like so:

// in /projectRoot/next-web/server.js
const nextApp = next({
  dev: NODE_ENV !== 'production',
  dir: APP_DIR,
  quiet: false,
});

How the heck do we actually build and ship this :)?

@kachkaev
Copy link
Contributor

kachkaev commented Jul 10, 2019

@armenr This small app of mine might help. It uses a custom entry point (src/server.ts) and here is how it calls next():
https://gitlab.com/kachkaev/website-frontend/blob/e1c7106cf63811f6341c4bd47dd2354eb2546914/src/server.ts#L11-18

Keeping all source files under PROJECT_ROOT/src (or another subdirectory) is quite challenging in Next.js. Because of the added automatic TS integration in Next 9, things even become a bit more messy 😔 I wish #4315 was reopened.

@armenr
Copy link

armenr commented Jul 27, 2019

:) I set up a monorepo, so the question I was asking was compounded by other complexities

We've since figured out exactly what to do, but I appreciate the sample code. Still useful! Thank you :)

@anoop-gupt
Copy link

@armenr What is your workaround with regards to monorepo? I set up my project with lerna and still constrained with it.

@armenr
Copy link

armenr commented Aug 2, 2019

@anoop-gupt

Lerna, monorepo, yarn workspaces, and separate packages.

I put all the front-end code into a folder I call renderer-universal. I then have a package called next-web where I keep my custom next server. I also have another package where I keep nextron (next + electron...excellent project, look them up on GitHub).

In the server.js file for nextron and next-web, I use:

const nextApp = next({
  dev: NODE_ENV !== 'production',
  dir: APP_DIR,
  quiet: false,
});

And I pass in the directory location of the renderer-universal package via ENV variables to those server files.

I also have a bunch of microservices we wrote residing in other lerna packages in the monorepo as well.

No custom webpack/babel configs or symlink resolution required.

@revskill10
Copy link
Contributor

Normally, i prefer this project structure:

src
  - api
  - pages
  - utils

Top level src folder is normal and many projects use it. Why not ?

@anoop-gupt
Copy link

@revskill10 Yesh, even I preferred that structure.

@armenr
Copy link

armenr commented Aug 2, 2019

We're distributing our app & services + NextJS into both desktop/cloud hybrids as well as web builds.

Package management - node_modules duplication, the need for custom serverJS files w/ Next, and shared modules and libs between the different microservices made it hard to break everything apart or follow the conventional/simpler directory structure.

To provide an easily manageable setup for my team, I had to come up with a pattern that let us work on desktop and web versions simultaneously, and to decouple all microservices and deduplicate all shared libs & modules between them. The only real "right" way to do that was via the setup I've described.

For the average project getting started, this is overkill. In our case, we had a reasonably clear understanding of our initial requirements and what we needed to build, so I was just answering the question.

For what it's worth, we're thinking of getting rid of the custom server.js file and instead moving to the /api layout that's been implemented into Next9. Unclear, as of yet, whether this will still make it easily possible for us to develop on/build web + nextron simultaneously in a simple way.

@anoop-gupt
Copy link

@armenr Can I have your repository location, please? It seems a good solution.

@scf4

This comment has been minimized.

@scf4

This comment has been minimized.

@armenr

This comment has been minimized.

@janhesters
Copy link

This has been requested since 2017. How can we help to get this feature shipped?

@scf4

This comment has been minimized.

@scf4

This comment has been minimized.

@timneutkens
Copy link
Member

timneutkens commented Aug 18, 2019

Replied here, going to lock this issue.
#4315 (comment)

@vercel vercel locked as off-topic and limited conversation to collaborators Aug 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests