Figuring Out Gatsby #2 - The basic, but clever things we can do with pages.

neosaurrrus

Lukie Kang

Posted on December 3, 2020

Figuring Out Gatsby #2 - The basic, but clever things we can do with pages.

Last time we set Gatsby up and made our first page(s). Now let's look at the common things you will do when building out an actual site.

For this series of blog posts, I am working on a hypothetical restaurant site which will have the following pages:

  • Home
  • Food
  • Drinks
  • Team

Since we have the Index page set up, we can build basic versions of these pages by copying and pasting it and replacing a few words:

//Food.js

import React from 'react';

function FoodPage() {
  return (
    <div>
      <p>This is the Food page</p>
    </div>
  );
}

export default FoodPage;
Enter fullscreen mode Exit fullscreen mode

Hopefully, you can figure out how the rest will look.

Navigation - Our First Component

I imagine you have been using the web long enough to see that a navbar allowing us to jump between pages is a good idea in our app. You may also see that abstracting this out into a single component we use on all of our pages will save us alot of code and hassle. So let's do that.

The components folder is where we create little pieces that are reuseable across pages. Here we can create a Nav Component like so:

//Nav.js
import React from 'react';

function Nav() {
  return (
    <nav>
      <ul>
        <li> Food</li> //Not a link yet... 
        <li> Drinks</li>
        <li> Team</li>
      </ul>
    </nav>
  );
}

export default Nav;
Enter fullscreen mode Exit fullscreen mode

We have to remember to add it to our Pages like so:

import React from 'react';
import Nav 
function FoodPage() {
  return (
    <div>
      <p>This is the Food page</p>
    </div>
  );
}

export default FoodPage;
Enter fullscreen mode Exit fullscreen mode

That will get the Nav component onto our pages, but it doesn't actually have any links just yet.

The Link Tag

Now you could use <a> tags but that will result in a page refresh which isn't very Gatsby (i.e doesn't leverage what Gatsby can do for us) so lets use Gatsby link tags instead:

import React from 'react';
import { Link } from 'gatsby';

export default function Nav() {
  return (
    <nav>
      <ul>
        <li>
          <Link to="/food">Food</Link>
        </li>
        <li>
          <Link to="/drink">Drink</Link>
        </li>
        <li>
          <Link to="/team">Team</Link>
        </li>
      </ul>
    </nav>
  );
}
Enter fullscreen mode Exit fullscreen mode

If you test that out, it is fast.

Navigate function

However, you can also change the page programatically. In other words, without replying on the user click? For a form for example. We need the navigate function from Gatsby:

import { navigate } from gatsby
//at some point in the code... 
navigate('/newpage', {replace: true})
Enter fullscreen mode Exit fullscreen mode

The {replace:true} option lets you add the new page to the history, which allows the back button to work for it.

Layouts

Most web page have a header, footer, navigation and a whole bunch of stuff that appears on each page. We have the Nav component added to each page, that will get annoying especially with a whole bunch of other components we want everywhere, this is where layouts come in.

It isn't as easy as just putting everything into a Layout component and calling it a day as we normally want our header to come before the content and the footer afterwards.

Handily, each component contains a props that references its children, allowing the components it contains to be rendered. So once we have created the Layouts component we can add props.children to allow child components to render between other elements of the layout.

export default function Layout(props){
  return (
    <div>
      <Header />
      {props.children}
      <Footer />
  )
}
Enter fullscreen mode Exit fullscreen mode

Obviously you can change what is in the Layout and all you'd need to do is add the Layout component to each page. However Gatsby does does give us a smarter way of doing it...

We need to create a file in the root location called gatsby-browser.js. This file allows us, for the browser use several APIs. These APIs can be found here. The one we want here is call `wrapPageElement\ which according to the Gatsby site:

Allow a plugin to wrap the page element.
This is useful for setting wrapper components around pages that won’t get unmounted >on page changes. For setting Provider components, use wrapRootElement.

So following the instructions given we will end up with something like this:

import React from 'react';
export function wrapPageElement({ element, props }) {
return {element};
}

As you can see it is fairly similar to the Layout, where props are what props the page contains and element is the page itself in Gatsby.

Important At time of writing, you need to restart the server when you modify these files If, like me you tend to lose the terminal you are running the server, then there is a [useful trick here(https://dev.to/eclecticcoding/kill-blocked-ports-25ca)

Once you have it working, the Layout component will be loaded on every page without doing anything! You might need to clear out old references to your Nav/Layout else you will see twice the Layout!

Finally, while this works for the browser, for server-side stuff, we want to do the same in a file called gatsby-ssr.js in the same location. Literally you can copy and rename the gatsy-browser.js file. More on all that SSR stuff later!

Hopefully if you followed all the above you have a smart set of pages with layouts that are smart!

Ok, now the problem with building a new app is that it all looks a bit dull in black and white and default fonts, so let's take an aside to look at using CSS with Gatsby in the next post!

💖 💪 🙅 🚩
neosaurrrus
Lukie Kang

Posted on December 3, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related