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

Add configuration to specify the name of the pages directory. #936

Closed

Conversation

gcpantazis
Copy link
Contributor

@gcpantazis gcpantazis commented Jan 30, 2017

Being able to customize the name of the pages directory was brought up in #914, and this PR makes that possible by adding configuration in next.config.js.

It does bring up the possible need of a refactor for how configuration is disseminated to the server code, as it's becoming very repetitive to have to call getConfig(dir) every place we need access to the settings (and this commit seems to be propagating that convention more than ever).

So, open for consideration! Happy to continue to work on this, but as @nkzawa mentioned it needs discussion.

cc/ @arunoda @rauchg @timneutkens from the relevant conversation in #914 🤝

lib/prefetch.js Outdated
@@ -110,7 +110,7 @@ if (hasServiceWorkerSupport()) {

function getPrefetchUrl (href) {
let { pathname } = urlParse(href)
const url = `/_next/${__NEXT_DATA__.buildId}/pages${pathname}`
const url = `/_next/${__NEXT_DATA__.buildId}/${__NEXT_DATA__.pagesDirectory}${pathname}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I quite don't like this change.
We should not need to any changes to the client code.

For that, keep the pages in the .next as pages. There's no need for changing that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, with that we only need to change few places.
So, that's better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think keeping ./.next/pages regardless would work with SSR if you had a deeper-nested custom pages folder (ala views/pages, see discussion here)

@nkzawa
Copy link
Contributor

nkzawa commented Jan 31, 2017

I wonder when you actually need this 🤔

@gcpantazis
Copy link
Contributor Author

gcpantazis commented Jan 31, 2017

@nkzawa I think a shallow reason would be to simply customize the name to screens or some such as was mentioned in the discussion in #914. A much more important (to my eye) reason would be to put pages into a nested folder for views, etc., ala:

- next.config.js
- package.json
- server.js
- /views
    - /pages
        - index.js
        - foo.js
        - bar.js
    - /components
    - /containers

This patch would allow you to set pagesDirectory: 'views/pages' in next.config.js for the above structure. Having this flexibility drops an "opinion" from the architecture, and (in my case) lets me customize the structure to fit my project needs.

@arunoda
Copy link
Contributor

arunoda commented Jan 31, 2017

I am starting feeling we should not do this.
Having a single way to something is pretty good is some cases. We need to keep the balance.
Create React App (CRA) is a pretty extreme case.

In the case of Next.js, we allow to customize Next.js with webpack and babel.
We also allow to pass a custom directory for the next command.

Having the pages directory is kind of an identity of Next.js.
Changing the pages directory name doesn't give us much(or fix a burning issue) but it complicates Next.js source.

That's why I don't like to take this.

@gcpantazis
Copy link
Contributor Author

I'd argue that this isn't really complicating the source — it's removing dozens of hard-coded strings for pages, and centralizing that value in one place. As a bonus it allows for the end-users to have more control over directory structure. From a new-user standpoint this is totally optional — pages is still the default, so nothing really changes.

@rauchg
Copy link
Member

rauchg commented Jan 31, 2017 via email

@gcpantazis
Copy link
Contributor Author

I mean, I'd argue that "aesthetics" (I'd call it clear folder structure, but potato-patatoh) is important for individual implementations. ./pages is certainly fine for a very simple application (or even a complex one with a single focus), but as that application grows or has other needs, maybe filling the root directory with folders isn't the right choice.

For example, it's officially sanctioned that Next allows custom servers, where you fine-tune the routing. Let's say I'm using express to derive the incoming routes, and direct some of them to an API and others to Next. Let's also say I want to have a separate Next application for standard web and AMP pages (This would be an expansion of the example I'm working on in #913 ). I'd ideally want a folder structure along the lines of:

- next.config.js
- package.json
- server.js
- /standard
    - /pages
        - index.js
        - foo.js
        - bar.js
    - /components
    - /containers
- /amp
    - /pages
        - index.js
        - foo.js
        - bar.js
    - /components
    - /containers
- /api
    <API structure>
- /static  
    <static assets>
- /configuration
    <shared configuration, potentially>
(etc)

Making the pages directory configurable would allow me to do that, or tackle any number of other application structures.

@rauchg
Copy link
Member

rauchg commented Jan 31, 2017

Couple questions about your example:

  • why would you want to colocate your API with your frontend?
  • how would next know about both amp/pages and standard/pages?

@gcpantazis
Copy link
Contributor Author

why would you want to colocate your API with your frontend?

The convenience of having a single server, I suppose. It would depend on the project. For a more prototype-ish server for a hack week I could definitely see benefit to colocating to simplify the setup.

how would next know about both amp/pages and standard/pages?

In my head I was thinking that the programatic usage of next() in custom servers could lend itself towards creating multiple next apps that could operate side-by-side. Seems like that's not currently possible (happy to work towards making it possible), but I do see some benefit in colocating AMP and non-AMP pages since they may share some common components.

@amonks
Copy link

amonks commented Feb 1, 2017

Here's another example.

I'm working on a boilerplate for multi-service apps. If you had a service called 'front' and a service called 'back' it would look somewhat like this:

.
├── README.md
├── back
│   ├── README.md
│   ├── Dockerfile
│   ├── package.json
│   ├── backpack.config.js
│   ├── .babelrc
│   ├── src
│   │   ├── index.js
│   │   ├── modules
│   │   │   ├── root
│   │   │   ├── users
│   │   │   ├── posts
│   │   │   └── ...
│   │   └── ...
│   └── yarn.lock
│
├── front
│   ├── README.md
│   ├── Dockerfile
│   ├── package.json
│   ├── next.config.js
│   ├── .babelrc
│   ├── pages
│   │   └── ...
│   ├── modules
│   │   ├── root
│   │   ├── users
│   │   ├── posts
│   │   └── ...
│   ├── server.js
│   ├── ...
│   └── yarn.lock
│
├── package.json
├── tools
│   └── ...
└── yarn.lock

My goal is to have a consistent development experience across the back- and front-end services (plus any others), and some tools for managing them together (deploying or staging them all at once, for example, or performing integration tests across services).

For this project, internal consistency between the different services is more important than external consistency with next.js conventions, so I'd like to be able to keep front-end code (including pages) inside a src folder.

@sedubois
Copy link
Contributor

sedubois commented Feb 1, 2017

There might be two different questions here. On the one hand it's good to separate into micro services in the cloud (e.g separate front end from API), but on the other I understand wishing to keep all the code base in a monorepo. How can these needs be combined?

@gcpantazis
Copy link
Contributor Author

Somewhat related, as I'm applying this to my project I'm also seeing a need to customize the output directory (i.e. the ./_next routes). I'd ideally like to be able to run several next services behind a reverse proxy, which would direct the correct traffic to the individual servers. So if I'm making a CoolServiceApp that contains the routes /foo and /bar:

www.website.com/foo/
www.website.com/bar/
www.website.com/front-end-assets/cool-service-app/_next/<...>

That way I could separately launch a AwesomeServiceApp that has route /baz:

www.website.com/baz/
www.website.com/front-end-assets/awesome-service-app/_next/<...>

I could possibly do this by manually changing /_next/ strings to my preferred directory (possibly with middleware), and aliasing the directories with a custom server... but configuring the output seems ideal. There's also /_next-prefetcher.js to consider, since that's served out of site root. 🤔

@niksurff
Copy link

niksurff commented Feb 7, 2017

As far as I see it next.js' biggest selling point is it's philosophy of:

Add your React components to a pages folder, run next and enjoy the rest of your day.

Maybe next.js shouldn't necessarily try to serve everybody but rather keep it's scope in check and try to improve on current values?

Features add up easily.

¯\_(ツ)_/¯

@rauchg
Copy link
Member

rauchg commented Feb 20, 2017

I've come around on this. I think we should allow to make it configurable.

@timneutkens
Copy link
Member

@gcpantazis could you rebase the PR?

@timneutkens timneutkens added this to the 2.1 milestone Feb 25, 2017
@gcpantazis
Copy link
Contributor Author

Rebased, but looks like I'll need to patch to pass tests; I'll fix, verify with our downstream project, and add some more tests (likely Monday).

@timneutkens
Copy link
Member

@gcpantazis I wonder if these are related to your changes 🤔

@gcpantazis gcpantazis force-pushed the configure-page-directory-name branch from 4ac96a8 to 8ac4013 Compare March 10, 2017 19:50
@gcpantazis
Copy link
Contributor Author

Updated to pass tests as of this comment (missed a few introduced references to 'pages'), but still needs test coverage.

@gcpantazis
Copy link
Contributor Author

Basic test added. Let me know if this needs anything else, @timneutkens!

Copy link
Member

@timneutkens timneutkens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great 👍 marked for after 2.0

@juanpablocs
Copy link

What is the status of this?

@tashburn
Copy link
Contributor

tashburn commented Jun 7, 2017

I'd really like this too. If we're customizing the /pages folder, I think we should also allow a custom '/static' folder.

@gcpantazis
Copy link
Contributor Author

@tashburn that's #2186, which should be ready to go. This one is harder than it used to be, pages is ingrained in a bunch of places that aren't readily accessible to the config file. Working on it 🔧

gcpantazis added a commit to gcpantazis/next.js that referenced this pull request Jun 7, 2017
(Related to vercel#936; this is the more important bit for us at Thumbtack,
but doing this enables me to restart work on vercel#936 so I wanted to get
it in for review.)

Currently the output static assets are stored in `/_next`, but this
may not be ideal. At Thumbtack, we need to let the reverse proxies route
traffic to several servers, including several Next servers eventually,
so it's important that we're able to be very specific about where
the static files are stored. This enables us to say:

`assetDirectory: '/assets/fe/service-foo'

in one app, and...

`assetDirectory: '/assets/fe/service-bar'

in another, and afterwards point traffic for those folders from the
reverse proxies to the appropriate server. I'm sure others may have
other use-cases for specifying the output directory, but this is our
immediate need.

As mentioned above, this is related to the configuration update in
PR vercel#936, and merging this in enables us to move forward with restarting
that task.
@tashburn
Copy link
Contributor

tashburn commented Jun 7, 2017

@gcpantazis when you say "ready to go", do you mean this feature "is available now as part of the latest code", or do you mean "scheduled for the next release"?

Also, to clarity, I'd like to customize the input source folder (e.g. use <root>/client/static instead of '/static`). I'm not talking about customizing the output static assets folder within the build folder, per #2186 (though I can see that being useful too).

@gcpantazis
Copy link
Contributor Author

@tashburn Oh, of course, my misunderstanding. Yeah by "ready to go" I just mean that it's ready for review by the maintainers. :)

For what it's worth customizing /static should be trivial. If there isn't an issue for that already you could create one and tag me in it, it's not something we need at my company but I can certainly create a pull request for it after I re-do this PR (if someone else doesn't get to it first)

gcpantazis added a commit to gcpantazis/next.js that referenced this pull request Jun 8, 2017
(Related to vercel#936; this is the more important bit for us at Thumbtack,
but doing this enables me to restart work on vercel#936 so I wanted to get
it in for review.)

Currently the output static assets are stored in `/_next`, but this
may not be ideal. At Thumbtack, we need to let the reverse proxies route
traffic to several servers, including several Next servers eventually,
so it's important that we're able to be very specific about where
the static files are stored. This enables us to say:

`assetDirectory: '/assets/fe/service-foo'

in one app, and...

`assetDirectory: '/assets/fe/service-bar'

in another, and afterwards point traffic for those folders from the
reverse proxies to the appropriate server. I'm sure others may have
other use-cases for specifying the output directory, but this is our
immediate need.

As mentioned above, this is related to the configuration update in
PR vercel#936, and merging this in enables us to move forward with restarting
that task.
gcpantazis added a commit to gcpantazis/next.js that referenced this pull request Jun 11, 2017
(Related to vercel#936; this is the more important bit for us at Thumbtack,
but doing this enables me to restart work on vercel#936 so I wanted to get
it in for review.)

Currently the output static assets are stored in `/_next`, but this
may not be ideal. At Thumbtack, we need to let the reverse proxies route
traffic to several servers, including several Next servers eventually,
so it's important that we're able to be very specific about where
the static files are stored. This enables us to say:

`assetDirectory: '/assets/fe/service-foo'

in one app, and...

`assetDirectory: '/assets/fe/service-bar'

in another, and afterwards point traffic for those folders from the
reverse proxies to the appropriate server. I'm sure others may have
other use-cases for specifying the output directory, but this is our
immediate need.

As mentioned above, this is related to the configuration update in
PR vercel#936, and merging this in enables us to move forward with restarting
that task.
@sbking
Copy link

sbking commented Jun 25, 2017

This seems especially important now that we have dynamic imports. I now only have a single controller.js file in the pages directory, while my actual page components live elsewhere to avoid confusion from the somewhat magical behavior of pages/. That way if I accidentally use Router.push('/somePage') instead of Router.push('/controller', '/pageName'), then I get an error rather than an unstyled version of the page.

This means that the name of the directory is not meaningful for apps that take advantage of dynamic imports, which seems to be an important part of the direction that Next.js is moving.

@timneutkens timneutkens removed this from the 2.1 milestone Jul 1, 2017
@AhmedAzzabi
Copy link

Is this in yet ?

@gcpantazis
Copy link
Contributor Author

@timneutkens Maybe we should just close this one out and make an issue to track the feature request. As mentioned above this code is too far removed from the active dev branches to be salvaged.

#2186 adds some configuration for the _next folder, and I'm happy to continue with pages after that one is merged in.

@tconroy
Copy link

tconroy commented Aug 7, 2017

Hey @gcpantazis. Thank you for all your work on this! Curious if this is still slated for a release -- seems it got caught up in the CI and now there's a couple of conflicts.

@timneutkens
Copy link
Member

Lets close this, feel free to create an issue for the feature request.

@julkue
Copy link

julkue commented Feb 2, 2018

@gcpantazis @timneutkens Has there been any further investigation or follow-up ticket?

@ghost
Copy link

ghost commented Apr 16, 2018

Any updates on this?

@gcpantazis
Copy link
Contributor Author

gcpantazis commented Apr 16, 2018

I no longer (personally) view this as critical or necessary. Much of what the team has done in the past year has made much of what I was proposing here obsolete (i.e. #2186 is largely irrelevant given newer features like https://github.com/zeit/next.js#dynamic-assetprefix)), and most of my rationale above for specifying a custom pages directory boils down to preference (and in practice it hasn't been a problem for us).

If anyone disagrees, they're welcome to open a ticket for the feature request! But please do so instead of pinging on this thread. 🙇 👍 👋

@dmitryrn
Copy link

dmitryrn commented May 6, 2018

So... What can we do?

@hiradary
Copy link

I suppose you shoud add this. it's such a limitation for some who have their own special folder structure.. for example I like to keep my source code away from package.json, babelrc, ... .

    |--node_modules
    |--package.json
    |--README
    |--src
        |--pages
        |--components
        |--styles
        ...

@lavir
Copy link

lavir commented Mar 25, 2019

I suppose you shoud add this. it's such a limitation for some who have their own special folder structure.. for example I like to keep my source code away from package.json, babelrc, ... .

    |--node_modules
    |--package.json
    |--README
    |--src
        |--pages
        |--components
        |--styles
        ...

In your case this should work:

"dev": "next ./src",
"build": "next build ./src",
"start": "next start ./src"

@cyrus-za
Copy link

@lavir that does not work for that case. It means nextjs will add .next directory inside src along with other things such as tsconfig (for us ts users) among other things. Those files belong in the root, not in src. We do not want to change the next root, just the pages directory.

@timneutkens
Copy link
Member

Just leaving this here for reference: https://nextjs.org/blog/next-9-1#src-directory-support

@cyrus-za
Copy link

Thanks @timneutkens I would have missed this and probably only found out way later!

@parlay96
Copy link

@timneutkens #30172
There are many pages below pages. I want to realize classification
such as:
── pages
├── aModule
── a1.tsx
.....
├──bModule
── b1.tsx.
── b1.tsx
Then access the path: www.abc.com/aModule/a1 I want to achieve: www.abc.com/a1?

If I have many pages below pages. If there is no configured routing table, it cannot be classified, which is difficult to maintain

@robert8888
Copy link

robert8888 commented Jan 25, 2022

I treat 'pages' dir as router. Since this is kind of handicapped router :P. So in page components under pages dir i keep simple PageWrapper copmonents witch provide layout and contain target page component from /components/@pages.

Then pages components don't have any logic. Just point to correct component in components/@pages dir. In getStatuc/ServerSideProps i just run prepared data fetch modules witch provides data expected by target page component.

sadly i can't rename pages to 'router' or 'routes'

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 25, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.