How to add dynamic and customizable banners to a Next.js app

One of the ways to promote new products or to tell customers about a new sale is to display a banner on your website’s page with this information. This article will cover how to add three types of banners to the application built with Next.js. These types are defined by their position on the page: center, bottom, and top. To make the banners dynamic the content and the customization for them could be fetched from a CMS. In my case it’s ButterCMS but it could be any other CMS of your choice.

These are the screenshots of how the banner could look like in the end:

Centered banner
Top banner
Bottom banner

The demo could be found here.

Banner configuration

The resulting banners are going to be pretty simple but with the help of CMS, it could be as complex as you’d like. The banner will have these elements:

  • headline
  • text message
  • call to action button or link
  • button to hide the banner

To allow flexible customization for the banners, the CMS should contain these data:

  • headline
  • text — should support HTML tags
  • button label text
  • button link
  • button background color
  • banner width — customization for centered banner
  • banner max width — customization for centered banner
  • banner height
  • banner max height
  • banner background color
  • banner type or position — center, top, bottom

The configuration for the banner in ButterCMS could be viewed here.

How could we define which pages have which banner? If the page content is already a part of CMS then we could just add a property to the page that would be a reference to any of the created banners in the CMS. Another possible solution could be to fetch a specific banner by its property (i.e. add a unique name to banner configuration).

Most of the banners’ styling is going to be developed with tailwindcss.


We are going to create a smart component that would select which type of banner needs to be rendered on the page and three dumb components for each banner type.

Let’s create a component for the centered banner. Create a file center-banner.js with this content:

We are using dangerouslySetInnerHTML for banner text since it could have some HTML tags. We added prose class to that div element. What does it do? It allows this HTML code from the CMS to be styled the same as other page elements. It is done by using the @tailwindcss/typography package. To install run this command:

npm @tailwindcss/typography

And then update the tailwind.config.js file:

module.exports = {    ...    plugins: [require("@tailwindcss/typography")],};

The banners usually have close buttons to hide the banner. In this component’s template clicking on the close button triggers closeButtonClicked function which is a prop from our smart component that we will create later.

To fit the banner content into mobile screens, we are going to make the banner full width and full height by adding this CSS code:

Since width, max-width, height and max-height are defined in the CMS we are using inline styles. So to override them in the styles file we use !important.

This banner could have some improvements. For example, the call to action button is going to be displayed even if the button label was not set in the CMS. The default values for banner sizes could also be better organized.

The component for the bottom banner is very similar. Create file bottom-banner.js:

The default values are different and the component has fewer props since this banner should have 100% width.

The component for the top banner is the same as for the bottom banner but it uses another class to position the banner at the top. Create a new file top-banner.js with this content:

To fit content on mobile for both of these banner types we use this CSS code:

Now it’s time to create the smart component. Create a new file banner.js. This component should take care of rendering the correct component for banner type and the logic of displaying/hiding the banner:

We use useState hook to display/hide the banner. Note that we set closeButtonClicked prop as closeButtonClicked={() => setDisplayBanner(false)} to hide the banner.

Now the banner could be displayed on the page by adding this element to the page template:

// banner is a variable with all banner configuration properties
<Banner banner={banner}></Banner>

Make sure that this element is displayed only if the banner exists. One possible solution for this is to create a new variable:

const hasBanner = banner && Object.keys(banner).length > 0

and to render the banner component this way:

{hasBanner && (    <Banner banner={banner}></Banner>)}


We have created a dynamic banner with customization. All of the content, the banner position, and the sizes could be defined in a CMS. To look at the integration of this banner component into the Next.js application with ButterCMS, look at this GitHub repository:

Full Stack Web Developer