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

next export default pages #1972

Closed
jstcki opened this issue May 15, 2017 · 20 comments
Closed

next export default pages #1972

jstcki opened this issue May 15, 2017 · 20 comments
Assignees

Comments

@jstcki
Copy link
Contributor

jstcki commented May 15, 2017

Hi! Thanks again for next export!

One question: why is exportPathMap in a custom config required? Wouldn't it be a good default to export all the pages? Or at least to provide a defaultExportPathMap function which could be merged with custom routes?

E.g.

const defaultExportPathMap = require('next/pathmap');
exports.exportPathMap = () => Object.assign(
  {},
  defaultExportPathMap(),
  { '/foo/bar': { page: '/foo', query: { id: 'bar' } } }
);
@arunoda
Copy link
Contributor

arunoda commented May 16, 2017

@herrstucki we will eventually do it with some feedback from the community.
We didn't do it to make it simple at start.
Sometimes, you may don't wanna build all the pages specially if they are used for custom routing.
In that case, building those page may throw an error.

@arunoda
Copy link
Contributor

arunoda commented May 16, 2017

But we are keep looking at the different options. Help us to figure out the best way to do this.

@jstcki
Copy link
Contributor Author

jstcki commented May 16, 2017

A few thoughts:

  1. As out-of-the-box behavior, try to render all pages. In a basic setup without custom routing this should work fine.
  2. If you want custom routing, you'll need a custom server anyway, so the mental overhead of adding the exportPathMap too should be okay in this case. For convenience, next.js could provide the default path map.
  3. There is currently a problem with custom export paths anyway: when I configure exportPathMap (without creating a custom server) with something like { '/foo/bar': { page: '/foo', query: { id: 'bar' } } }, /foo/bar will work when exported and when navigated to in the client but it won't work in dev mode when accessed directly (i.e. http://localhost:3000/foobar will return 404).
  4. So I wonder: if next.js core provided a simple way to define custom routes via next.config.js, this could not only be used for export but also for the (dev and prod) server. An example of how this could look like:
// This map will be used by default dev and prod server also
exports.pathMap = {
  '/foo/:id': ({id}) => ({ page: '/foo', query: {id} })
}

// Exported paths are separated from the mapping
exports.exportPaths = [
  ...defaultExportPaths(),
  '/foo/bar',
  '/foo/baz'
]

@arunoda
Copy link
Contributor

arunoda commented May 16, 2017

There is currently a problem with custom export paths anyway: when I configure exportPathMap (without creating a custom server) with something like { '/foo/bar': { page: '/foo', query: { id: 'bar' } } }, /foo/bar will work when exported and when navigated to in the client but it won't work in dev mode when accessed directly (i.e. http://localhost:3000/foo/bar will return 404).

This is the intended behaviour. Now you've created a custom URL for your app.

@jstcki
Copy link
Contributor Author

jstcki commented May 16, 2017

@arunoda sure, but I'm just lamenting that I'd have to re-create the logic of param-to-query mapping in two places in different ways (server and config). IMO an unnecessary source for confusion and errors.

@arunoda
Copy link
Contributor

arunoda commented May 16, 2017

@herrstucki you don't need to create it twice. Just create .json file and import and use it both in the server and the config.

@jstcki
Copy link
Contributor Author

jstcki commented May 16, 2017

@arunoda yeah, it can be done this way. Still, there's some slight differences (custom server API vs. config API). Not a big deal. I guess you've had more in-depth discussions about core support for custom routes already 😅

But back to the original point: do you see it as a problem to export all pages by default (when no custom routes are used)?

@arunoda
Copy link
Contributor

arunoda commented May 16, 2017

But back to the original point: do you see it as a problem to export all pages by default (when no custom routes are used)?

That's a good point. But there's no way to detect it.

@jstcki
Copy link
Contributor Author

jstcki commented May 16, 2017

That's a good point. But there's no way to detect it.

Yes, but the user knows when they've set up custom routes (see point 2 in #1972 (comment)), so they're already in the customization mindset 🙂

For the case where the user has customized routing but forgot to add exportPathMap, next export could show a helpful error message if something goes wrong, e.g.

Error: Building page /foo failed.
If you're using custom routes, you need to specify the ones
which should be exported in next.config.js (see [link to docs]).

@chibicode
Copy link
Member

chibicode commented Jun 11, 2017

Came here b/c I'm currently experiencing some pain due to having no custom routes but many files under /pages.

I also like the "export all pages by default, show error and ask to add exportPathMap when it breaks" option. It's the simplest way when there's no custom routes, and when there's custom routes, one must write exportPathMap anyway. On the other hand, the defaultExportPathMap mentioned earlier might not be necessary, so I'd hold off on that.

@chibicode
Copy link
Member

chibicode commented Jun 11, 2017

In a meantime, here's my workaround which uses glob to programmatically generate exportPathMap:

// yarn add glob
const glob = require('glob')

exports.exportPathMap = () => {
  const pathMap = {}
  glob.sync('pages/**/*.js', { ignore: 'pages/_document.js' }).forEach(s => {
    const path = s.split(/(pages|\.)/)[2].replace(/^\/index$/, '/')
    pathMap[path] = { page: path }
  })
  return pathMap
}

@sheerun
Copy link
Contributor

sheerun commented Nov 27, 2017

Is there a way to make next use pre-compiled pages for production for dynamic urls?

For example something like

const exportPathMap = {
  '/search/*': { page: '/search' }
}

With this configuration next would serve in production any URL starting with /search with pre-generated search.html page.

EDIT: I've implemented similar idea here: #3451

@millette
Copy link
Contributor

Implemented in 6.0.0 with #4066

@timneutkens
Copy link
Member

Thanks!

@kasajian
Copy link

@herrstucki got it right.

I learned about nextjs from staticgen.com. I have been evaluating nextjs tonight, and so far, I am able to create pages, etc., even retrieve data without a lot of effort. I'm really looking for a static site generator

But after I build, and try to export, I get
Could not find "exportPathMap" function inside "next.config.js"

Why?

next seems to be doing so much of the heavy lifting for me. The fact that I have to do any configuration at all in order to export a static version seems to me like this is not the framework that I'm looking for.

It's SO close -- it missed the boat entirely.

I submitted an issue with staticgen to remove nextjs from the list so more people like me don't waste time with it, unless they really aren't looking for a static-site-generator, in which case it seems like a great framework.

netlify/staticgen#390

@timneutkens
Copy link
Member

But after I build, and try to export, I get
Could not find "exportPathMap" function inside "next.config.js"

Next.js 6+ automatically exports all pages inside the pages directory as per #4066. So I'm not sure what you ran into exactly, can you provide a reproduction?

@kasajian
Copy link

I just got the latest bits, used the sample, and tried to do an export immediately after a build.

@kasajian
Copy link

Here's how to reproduce it:

git clone https://github.com/arunoda/learnnextjs-demo.git
cd learnnextjs-demo
git checkout getting-started
npm install
npm run dev
    (shutdown the server)
node_modules\.bin\next build 
node_modules\.bin\next export

My package.json:

{
  "name": "hello-next",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "next"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^4.2.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  }
}

@millette
Copy link
Contributor

millette commented Jun 25, 2018

@kasajian
Try the basic export example.

curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/basic-export
cd basic-export
npm install
npm run build
npm run export
cd out # tada!

Not sure what you expected from learnnextjs, but as you can see, it's using next 4.2.0 whereas next 6 made exportPathMap optional.

@kasajian
Copy link

Thank you. What I expected from learnnextjs is that it wouldn't have the problem that I encountered. I'm just going through the getting-started example on the site. I assume it's going to use the latest bits.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 25, 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

7 participants