I am struggling to implement a sub-routing system on a page which is created through createPage.
I need the default sub-route of the page to be built to static html but also, any subsequent sub-routes on the same page need to be client only. This has led to me having two routers for the same page. One on the template used for createPage and then one on the page component I use for the matchPath assignment.
The issue I am getting is that the template component is rendering for the default sub-route and then for any other sub-routes the page component is, resulting in full page flashes and data updating when it shouldn't be.
Have replicated my approach in this codesandbox. Make sure to go to https://hkhbb.sse.codesandbox.io/test/foo/bar to see the output.
I go into detail about my issues on #14954. I thought I had got round the issue but it has since returned since updating to latest gatsby (2.13.45). Is this the correct approach when trying to achieve what I am trying to achieve?
Thanks!
EDIT:
I should mention that I have around 25k pages generated which need to have this sub routing system on. I have tried adding a matchPath directly in createPage but this inflates the JS bundle massively because of an array containing matchPath data.
I have had a similar issue when trying to create a "tab"-like sub navigation on a page. I would be interested to see if the approach is valid or not.
Check out my answer to your SO question: https://stackoverflow.com/a/57444523/10340970
TL,DR: You should make /test/foo/bar a root page for dynamic route as well, instead of mixing static page (/test/foo/bar) with dynamic route (/test/:param1/:param2)
Check out my answer to your SO question: https://stackoverflow.com/a/57444523/10340970
TL,DR: You should make
/test/foo/bara root page for dynamic route as well, instead of mixing static page (/test/foo/bar) with dynamic route (/test/:param1/:param2)
Thanks for this! I have added a comment to your answer.
Basically, what you are saying is correct and it gets around the rendering problem. But because we are generating so many pages (#14954), the JS bundle becomes to large for us to be able to use it as a solution, because of the array containing matchPath data.
In that issue above, I am told that adding so many matchPaths to pages isn't recommended and I can see why, but I don't think there has been any thought to our current use case. I understand it is an edge case, but we currently can't update to the latest Gatsby without getting round this some way, or coming up with a completely different solution.
I understand it is an edge case
Is it an edge case though? If I understand your requirement correctly, it's equivalent to wanting to add a REST URL-style edit sub-route:
/posts/123 - statically generated
/posts/123/edit - client-only protected route
That's a very common case so I've filed #24792 for a clearly documented solution.
This is already possible:
createPage({
path: `/posts/123`,
component: require.resolve("./src/templates/post.js"),
matchPath: `/posts/123/*`
})
Your post page is statically generated, and will handle all sub routes off that, i.e. /posts/123/edit
This is already possible:
createPage({ path: `/posts/123`, component: require.resolve("./src/templates/post.js"), matchPath: `/posts/123/*` })Your post page is statically generated, and will handle all sub routes off that, i.e.
/posts/123/edit
You're right and I went down this route originally, but for large websites this isn't a good solution as each matchPath is added to the bundle, and the bundle size is then inflated.
Just to say, for our site we ended up abandoning the sub routing and ended up having a tabbing system which just links to a new page (entire layout re-renders).
Yep the algorithm would have to change which is somewhat discussed here.
Yep the algorithm would have to change which is somewhat discussed here.
It is discussed there in a sense, but even if the logic there changed I'm not sure it would help in this case. If we directly added matchPath to every create page then they would be in the matchPath array before we even hit the code mentioned in that issue.
The example I've put in there is unrelated to your issue here, but it highlights that there are multiple further ways that people want to use it.
It could be that the matchPaths is extended to allow user-defined functions:
//i.e. path is /posts/123/edit
path => {
if(path.match(/posts\/\d+/) {
// return the correct static route, i.e. /posts/123
} else {
return null
}
Most helpful comment
The example I've put in there is unrelated to your issue here, but it highlights that there are multiple further ways that people want to use it.
It could be that the matchPaths is extended to allow user-defined functions: