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' } } }
);
@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.
But we are keep looking at the different options. Help us to figure out the best way to do this.
A few thoughts:
exportPathMap
too should be okay in this case. For convenience, next.js _could_ provide the default path map.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).// 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'
]
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.
@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.
@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.
@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)?
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.
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 https://github.com/zeit/next.js/issues/1972#issuecomment-301681368), 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]).
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.
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
}
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: https://github.com/zeit/next.js/pull/3451
Implemented in 6.0.0 with #4066
Thanks!
@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.
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?
I just got the latest bits, used the sample, and tried to do an export immediately after a build.
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"
}
}
@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.
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.
Most helpful comment
In a meantime, here's my workaround which uses
glob
to programmatically generateexportPathMap
: