Create app like navigation that is shared across pages and will persist on the page (rather than re-rendering when you refresh or change pages) like you'd get in a traditional Single Page Application. This is useful for headers, sidebars, and navigation elements to preserve state and weird flashes of reloading content.
This lesson utilizes a few React components that implement the Gatsby specific
wrapPageElement which is used to wrap all pages in a Gatsby app with a set of components. A similar API called
wrapRootElement is often used to wrap an app in context providers.
Kyle Gill: [0:00] To get started, we need a component for our app to use across multiple pages. We're going to build a layout component for that. Create a file called layout.js, and inside it, import React. Additionally, import some components from Chakra UI to give us easier to use components to set up the structure. I'm using a flex and grid.
[0:21] Create a new component with the children from props to structured. Add a grid to vertically align a header, which we'll add soon, a flex section and a flex component, with the as prop used to make a display as a footer. Finally, the component is the export at the bottom.
[0:41] Now in to make sure the header component is imported, and we need to create the actual file for it. Import React again, as well as more Chakra UI components, button flex and text. Use them to create the component with a simple header structure inside of a Flex component. I'm including a title for the app, as well as a few buttons that will be used to navigate between pages and link to sign up.
[1:11] You can preview the component by going to the Index page, importing the layout, and wrapping the existing content of the page with the new component. Not too impressive yet, but you can see the header, main section, and footer. With some more styles added, it will look a lot cleaner.
[1:27] Since the buttons in the header will navigate to other pages and should actually be links, go back to the header file, import Link from Gatsby, and provide it through the Chakra UI as prop to make the buttons render a more semantic inaccessible link tag instead. This also allows you to use the props for a GatsbyLink as well, like the to prop to tell the link what page to navigate to when clicked.
[1:52] However, if we create a new page, like /new to eventually display a new playlists, we have to wrap the entire page component in the layout again. Each time you navigate between pages, the whole layout re-renders and will lose it state. This will become more important when we add authentication.
[2:08] Note that the new component here in the page directory will automatically be turned into a route/new based on its file name by Gatsby. We want to remove the layout and let Gatsby handle wrapping each page with it.
[2:23] Gatsby has an API called wrapPageElement to wrap each page with your own components and persist those components between pages. It's perfect for this use case. Create one more component called the wrapPageElement and import React in your layout component.
[2:38] Export a function with the name of the Gatsby API, wrapPageElement. The function should include your newly created layout component and include the page element in it. The element is what contains all of the code from your page like children in React. Be sure to pass in the other props as well.
[3:01] We need to make sure Gatsby will pick up this function and run it at the appropriate stage of Gatsby's develop and build processes by including it inside of the gatsby-browser and gatsby-ssr file. Create them at the root of the site if they don't already exist.
[3:15] These files are read during the build step to enhance how Gatsby service site renders or works in the browser. Re-export the wrapPageElement component that you already created in both the gatsby-ssr and gatsby-browser files to include the layout when the site is server-side rendered, and when it's rendered in the browser.
[3:35] Now, you can remove the layout component from your files in the pages directory. Restart the site with the gatsby develop command, and your layout will persist across all pages in your app. Only the children will get re-rendered and the state will be preserved.