Home > Software design >  In Gatsby how to identify if current page being rendered is 404?
In Gatsby how to identify if current page being rendered is 404?

Time:04-08

In src/pages I've setup a 404.js page per the docs "Adding a 404 Page". Within this file I'm calling my Layout component and also passing in location props.

In my Layout.js file I'm trying to conditionally render some components based on wether the current page is a 404. In my testing the location object doesn't render a boolean for this, example testing with the browser asdsada:

hash: ""
host: "localhost:8000"
hostname: "localhost"
href: "http://localhost:8000/asdsada"
key: "initial"
origin: "http://localhost:8000"
pathname: "/asdsada"
port: "8000"
protocol: "http:"
search: ""
state: null

I was unable to find a way to do this after reading:

In Gatsby is there a way to identify if the current page being rendered is the 404 page so I can ternary a component?

CodePudding user response:

You can use allSitePage node, which is automatically generated by Gatsby.

{
  allSitePage(sort: {fields: path, order: ASC}) {
    edges {
      node {
        id
        path
      }
    }
  }
}

Extracted from: https://www.gatsbyjs.com/docs/recipes/querying-data/

You can place it in a useStaticQuery hook, loop through them, and find (or using some) your current page path (extracted from location). Something like:

const is404 = allSitePage.edges.some(({ node }) => node.path === `${location.pathname}/`)

If your current page (location.pathname) is not in the list of all pages (allSitePage), for example /asdsada means that you are displaying the 404 page.

You can also use an includes or other approaches.

CodePudding user response:

Wanting to identify if the page was 404 so I could conditionally render my Breadcrumb component that exists in my Title component. Here is my working example with the help of the answer. I did run into an issue looping through the suggested variable pageIs404 but I was able to understand and solve the issue with identifying if 404 using:

 const is404 = allSitePage.edges.some(({ node }) => node.path === `${location.pathname}/`)
    ? false
    : true

note when testing in GraphiQL the query of:

query MyQuery {
  allSitePage {
    edges {
      node {
        id
        path
      }
    }
  }
}

resulted in:

{
  "data": {
    "allSitePage": {
      "edges": [
        {
          "node": {
            "id": "SitePage /dev-404-page/",
            "path": "/dev-404-page/"
          }
        },
        {
          "node": {
            "id": "SitePage /404/",
            "path": "/404/"
          }
        },
        {
          "node": {
            "id": "SitePage /404.html",
            "path": "/404.html"
          }
        },
        {
          "node": {
            "id": "SitePage /contact/",
            "path": "/contact/"
          }
        },
        {
          "node": {
            "id": "SitePage /",
            "path": "/"
          }
        }
      ]
    }
  },
}

and since I was comparing path I modified the test for pathname to ${location?.pathname}/

my useStaticQuery in the Layout component looks like:

  const { allSitePage } = useStaticQuery(
    graphql`
      {
        allSitePage(sort: { fields: path, order: ASC }) {
          edges {
            node {
              path
            }
          }
        }
      }
    `,
  )

and then I just passed it down to the needed component with:

<Title pageName={pageName} is404={is404} />

in the Title component I test and render with:

{is404 === false && <Breadcrumbs />}
  • Related