With the updated matchPath sorting from https://github.com/gatsbyjs/gatsby/pull/17411, nested client only routes are not correctly displayed.
I believe it is also related to this issue: https://github.com/gatsbyjs/gatsby/issues/9705
You are navigated to /admin/user/123 and AdminUser component is displayed
match-paths.json should look like this
{
"path": "/admin/",
"matchPath": "/admin/*"
},
{
"path": "/admin/users/users/",
"matchPath": "/admin/*"
},
{
"path": "/admin/users/user/",
"matchPath": "/admin/*"
}
Url changes to /admin/user/123, but the AdminUsers component is displayed
match-paths.json looks like this:
{
"path": "/admin/users/users/",
"matchPath": "/admin/*"
},
{
"path": "/admin/users/user/",
"matchPath": "/admin/*"
},
{
"path": "/admin/",
"matchPath": "/admin/*"
},
System:
OS: macOS 10.14.6
CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 12.8.0 - /usr/local/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.9.0 - /usr/local/bin/npm
Browsers:
Chrome: 76.0.3809.132
Firefox: 68.0.2
Safari: 12.1.2
npmPackages:
gatsby: ^2.15.14 => 2.15.14
gatsby-image: ^2.2.18 => 2.2.18
gatsby-plugin-manifest: ^2.2.16 => 2.2.16
gatsby-plugin-offline: ^2.2.10 => 2.2.10
gatsby-plugin-react-helmet: ^3.1.7 => 3.1.7
gatsby-plugin-sharp: ^2.2.21 => 2.2.21
gatsby-source-filesystem: ^2.1.22 => 2.1.22
gatsby-transformer-sharp: ^2.2.14 => 2.2.14
@dopeters I've created new gatsby site based on the hello world starter and grabbed the code you posted. And i can confirm this. In the meantime depending on your use case and timeframe i would go with gatsby-plugin-create-client-paths, if you want i can update the code based on the plugin and hoist it to a repo and you can take a look at it at your own pace. Also i'm going to ping @wardpeet to see if he can chime in and possibly help you out better.
I'm not quite sure if this is bug. There are 3 routes with /admin/* matchPath so any of those are equally suitable to render /admin/user/123 route (there is nothing we can use to decide whether to use one or the other).
Maybe we could display warning if same matchPath is used for multiple routes (?)
@pieh it seems that what's intended is to funnel all the requests to the router inside /admin/ and let it deal with it. Probably this is more a edge case and a possible solution for this case is actually use the plugin.
@jonniebigodes The same thing happens in the actual app I found this issue in, which does use that plugin. If you are able to make an example with that plugin that works, I'd be very interested in seeing that.
Appreciate your help!
@dopeters let me start by apologize, in my comment it was written in a haste as i was really tired and basically i probably mislead you as you don't actually need the plugin.
With that out of the way i took a new look with "fresh eyes" (pardon the bad pun) to the example you supplied and it seems that you want to create client-side routing, probably something in the nature of this and this.
Based on that and your code, it seems that probably the problem itself resides in the implementation of the client side routing. Once again based on your code, you want to funnel the client side routes to /admin and all subsequent routes go from there.
You can achieve this by simplifying the way pages are handled in the onCreatePage api call in gatsby-node.js and some work done to the code.
Going to enumerate the steps i took to achieve this.
gatsby-node.js from:exports.onCreatePage = ({ page, actions }) => {
const { createPage } = actions
if (page.path.match(/^\/admin/)) {
createPage({
...page,
matchPath: "/admin/*",
})
}
if (page.path.match(/^\/admin\/user/)) {
createPage({
...page,
matchPath: "/admin/*",
})
}
if (page.path.match(/^\/admin\/users/)) {
createPage({
...page,
matchPath: "/admin/*",
})
}
if (page.path === "/") {
createPage({
...page,
matchPath: "/*",
})
}
}
to
exports.onCreatePage = async ({ page, actions }) => {
const { createPage } = actions
if (page.path.match(/^\/admin\/admin/)) {
page.matchPath = `/admin/*`
createPage(page)
}
}
With that all of the traffic incoming to /admin/ will be funneled directly into the router and let it do his job and show the what needs to be shown.
admin.js inside /src/pages/ inside /src/pages/admin.admin.js to reflect the changes and now looks like:import React from "react"
import { Router } from "@reach/router"
import AdminPage from "../../components/admin/admin"
import AdminUser from "../../components/admin/user"
import AdminUsers from "../../components/admin/users"
const AdminIndex = () => {
return (
<Router basepath="/">
<AdminPage path="admin" />
<AdminUser path="admin/user/:userId" />
<AdminUsers path="admin/users" />
</Router>
)
}
export default AdminIndex
As you can see by the code snippet the pages that the router will handle were moved. They are now inside /src/components/admin/*. Did this, because despite being pages, they are now treated as components and i wanted to keep it simple and clean, only leaving the router there.
All of the code of the pages is exactly the same.
gatsby build && gatsby serve to get a production build and emulate a production server. Opened up http://localhost:9000/admin and i'm presented with:

http://localhost:9000/admin/users yelds the following:
Created the repo, expanded the code you supplied with one extra example.
Pushed the code to a netlify site and with that i was getting some errors with the redirection. I don't know what will be your case, but take a look at the netlify.toml file for the redirects to prevent a 404 being shown and then flashes to the actual page and content.
Feel free to provide feedback so that we can close this issue or continue to work on it untill we find a suitable solution.
Once again sorry for the misleading information.
@jonniebigodes Thank you this was extremely helpful. Looks like changing the directory of those pages does solve the issue we're seeing. Gonna go ahead and close this out. Appreciate all the help!
@dopeters no need to thank, just glad i was able to help and you were able to solve the issue.
Most helpful comment
@dopeters let me start by apologize, in my comment it was written in a haste as i was really tired and basically i probably mislead you as you don't actually need the plugin.
With that out of the way i took a new look with "fresh eyes" (pardon the bad pun) to the example you supplied and it seems that you want to create client-side routing, probably something in the nature of this and this.
Based on that and your code, it seems that probably the problem itself resides in the implementation of the client side routing. Once again based on your code, you want to funnel the client side routes to
/adminand all subsequent routes go from there.You can achieve this by simplifying the way pages are handled in the
onCreatePageapi call ingatsby-node.jsand some work done to the code.Going to enumerate the steps i took to achieve this.
gatsby-node.jsfrom:to
With that all of the traffic incoming to
/admin/will be funneled directly into the router and let it do his job and show the what needs to be shown.admin.jsinside/src/pages/inside/src/pages/admin.admin.jsto reflect the changes and now looks like:As you can see by the code snippet the pages that the router will handle were moved. They are now inside
/src/components/admin/*. Did this, because despite being pages, they are now treated as components and i wanted to keep it simple and clean, only leaving the router there.All of the code of the pages is exactly the same.
gatsby build && gatsby serveto get a production build and emulate a production server. Opened uphttp://localhost:9000/adminand i'm presented with:http://localhost:9000/admin/usersyelds the following:Created the repo, expanded the code you supplied with one extra example.
Pushed the code to a netlify site and with that i was getting some errors with the redirection. I don't know what will be your case, but take a look at the netlify.toml file for the redirects to prevent a 404 being shown and then flashes to the actual page and content.
Feel free to provide feedback so that we can close this issue or continue to work on it untill we find a suitable solution.
Once again sorry for the misleading information.