Create a Homepage Banner

Beta

These docs rely on Slice Machine, which is in active development and subject to change. Content Relationships are not currently supported with Slices.

This article will explore the concept of breaking a website in to blocks, by the end you learn how to recreate them as components and test them locally.



1. Break the Design into Pieces

As we will recreate our homepage design as components, we will want to break the page into blocks. We can think of the parts of our website as easily reusable building blocks, with which we can create highly flexible pages.

So if we imagine that the banner at the top of our page is a block that lives on its own, we can begin to imagine what that block is made of. This is pretty straightforward. We will need the following fields:

description

link

Ā Link field, for the clickthrough URL

linkLabel

Key Text field, for the button text

background

Here's a video to further show this:


2. Create a Component

Now that we know what fields are needed to build our banner, we will want to begin the development process. The first step in this process is to generate a component & Slice (Content Model) template which we'll build on top of.

Wait, what's a Slice?

Basically, a 'Slice' is the name that we give the content model that will be used to inject content in to your component.

Create Slice Command

To generate a component & Slice (Content Model), we run theĀ 'Create Slice'Ā command.

Copy
prismic sm --create-slice

šŸ’” What does this Command do?

The --create-slice command will create the template files for a new component, content model (Slice), the mock data, and Storybook. It also adds a default @/slices path to your sm.json file. This will give you the power to develop your entire component library locally.

Here's an example of what running the command looks like. We select the @/slices local library (or create it if it doesn't exist), then we give it a name made of 2 PascalCased words. I'll call mine BannerSlice:

Running the prismic sm --create-slice command in the terminal
Running the prismic sm --create-slice command in the terminal

Component Naming

You can name your component anything that you wish as long as it's PascalCased words, there's no need to include anything special like 'Slice', 'Component', or anything else. It's up to you :)


3. Create a Slice for your Component

The next step will be to create the content model (Slice) for our component using the previously listed fields. To do this we will need to open the Slice Builder!

šŸ’” What is the Slice Builder?

A visual builder for your Slice Models with all the tools you need to generate data models and mock CMS content locally. This tool includes suggested code snippets & options for customising your mock data output.

Launch the Slice Builder

To open the Slice builder by running the following command:

Copy
prismic sm --develop

Add your Fields to the Slice

Once you run the above command, the Slice Builder will be running onĀ http://localhost:9999. When you visit the link, you will be greeted by a visual representation of the component we just created (BannerSlice). Next, click through to the build screen for our newly created Slice (content model), so we can begin to add our fields. Which if you remember, are:

description

link

Link field, for the clickthrough URL

linkLabel

Key Text field, for the button text

background

Use the visual builder to add and name the fields. The 'name' you give these fields are API IDs to reference the fields. You can click the gear icon āš™ļø if you want to edit any of these fields' settings. Thanks to the template created by the --create-slice command previously, 2 of these fields, Title & Description, have already been added.

šŸ’” What's an API ID?

The fields' API ID is the ID corresponding to the data that will come from the content API (Prismic). But, this field will correspond to the mock data that we will generate for developing our component locally when using the Slice Builder.

Then clickĀ 'Save model to filesystem'. This will update theĀ model.jsonĀ file with the fields that will represent our content and theĀ mock.jsonĀ file containing the mock data that we will use to develop our component. You'll see more about that next.

Customize Mock Data (Optional)

You may want to quickly customize the structure of the mock data that is generated for each of the fields to make it closer to what your actual content will look like. For example, if you want more or less text for a Rich Text field, then you can go to the settings of each field and select the 'Mock Config' Tab. You can then edit the mock data as you see fit.

Remember to click 'Save model to filesystem' after editing these settings so that the mock.json file is updated.


4. Update Component Code

Now we can add the corresponding code to our component file (~/slices/BannerSlice/index.js) for the fields that we just added.

Using Suggested Code Snippets

You can see the recommended code snippets for your framework with API IDs included by clicking theĀ 'Show code snippets'Ā checkbox. Click theĀ 'Copy code'Ā button on the suggested code snippets in the Slice Builder, then in your code editor of choice, navigate to and open your component file, in my caseĀ ~/slices/BannerSlice/index.js. Finally, paste this code into yourĀ index.jsĀ file. You can see where to paste these code snippets in the code example below.

Custom Changes

A couple of differences from the suggested code snippets will be for the background image and the banner title.

For the title, we'll use theĀ asTextĀ method to make sure it's outputting the title as aĀ <h1>, this asText method allows us to remove formatting and take control of the styling. Next, we'll move to the styling and we'll preview how our component will look locally as we create our CSS.

For the background image, we will take theĀ API IDĀ from that field and add it to theĀ <section>Ā block's styling, we'll discuss this more below.

We've also added some CSS classes to the HTML tags for styling using the className attribute.

Full Suggested Code

Below you can see the full code for the fields that we should add:

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

const BannerSlice = ({ slice }) => (
  <section className="homepage-banner">
    <div className="banner-content container">
      <h2 className="banner-title">{RichText.asText(slice.primary.title)}</h2>
      <div className="banner-description">
        <RichText render={slice.primary.description} />
      </div>
      <a href={Link.url(slice.primary.link)}>
        { slice.primary.linkLabel }
      </a>
    </div>
  </section>
)

export default BannerSlice

5. Preview Locally & Style Component

To do our styling we'll launch our Local Component Dev Environment so that we can see live updates for the changes to our code.

Launch the Local Component Dev Environment

Our Dev Tools come with a built-in local development environment. This tool will put together your component code, Slice model, and mock data to allow you to develop your component in isolation without the need to add data to your Prismic repository.

If it isn't launched yet, open a new terminal window and run the following command:

  • npm
  • Yarn
Copy
npm run storybook
Copy
yarn run storybook

Once you launch it will be automatically prompted to a new browser tab onĀ http://localhost:8888.

What's Storybook?

To learn more about this powerful tool and what else you can do with it, visit our full documentation:

Storybook Docs

Component Level CSS

For this tutorial, we're going to use JSX to have control over the scoped styles of each Model. Next.js comes bundled styled-jsx to provide support for isolated scoped CSS. You can read more about this and it's other supported CSS methods, including CSS modules, here.

Full CSS + Full Component Code

Like we spoke about in the code snippets step we're going to add the background image from the API into the CSS using Styled-JSX. First, you can see below that we open a normal <style> tag but add the jsx attribute and place and curly bracket and backtick {` before we enter the standard CSS.

Then inside a normal class selector for the homepage-banner we define the background property and pass the background image URL to the URL CSS function using temporal literates, background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${ slice.primary.background.url }); this is highlighted below.

Below you'll also find a tab for the full component code:

  • styled-jsx
  • Full Component Code (index.js)
Copy
<style jsx>{`
  .homepage-banner {
    font-family: 'Lato', sans-serif;
    margin: 0 0 80px 0;
    padding: 6em 0 6em;
    background-position: center center;
    background-size: cover;
    color: #ffffff;
    line-height: 1.75;
    text-align: center;
    background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${ slice.primary.background.url });
  }
  .banner-content {
    text-align: center;
  }
  .banner-title {
    width: 90%;
    max-width: 490px;
    margin-left: auto;
    margin-right: auto;
    color: #ffffff;
    font-size: 70px;
    font-weight: 900;
    line-height: 70px;
  }
  .banner-description {
    width: 90%;
    max-width: 490px;
    margin-left: auto;
    margin-right: auto;
  }
  a {
    background: #ffffff;
    border-radius: 7px;
    color: #484d52;
    font-size: 14px;
    font-weight: 700;
    padding: 15px 40px;
  }
  a:hover {
    background: #c8c9cb;
  }
  @media (max-width: 767px) {
    .homepage-banner {
      margin: 0 0 40px;
      padding: 10em 0 6em;
    }
    .banner-title {
      font-size: 50px;
      line-height: 50px;
    }
  }
`}</style>
Copy
import React from 'react'
import { RichText } from 'prismic-reactjs'
import { Link } from 'prismic-reactjs'

const BannerSlice = ({ slice }) => (
  <section className="homepage-banner">
    <div className="banner-content container">
      <h2 className="banner-title">{RichText.asText(slice.primary.title)}</h2>
      <div className="banner-description">
        <RichText render={slice.primary.description} />
      </div>
      <a href={Link.url(slice.primary.link)}>
        { slice.primary.linkLabel }
      </a>
    </div>
    <style jsx>{`
      .homepage-banner {
        font-family: 'Lato', sans-serif;
        margin: -70px 0 80px;
        padding: 6em 0 6em;
        background-position: center center;
        background-size: cover;
        color: #ffffff;
        line-height: 1.75;
        text-align: center;
        background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.6)), url(${ slice.primary.background.url });
      }
      .banner-content {
        text-align: center;
      }
      .banner-title {
        width: 90%;
        max-width: 490px;
        margin-left: auto;
        margin-right: auto;
        color: #ffffff;
        font-size: 70px;
        font-weight: 900;
        line-height: 70px;
      }
      .banner-description {
        width: 90%;
        max-width: 490px;
        margin-left: auto;
        margin-right: auto;
      }
      a {
        background: #ffffff;
        border-radius: 7px;
        color: #484d52;
        font-size: 14px;
        font-weight: 700;
        padding: 15px 40px;
      }
      a:hover {
        background: #c8c9cb;
      }
      @media (max-width: 767px) {
        .homepage-banner {
          margin: 0 0 40px;
          padding: 10em 0 6em;
        }
        .banner-title {
          font-size: 50px;
          line-height: 50px;
        }
      }
    `}</style>
  </section>
)

export default BannerSlice

Save and preview your changes in the Local Component Development Environment, http://localhost:8888.

6. Push Slice to Prismic

Finally, jump back over to the Slice Builder, update your screenshot, which will be used as a preview for your content writers to choose Slices, and Push Slice to Prismic.

Congratulations you've just built your first component! Now let's do the rest.


Next and Previous articles


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.