Gatsby: reach/router documentation (or bug?)

Created on 4 Jul 2019  路  13Comments  路  Source: gatsbyjs/gatsby

Hi all,

Summary

I'm new to both Gatsby and React, so I'm guessing it is my own ignorance holding me back here, but I've been having a hard time trying to get routing to work using the @reach/router in v2. I couldn't find anything in the issues or the docs that was helpful. I did see someone complaining recently on Twitter - https://twitter.com/pugson/status/1146087953594224641 - about the lack of documentation for @reach/router (which I share), but the proposed solution to copy code from https://t.co/HHB69cui95 didn't help.

Relevant information

I created an example of what I'm trying to do in a public repo here: https://github.com/erikhopp/gatsby-routing-test

I'm just trying to use the Router component to create new pages and to pass parameters through the URL (but not as query components).

const IndexPage = () => (
  <Layout>
    <Router>
      <Home path="/" />
      <ThingHome path="thing" />
      <Thing path="thing/:thingId" />
    </Router>
  </Layout>
)

In context: https://github.com/erikhopp/gatsby-routing-test/blob/master/src/pages/index.js

Whenever I'm going to anything but '/' I'm getting a 404 error. I've tried a bunch of different things in the process of understanding the syntax and structures.

I'm starting to think it is something wrong in my environment and not actually the code since it seems like the code is pretty straight-forward.

Any help would be greatly appreciated.

Environment (if relevant)

Local development

System:
OS: macOS 10.14.5
CPU: (8) x64 Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 12.4.0 - ~/.nvm/versions/node/v12.4.0/bin/node
Yarn: 1.16.0 - /usr/local/bin/yarn
npm: 6.9.2 - ~/.nvm/versions/node/v12.4.0/bin/npm
Languages:
Python: 2.7.16 - /usr/local/bin/python
Browsers:
Chrome: 75.0.3770.100
Firefox: 67.0.4
Safari: 12.1.1
npmPackages:
gatsby: ^2.13.3 => 2.13.3
gatsby-image: ^2.2.4 => 2.2.4
gatsby-plugin-manifest: ^2.2.1 => 2.2.1
gatsby-plugin-offline: ^2.2.0 => 2.2.0
gatsby-plugin-react-helmet: ^3.1.0 => 3.1.0
gatsby-plugin-sharp: ^2.2.2 => 2.2.2
gatsby-source-filesystem: ^2.1.2 => 2.1.2
gatsby-transformer-sharp: ^2.2.1 => 2.2.1
npmGlobalPackages:
gatsby-cli: 2.7.7

File contents (if changed)

No changes from the Gatsby Default starter

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

stale? awaiting author response question or discussion

Most helpful comment

Reopening this since we still need docs for @reach/router! I'm nearly finished with this doc, and I'll incorporate some of the discussion here into it.

All 13 comments

I think this is because you need to create client-side paths, since you haven't actually created those pages in the pages/ directory. You might run into issues with the plugin to do so, like #15294.

@erikhopp Disregard my previous answer.

The issue is that you are missing a wildcard path for your page with clientside view. See gatsby node of the example.

Hi folks,

Thanks for the responses. I've just now added the code @freiksenet pointed to in the gatsby-node.js file and I'm not seeing any different behavior.

Here is a diff:

+
+exports.onCreatePage = async ({ page, actions }) => {
+  const { createPage } = actions
+
+  // page.matchPath is a special key that's used for matching pages
+  // only on the client.
+  if (page.path.match(/^\/thing/)) {
+    page.matchPath = `/thing/*`
+
+    // Update the page.
+    createPage(page)
+  }
+}

Here is the commit: https://github.com/erikhopp/gatsby-routing-test/commit/15c9fa82047904178167ecc85f75b78087d940da

Then I stacked on the suggestion that @JaKXz made here - https://github.com/erikhopp/gatsby-routing-test/commit/4ebb8b1f25b6e9bbcd6e4697edcc80d23fabb75d - and that also didn't change anything, unfortunately.

Please see the repo that I've created to help identify the issue - https://github.com/erikhopp/gatsby-routing-test. Am I doing something stupid that all other Gatsby users know to avoid? Is it something with my environment?

Thanks.
Erik

Hi!

What else can I do to help move this issue forward? I'm still not able to get what seems to me to be pretty basic routing working within Gatsby.

@wardpeet, since you've assigned this to yourself, does that mean you have a diagnosis for the issue?

Thanks all for taking a look!
Erik.

Hey @ericpoe
You do need to have /thing/ page first when you are using gatsby-plugin-create-client-paths plugin or code in https://github.com/erikhopp/gatsby-routing-test/blob/master/gatsby-node.js (btw. both of those do the same thing).

So you would need to create file /src/pages/thing.js with react component. That react component will be rendered then for /thing/* paths

@erikhopp Hey, try changing the ThingHome path to /thing like so.

<ThingHome path="/thing" />

The line after that with the :thingId, I'm not sure about this one... But try this and see if it works. Also, the order in which you place each route inside of I think matters as well. So try putting the "/" as the last child in this element to see if this makes a difference.

Also, are you just running this locally? And are you by any chance deploying this project to github pages with a pathPrefix?

I've included a project and demo here for client only routes with some routes hidden until authenticated. It works fine locally and on Netlify, but if I try to put it on Github pages with a pathPrefix, I get 404 errors:

Simple-Auth [Demo on Netlify], [[Demo on GitHub Pages with pathPrefix](https://bchehraz.github.io/simple-auth/)] [[Source](https://github.com/bchehraz/simple-auth)]

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

Hey again!

It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.

Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community!

Reopening this since we still need docs for @reach/router! I'm nearly finished with this doc, and I'll incorporate some of the discussion here into it.

Hey again!

It鈥檚 been 30 days since anything happened on this issue, so our friendly neighborhood robot (that鈥檚 me!) is going to close it.

Please keep in mind that I鈥檓 only a robot, so if I鈥檝e closed this issue in error, I鈥檓 HUMAN_EMOTION_SORRY. Please feel free to reopen this issue or create a new one if you need anything else.

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks again for being part of the Gatsby community!

I agree with the sentiment of the original poster. In common with so much in Gatsby, the documentation for reach/router is almost non-existant. The code given at the reach router site does not work out of the box for gatsby, there are no examples that I could find on Gatsby website (for the most simple router example) and a search of the web reveals almost nothing. And yet the direct quote from the gatsby website is "We recently announced the second major release of Gatsby 馃殌. One change we want to highlight is the switch to using @reach/router to improve the accessibility of routing in Gatsby sites. What is @reach/router, and what are the benefits of undertaking the switch?"

The worst part is that this lack of documentation for even the most simple cases is very typical and is another example of what puts many off Gatsby.

Still nothing on the docs, as a work-around I'm using query strings whenever I need dynamic routes, it's not ideal, but it does work.

Just to encourage people I got this working. I offered to work on docs at the Gatsby support site and got no interest/ reply.

The route I took (pun intended) was say you want an area called features with some components that mount depending on url after [your domain]/features/[some feature] you do something like this.

Create a page in your pages folder called:

features.js

import React from "react"
import { Router } from "@reach/router"
import Layout from "../components/layout"
import Feature1 from "../components/features/route1"
import Feature2 from "../components/features/route2"
//import some nav component?

const Features = (props) => {
  console.log (props.location.pathname)
  return (
  <>
    <Layout>
//some nav required, can be here or in an imported component
      <Router>
        <Feature1 path='/features/feature1'/>
        <Feature2 path='/features/feature2'/>
      </Router>
    </Layout>
  </>
)}
export default Features

You put your individual features code in your components feature1, feature2 etc. They reside with the rest of your components since they are not pages.

Then you have this in your gatsby-node.js

exports.onCreatePage = async ({ page, actions }) => {
  const { createPage } = actions
  // page.matchPath is a special key that's used for matching pages
  // only on the client.
  if (page.path.match(/^\/features/)) {
    page.matchPath = "features/*"
    // Update the page.
    createPage(page)
  }
}
//some recommended this optionally; although didn't work well for me
exports.onCreateWebpackConfig = ({ stage, actions }) => {
  actions.setWebpackConfig({
    output:{
      publicPath: '/',
    },
    devServer: {
      historyApiFallback: true,
      contentBase: './features/',
      hot: true
    },
  })
}

At this point if your nav points to those _exact_ paths above in features.js, you should get the right component for the right path. So going to [your domain]/features/feature1 will load all of features.js but with only the component 'Feature1' mounted inside your Router

Then finally for it to work on build on Netlify add a file to your root (where gatsby-node.js resides) called netlify.toml. I kept in the reference to the stack answer as a courtesy.

#https://stackoverflow.com/questions/58065603/netlify-renders-404-on-page-refresh-using-react-and-react-router 
[[redirects]]
  from = "/features/*"
  to = "/features/index.html"
  status = 200

That ensures a proper refresh.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

totsteps picture totsteps  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

andykais picture andykais  路  3Comments

magicly picture magicly  路  3Comments

brandonmp picture brandonmp  路  3Comments