Convert the static Homepage Banner

Prismic no longer recommends the gatsby-source-prismic-graphql plugin

With recent changes to Gatsby, Prismic no longer recommends the gatsby-source-prismic-graphql plugin that this documentation uses. Read more about the future of Prismic and Gatsby. We highly recommend using the gatsby-source-prismic instead. The documentation for this plugin can be found in the plugin's github README.

We will leave this documentation here for now, but will change it in the future when we determine the best approach for Prismic & Gatsby.

Welcome to the 2nd article in the Gatsby/Prismic Getting started tutorial series. We'll be walking through the steps required to convert the top homepage banner from being hardcoded in your Gatsby app to being filled with content from Prismic.

Before Reading

If you haven't already gone through the first step, we recommend you start there to download the project, launch a Prismic repository, and install the required dependencies.

Model the banner in Prismic

The first step when converting a project to use a headless CMS like Prismic is to model your content. We won't go super in-depth in this article, so if you want to learn more, check out our Content Modeling guides.

Let's take a quick look at our website so that we know what we need to do. If you don't already have your website running, then open a terminal at the root of your project and run the following command.

Copy
npm start

Looking at your homepage you'll see the banner at the top of the page then a number of different content elements below. In this example we will assume that the banner is a page element that we will always want on top of the page. We will also assume that the content below the banner should be easy to change and modify by the content authors.

We should model the banner as static, top-level fields. Everything below the banner will be modeled (as we will see in the next article) using a Slice Zone.

Model the banner's content fields

Now that we've decided to model the banner using static, top-level fields, we need to determine which fields to use. This is pretty straight forward. We will need the following fields:

Here's a video to further show this.

This model has already been put into place in your Prismic repository. Go to your Prismic repo, click on the Custom Types button in the left hand navigation bar, then select your Homepage type. Here you can see how these fields were configured in Prismic (note that you do not need to change anything, just take a look at how it is set up).

The homepage Custom Type

Make sure not to change anything and go back. Then click on the "Content" button on the left to go to your current Prismic content. From here, click on your homepage document to view the live document. It should look something like this:

The homepage document in Prismic

prismic_title

If you were curious about the prismic_title field, this is a field that we added for the sole purpose of giving an easy to find title in the Prismic UI. Sometimes this is a nice thing to add to a document in Prismic.

In our case, we already did the content modeling for you, but in your own project, you would need to build your Custom Type and fill in the content on your own. Now that we have a good understanding of the model, let's take a look at how to retrieve your content from Prismic.

Query the banner fields

The next step will be to query your homepage content. Gatsby uses GraphQL which is a query language in which you need to specify everything that you're looking for. Let's take a look at the query we'll need for this.

If you don't already have your project launched, start it up by running npm start from your terminal. Once the project is built and running, let's take a look at your API Explorer at http://localhost:8000/__graphql.

Once there, input this query in the left-hand panel:

Copy
{
  prismic {
    allHomepages {
      edges {
        node {
          banner_title
          banner_description
          banner_link {
            _linkType
            ... on PRISMIC_Page {
              _meta {
                uid
                type
              }
            }
          }
          banner_link_label
          banner_background
        }
      }
    }
  }
}

You can run the query by pressing the "play" button at the top, which should then show you the results of the query on the right.

The working GraphQL query

So we know that the query is working. There are a few important things to note here:

  • We have to include the prismic keyword at the top of the query to make sure that we are drawing from the Prismic content that the Prismic plugin collects at build time.
  • The allHomepages field is used to distinguish that we are querying the Homepage Custom Type.
  • Then we specify all the fields that we want to retrieve using their API IDs. For most of the fields we just need to use the API ID, but as you can see, the Link field is a bit more complicated. Read more about it here.

Now that we have our query, let's put it into our Homepage component. If you don't already have your project files open, open them now.

Navigate to src/pages/index.js. Let's add our Prismic query to this component! Here's what the following code snippets will show you:

  1. The first tab shows you just the query to add
  2. The second tab will show you how to retrieve the data object and do a console log to check that your query is working.
  3. The full index.js component with both 1 and 2 in place
  • Query
  • Retrieve the data
  • Full index.js file
Copy
import { graphql } from 'gatsby'

...

export const query = graphql`
{
  prismic {
    allHomepages {
      edges {
        node {
          banner_title
          banner_description
          banner_link {
            _linkType
            ... on PRISMIC_Page {
              _meta {
                uid
                type
              }
            }
          }
          banner_link_label
          banner_background
        }
      }
    }
  }
}
`
...
Copy
const Homepage = ({ data }) => {
  console.log(data)
  return (
    ...
Copy
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/Layout'
import SEO from '../components/SEO'
import HomepageBanner from '../components/HomepageBanner'
import MainContent from '../components/MainContent'

const Homepage = ({ data }) => {
  console.log(data)
  return (
    <Layout isHomepage>
      <SEO title="Home" />
      <HomepageBanner />
      <MainContent />
    </Layout>
  )
}

export const query = graphql`
query {
  prismic {
    allHomepages {
      edges {
        node {
          banner_title
          banner_description
          banner_link {
            _linkType
            ... on PRISMIC_Page {
              _meta {
                uid
                type
              }
            }
          }
          banner_link_label
          banner_background
        }
      }
    }
  }
}
`

export default Homepage

Now go to your local site at http://localhost:8000/ and refresh the page. In the browser console, you should see the data returned from Prismic.

GraphQL query results

Excellent, we know that the query is working as expected!

Render the results

With our query working, let's now render the results to produce the homepage banner.

Update the Homepage component

First let's remove the console.log, prepare the banner content, then pass it to our HomepageBanner component. Here's what the Homepage component should look like now:

  • Homepage component
  • Full index.js file
Copy
const Homepage = ({ data }) => {
  const prismicContent = data.prismic.allHomepages.edges[0]
  if (!prismicContent) return null
  const document = prismicContent.node

  const bannerContent = {
    title: document.banner_title,
    description: document.banner_description,
    link: document.banner_link,
    linkLabel: document.banner_link_label,
    background: document.banner_background,
  }

  return (
    <Layout isHomepage>
      <SEO title="Home" />
      <HomepageBanner bannerContent={bannerContent} />
      <MainContent />
    </Layout>
  )
}
Copy
import React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/Layout'
import SEO from '../components/SEO'
import HomepageBanner from '../components/HomepageBanner'
import MainContent from '../components/MainContent'

const Homepage = ({ data }) => {
  const prismicContent = data.prismic.allHomepages.edges[0]
  if (!prismicContent) return null
  const document = prismicContent.node

  const bannerContent = {
    title: document.banner_title,
    description: document.banner_description,
    link: document.banner_link,
    linkLabel: document.banner_link_label,
    background: document.banner_background,
  }

  return (
    <Layout isHomepage>
      <SEO title="Home" />
      <HomepageBanner bannerContent={bannerContent} />
      <MainContent />
    </Layout>
  )
}

export const query = graphql`
query {
  prismic {
    allHomepages {
      edges {
        node {
          banner_title
          banner_description
          banner_link {
            _linkType
            ... on PRISMIC_Page {
              _meta {
                uid
                type
              }
            }
          }
          banner_link_label
          banner_background
        }
      }
    }
  }
}
`

export default Homepage

prismicContent

If you're curious about the if (!prismicContent) return null check that is done, we've added this to prevent an error from occurring when you eventually deploy the site live. There is an issue with the preview functionality that requires this check on every page. You can learn more about it here.

Update the HomepageBanner component

Open your src/components/HomepageBanner.js file. We will now update this file to retrieve the bannerContent prop that we passed in the Homepage component, then replace the static content with the Prismic content. We will use the prismic-reactjs library that we installed in the last article to help with the Rich Text fields.

Copy
import React from 'react'
import { Link } from 'gatsby'
import { RichText } from 'prismic-reactjs'

const HomepageBanner = ({ bannerContent }) => (
  <section
    className="homepage-banner"
    style={{ backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${bannerContent.background.url})` }}
  >
    <div className="banner-content container">
      <h2 className="banner-title">{RichText.asText(bannerContent.title)}</h2>
      <p className="banner-description">{RichText.asText(bannerContent.description)}</p>
      <Link to="/about" className="banner-button">{RichText.asText(bannerContent.linkLabel)}</Link>
    </div>
  </section>
)

export default HomepageBanner

You can see that we're now populating the homepage banner with our Prismic content. If you want to learn more, check out our articles on Rendering a Rich Text field and Rendering an Image field.

Some of you might have noticed that we didn't use the Link field yet but still have the hardcoded Link path: "/about". This is a bit more complicated and will require that we setup a Link Resolver function. Let's do that now.

We'll just give a brief introduction to Link Resolving here, to learn more check out the Link Resolving article. The Link Resolver is a simple function that takes in a Prismic document object or Link field and returns the corresponding url for that page in your site. Let's create one now.

Create a new folder in the src directory with the name utils. Then inside the new folder, create a file named linkResolver.js. Add the following code to your new src/utils/linkResolver.js file.

Copy
const linkResolver = (doc) => {
  if (doc.type === 'page') return `/${doc.uid}`
  return '/'
}

export default linkResolver

As you can see here, if the link passed to the Link Resolver is of the type "page", then it will generate the url using the page's UID value (which we will explore further in a later article). Anything else will return the root of the website: '/'.

Now that we have our link resolver, let's register it with the Gatsby/Prismic plugin. Open the gatsby-browser.js file and update the file to this:

Copy
import './src/styles/reset.css'
import './src/styles/common.css'
import './src/styles/style.css'

import { registerLinkResolver } from 'gatsby-source-prismic-graphql'
import linkResolver from './src/utils/linkResolver'

registerLinkResolver(linkResolver)

Our Link Resolver should now be registered and ready to use.

Add the final touches

Now we can add the final piece. Let's head back to src/components/HomepageBanner.js and make the following updates:

  • Additions
  • Full component
Copy
import { linkResolver } from 'gatsby-source-prismic-graphql'
...
<Link
  to={linkResolver(bannerContent.link._meta)}
  className="banner-button"
>
  {RichText.asText(bannerContent.linkLabel)}
</Link>
...
Copy
import React from 'react'
import { Link } from 'gatsby'
import { RichText } from 'prismic-reactjs'
import { linkResolver } from 'gatsby-source-prismic-graphql'

const HomepageBanner = ({ bannerContent }) => (
  <section
    className="homepage-banner"
    style={{ backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${bannerContent.background.url})` }}
  >
    <div className="banner-content container">
      <h2 className="banner-title">{RichText.asText(bannerContent.title)}</h2>
      <p className="banner-description">{RichText.asText(bannerContent.description)}</p>
      <Link
        to={linkResolver(bannerContent.link._meta)}
        className="banner-button"
      >
        {RichText.asText(bannerContent.linkLabel)}
      </Link>
    </div>
  </section>
)

export default HomepageBanner

Congrats, now the homepage banner is completely filled with content pulled from Prismic!

Test the new banner

To test that the content is coming from Prismic, do the following:

  1. Go to your Prismic repository and open the homepage document.
  2. Make a change to your banner content.
  3. Save and publish your changes.
  4. In your terminal, stop the current Gatsby server by pressing CTRL + C.
  5. Relaunch your server by running npm start.

This will re-build your site and update the content from your Prismic repository. When the build is complete, you can refresh the homepage and should see your updated content.

Previews

In a later article we will talk about how to setup Previews. So in the future, this process of testing new content will be much easier.

Next steps

Next up we will be replacing the rest of the homepage with Prismic content using Slices.

Converting the Homepage main content (slices) →