When exporting a page that defines getStaticPaths using exportPathMap, the routes defined in exportPathMap don't matter (i.e. they get overridden by getStaticPaths).
Assuming /blog/[slug].js has
export function getStaticPaths() {
return { paths: ["/blog/1st-post", "/blog/2nd-post"], fallback: false };
}
exportPathMap: () => ({
"/blog/irrelevant": {
page: "/blog/[slug]"
} // => will still output /blog/1st-post.html, /blog/2nd-post.html
});
Actually, I think the behavior is not wrong but maybe there should be a warning?
I think using exportPathMap _together_ with getStaticPaths can still be useful, e.g. if one wants to only export a subset of all pages. Maybe exportPathMap needs to only specify page paths when using GSP? E.g.
exportPathMap: () => ["/blog/[slug]"] // => intention is clear; let page handle all paths
Another odd behavior I just discovered: exportPathMap does not actually control anything related to pages using getStaticPaths. Even when ePM is set to {}, next export will export all pages with gSP 🤔
exportPathMap: () => ({}); // => will still output /blog/1st-post.html, /blog/2nd-post.html
Usage of exportPathMap for defining routes is discouraged now that you can handle it at the page level. We could probably add a warning though.
What's your take on being able to specify _which_ pages should be exported – or rather be excluded from the build?
Use case: I have an app that includes pages for docs and some for tests. Depending on the environment, I may want to only build/export the test pages, only build/export docs pages or exclude both from a build.
That's already possible using fallback: true I guess (if I understand your question correctly): https://nextjs.org/docs/basic-features/data-fetching#fallback-true
Hmm, no, I didn't meant to render fallback pages but for example if I have a pages folder that looks roughly like this:
… it would be great to be able to specify for next build (or next export) to
test/[id] (which could prerender to multiple pages using gSP)docs/*test/* and docs/* in prodWith next.js pre-9.3, I could somehow do this using different exportPathMaps.
I'm experiencing an error with {fallback: true} when using "next export" to deploy to Netlify making it return a 404 anyway.
Fallback behavior is not supported on fully static hosts, it requires next start or serverless target with integration, eg https://zeit.co supports it.
It would be great to see https://nextjs.org/docs/advanced-features/static-html-export updated to clarify that usage of exportPathMap is discouraged now -- I had to google and arrive at this issue to figure it out!
edit: pr #11814 filed to clarify documentation
Fallback behavior is not supported on fully static hosts, it requires
next startor serverless target with integration, eg https://zeit.co supports it.
Is there technical issue with supporting fallback behavior with static exports? This would let people naively route dynamically, much like react router. Is as fast? No, but it enables people to use Next under the constraints of needing to export static HTML and not being able to enumerate all values in a database at build time.
@miloofcroton This sounds like a different question you could file a separate issue for, but you can probably already use next's custom error handling if you wanted to perform some kind of fully dynamic routing with fallback client-side fetching.
@miloofcroton This sounds like a different question you could file a separate issue for, but you can probably already use next's custom error handling if you wanted to perform some kind of fully dynamic routing with fallback client-side fetching.
Can you explain your thought there? I'm not quite following.
I tried seeing what props I could get on my custom 404 page if I hit a non-existent route (e.g. I went to /posts/4 even though I only have /posts/[id] in my pages dir, and there's no exportPathMap. I'm assuming I should somehow get a prop on the error page that would let me redirect back to /posts/[id] and pass in a page prop, but I'm not seeing how.
@miloofcroton you can use the next router on your custom 404 page, and grab its asPath property to check which path was requested. ie.
import { useRouter } from 'next/router'
export default function Custom404() {
const { asPath } = useRouter()
// add custom logic to check `asPath` and redirect or render custom component here
}
From there you can render a custom component, or use Router.push to redirect to some predefined fallback page. Here's a minimal, naive example of the latter:
// 404.js
import Router, { useRouter } from 'next/router'
export default function Custom404() {
const { asPath } = useRouter()
if (asPath.startsWith('/posts')) {
Router.push('/fallback', asPath)
}
return <h1>404 - Page Not Found</h1>
}
// fallback.js
import { useRouter } from 'next/router'
export default function Fallback() {
const { asPath } = useRouter()
// a more realistic scenario might involve data fetching with a hook here
if (asPath.startsWith('/posts')) {
const id = parseInt(asPath.split('/')[2]);
return <h1>welcome to post {id}</h1>
}
return <h1>fallback error!</h1>
}
Hope that's enough to get you started -- if not, maybe it's better to open a separate issue so that it's not lost in the shuffle.
It sounds like we'll want to emit a warning saying we ignore any getStaticPaths powered page that is referenced in exportPathMap.
Most helpful comment
Usage of
exportPathMapfor defining routes is discouraged now that you can handle it at the page level. We could probably add a warning though.