Create a Homepage Banner

Welcome to the second article on the Prismic and Gatsby tutorial series. We'll be walking through the steps required to convert the content from the top homepage banner from hard-coded to use 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 plugins and dependencies.

Content modeling

The content modeling should be the first step to consider when converting a project to a headless CMS like Prismic.

Run npm start to re-launch your site and look at your homepage. There's a banner at the top of the page that we'll keep as a static top-level component. Let's review the fields used to build it:

Background

API ID: banner_background

An Image field.

Title

API ID: banner_title

A Rich Text field that only accepts <h1> elements for titles.

Description

API ID: banner_description

A Rich Text field that only accepts <p> elements for text.

Learn More Button

API ID:

banner_link

banner_link_label

A Link field for the clickthrough URL and a Rich Text field only accepts <p> elements for texts.

The model for this banner is already in your Prismic repository. Click on Custom Types, and select the Homepage type to see the content modeling of the banner.

Then, click the Documents button and select the Homepage to view the live version of the banner. It should look something like this:

⚠️ No need to modify the Custom Types

You do not need to change anything in the Custom Types of your repository. If you wish to change anything, we highly recommend you wait until the end of this step-by-step tutorial and read the dedicated plugin configuration article.

Now that we understand the model let's retrieve your content from Prismic.

1. Test the query

Run the project with npm start. Open the GraphQL Playground at http://localhost:8000/__graphql and paste this GraphQL query:

Copy
query Homepage {
  prismicHomepage {
    data {
      banner_title {
        text
      }
      banner_description {
        text
      }
      banner_link {
        url
        type
        uid
      }
      banner_link_label {
        text
      }
      banner_background {
        url
      }
    }
  }
}

Run the query by pressing the "play" button ▷ at the top to see the query results on the right.

2. Render the results

Let's now render the results to create the homepage banner.

1. Update the index.js file

Here we query the homepage document and pass the results to the <HomepageBanner /> component as props. Open the file at /src/pages/index.js and paste the following code.

Copy
// index.js file

import * as 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 HomeTemplate = ({ data }) => {
  if (!data) return null
  const doc = data.prismicHomepage.data

  return (
    <Layout isHomepage>
      <Seo title="Home" />
      <HomepageBanner
        title={doc.banner_title.text}
        description={doc.banner_description.text}
        linkUrl={doc.banner_link.url}
        linkLabel={doc.banner_link_label.text}
        backgroundUrl={doc.banner_background.url}
      />
      <MainContent />
    </Layout>
  )
}

export const query = graphql`
  query Homepage {
    prismicHomepage {
      data {
        banner_title {
          text
        }
        banner_description {
          text
        }
        banner_link {
          url
          type
          uid
        }
        banner_link_label {
          text
        }
        banner_background {
          url
        }
      }
    }
  }
`

export default HomeTemplate

2. Update the homepage banner

Open your src/components/HomepageBanner.js file. To retrieve the props that we passed in the index.js file, replace the static content with the following code:

Copy
// HomepageBanner.js file

import * as React from 'react'
import { PrismicLink } from '@prismicio/react'

export const HomepageBanner = ({
  title,
  description,
  linkUrl,
  linkLabel,
  backgroundUrl,
}) => (
  <section
    className="homepage-banner"
    style={{
      backgroundImage: `linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${backgroundUrl})`,
    }}
  >
    <div className="banner-content container">
      <h2 className="banner-title">{title}</h2>
      <p className="banner-description">{description}</p>
      <PrismicLink href={linkUrl} className="banner-button">
        {linkLabel}
      </PrismicLink>
    </div>
  </section>
)

We're now populating the homepage banner with our Prismic content.

Some of you might have noticed that we no longer use the hard-coded Link path: /about. Link fields are now processed using the PrismicLink component from @prismicio/react and the resolved url field provided from the query.

Now let's build a Link Resolver and add it to our plugin configuration to make our links work.

3. Add helper functions

Link Resolver

The Link Resolver is a function that takes in a Prismic document object or Link field and returns the corresponding URL for that page in your site. For example, If a document type is "page" with a UID of "about" it will generate the URL path: /about. If the document type is other than "page, " it will return the root "/" URL without the UID.

Create a file such as 〜/src/LinkResolver.js and add the following code:

Copy
// LinkResolver.js file

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

  return '/'
}

If you're curious to learn more, check out the Link Resolving article.

Now register it with the plugin. Open the gatsby-config.js file and update the file to this:

Copy
// gatsby-config.js file

require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`,
})

module.exports = {
  siteMetadata: {
    title: 'Gatsby + Prismic Tutorial',
    description: 'Learn how to integrate Prismic into your Gatsby project.',
  },
  plugins: [
    {
      resolve: 'gatsby-source-prismic',
      options: {
        repositoryName: process.env.GATSBY_PRISMIC_REPO_NAME,
        linkResolver: require('./src/LinkResolver').linkResolver,
        schemas: {
          homepage: require('./custom_types/homepage.json'),
          navigation: require('./custom_types/navigation.json'),
          page: require('./custom_types/page.json'),
        },
      },
    },
    'gatsby-plugin-image',
    'gatsby-plugin-react-helmet',
    {
      resolve: 'gatsby-plugin-manifest',
      options: {
        icon: 'src/images/favicon.png',
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'images',
        path: `${__dirname}/src/images`,
      },
    },
    {
      resolve: 'gatsby-plugin-google-fonts',
      options: {
        fonts: [`Lato\:400,400,700,700i,900`, `Amiri\:400,400,700,700i`],
      },
    },
  ],
}

Resolve internal links

We need to configure <PrismicLink> to use Gatsby's <Link>. Let's add a PrismicProvider component for handling internal links.

Create two files at the root of your project: gatsby-browser.js and gatsby-ssr.js, and paste the following code in both.

Copy
import * as React from 'react'
import { Link } from 'gatsby'
import { PrismicProvider } from '@prismicio/react'

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

export const wrapRootElement = ({ element }) => (
  <PrismicProvider
    internalLinkComponent={({ href, ...props }) => (
      <Link to={href} {...props} />
    )}
  >
    {element}
  </PrismicProvider>
)

Congrats, now the content for the homepage banner comes from Prismic!

4. Test the new content

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. Stop the current Gatsby server in your terminal 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 see your updated content.

Next steps

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


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Spot an error in the documentation? Get in touch with us on our Community Forum or using the feedback form above.