skip to Main Content

CURRENT BEHAVIOR

Hi. I am using Gatsby and my layout component (containing both header and footer) is placed inside gatsby-browser.js & gatsby-ssr.js’ wrapPageElement. However, in doing so, the layout is rendered on every page. I had placed my layout component inside both gatsby-browser and gatsby-ssr because I have dynamic content in my header – it shows the user’s email and navigation links if the user is authenticated

DESIRED BEHAVIOR

I would prefer my index page not to be wrapped with a layout since it’s will just be a static page for designs only and will not have any dynamic content

Henceforth, is there any way, I can do without Layout in my index.js? Thanks

gatsby-ssr.js & gatsby-browser.js

export const wrapPageElement = ({ element, props }) => {
      return <Layout {...props}>{element}</Layout>
    }

index.js

// a layout comprising both header and footer is still being rendered since layout component is in gatsby-ssr and gatsby-browser.js

import React from "react"
import { Link } from "gatsby"

import { Container } from "../components/common"
import SEO from "../components/seo"

const IndexPage = props => {
  return (
    <Container>
      <SEO title="Home" />
      <div>
        <Link to="/account">Go to your account</Link>
      </div>
    </Container>
  )
}

export default IndexPage

2

Answers


  1. Remove the Layout from gatsby-ssr and gatsby-browser.js. Place it in the all the pages components instead.

    Your index should look like this:

    const IndexPage = props => {
      return (
        <Layout {...props}>
          <Container>
            <SEO title="Home" />
            <div>
              <Link to="/account">Go to your account</Link>
            </div>
          </Container>
        </Layout>
      )
    }
    

    You should only put components in gatsby-ssr and gatsby-browser.js that you want on EVERY page like for example react-helmet or a page-wide React Context.

    You don’t want the layout to display on index therefore you cannot place it in gatsby-ssr and gatsby-browser.js.

    Login or Signup to reply.
  2. Edit 25aug2021

    I initially recommended checking "children.key", which doesn’t work when you are actually building your website. Instead "children.props.location.pathname" works for both SSR and non SSR. This is an example output of "children" when the build is created:

    {
        "key": null,
        "ref": null,
        "props": {
            "path": "/*",
            "*": "share-your-story",
            "uri": "/",
            "location": {
                "pathname": "/share-your-story",
                "search": "",
                "hash": ""
            },
            "pageContext": {
                "slug": "share - your - story "},
                "params":{}
        },
        "_owner":null
    }
    

    I have updated my answer below.

    For anyone still looking for another solution:

    This is possible by checking the value of "children.props.location.pathname", for the element/children which you pass to the Layout component for each page. This value contains the path of that page.

    So inside you Layout component, you can simply check the for which page path it’s being called for and then determine what to render.

    For example I don’t want to render the "Navigation" and "Footer" on the page with path "/no_layout", then I’ll do this inside the Layout.jsx:

    const Layout = ({ children }) => {
      // Conditionally don't show top and bottom nav
      if (children.props.location.pathname === '/no_layout') {
        return <>{children}</>
      }
    
      return (
        <>
          <Navigation />
          {children}
          <Footer />
        </>
      )
    }
    
    export default Layout
    

    Or if you have multiple pages/paths that you want to exclude from the regular layout and perhaps have a full screen layout, then you can just put them in a list and check the current path’s existence:

    const fullScreenPaths = [
      '/no_layout',
      '/never_layout',
      '/skip_layout',
      '/nope_layout',
      '/hellno_layout',
    ]
    
    const Layout = ({ children }) => {
      // Conditionally don't show top and bottom nav
      if (fullScreenPaths.includes(children.props.location.pathname)) {
        return <>{children}</>
      }
    
      return (
        <>
          <Navigation />
          {children}
          <Footer />
        </>
      )
    }
    
    export default Layout
    

    Kudos to this old comment on github for getting me on the right track.

    And if you don’t fully understand with what I mean with "children.props.location.pathname", then just:

    console.log(children)
    

    to see all the values you can use on rendering the layout.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search