Skip to content

Personalize Images on Landing Page Using Next.js

Personalization involves tailoring an experience, service, or product to cater to individuals or groups of individuals’ needs. With more than four billion internet users worldwide, it is now paramount for developers and business owners to build a robust and flexible digital product that accommodates the diverse range of target demographics and improves overall customer satisfaction.

This post demonstrates how to personalize images on an event landing page in a Next.js application using Cloudinary and Uniform.

Cloudinary is a visual media service we use to upload, store, manage, transform, and deliver images and videos for websites and applications.

Uniform is a digital experience composition platform that supports the composition, delivery, and management of building blocks required to create an application. It allows developers to seamlessly adapt and manage Jamstack technologies like headless content management systems, commerce APIs, and CDNs and deliver it as a single source of truth instead of making multiple API requests.

We completed this project in a CodeSandbox. Fork it to quickly get started.

The source code is also available on GitHub.

To fully grasp the concepts presented in this tutorial, the following requirements apply:

  • Basic understanding of JavaScript and React
  • Cloudinary account (create an account here)
  • Uniform account (create an account here)

In this post, we will focus on implementations only. The project UI has already been set up.

To get started, we need to clone the project by navigating to the desired directory and running the command below:

git clone https://github.com/Mr-Malomz/uniform-dynamic-landing.git && cd uniform-dynamic-landing
Code language: PHP (php)

First, we need to install the project dependencies by running the command below:

npm i 

Then, run the project using the command below:

npm run dev

Running App with Sample Data

With our application up and running, we need to upload sample images for our landing page personalization.

Sample images

In our Cloudinary dashboard, we uploaded the image by clicking on the Media Library tab, clicking on Upload, selecting the Web Address option, inputting the URL, and finally clicking on the Arrow Button to upload.

Cloudinary Console and Upload Dutton for Other Formats of Upload

Select Web Address and Enter URL

After uploading the images, we will see them displayed on the console.

Uploaded Images

With our images uploaded, we need to create a personalized digital experience using Uniform. To do this, we must sign up and fill in the required information.

Next, input personalized_landing_page as the project name and click Continue.

Note: Uniform automatically creates a sample project for new users. We might need to delete the project, as the free plan allows the creation of just a single project.

Next, navigate to the Security tab, select the API Keys, and click on the rounded Plus Icon to create one. Input landing_page as the API name, click on Add to Project, mark all the permissions, and click on Set Permissions. Then click on the Create API Key to create the API key.

Create API Key Input Details Set Permissions

With this done, we should see a screen containing our API Key and Project ID.

Before we close the modal, we need to create an .env file in the root directory of our application and add the snippet below:

UNIFORM_API_KEY=/API KEY GOES HERE/
UNIFORM_PROJECT_ID=/PROJECT ID GOES/
Code language: JavaScript (javascript)

Understanding some Uniform terminology

Before we model our project on Uniform and personalize our application, we must understand the features we will be leveraging to achieve this.

  • Components in a Uniform application work similarly to those in a React application; it lets us break our application into smaller reusable building blocks with properties
  • Composition is the combination of one or more components
  • Personalization in Uniform is used for tailoring experience
  • Signal is like a trigger that Uniform and our frontend application will track and respond to

For our project, we will create an image component.

Title and image components

Add Cloudinary integration support

Uniform improves the product’s digital experience through integration with an existing system. To connect Cloudinary to our project, we need to navigate to the Projects tab, click on the project, and click on any of the highlighted sections to add integrations to our project.

Click on the Project Add Integration

Search or browse through the available integrations, select the Cloudinary integration, click on the Add to project button, input the Cloudname, API Key and Save.

Select BigCommerce Add Integration Add Cloudname & API Key

We can get our Cloud Name and API Key from our Cloudinary dashboard.

Cloudinary Details

Add Signal

As earlier mentioned, a Signal is a trigger that Uniform and our frontend application will track and respond to. In our case, personalized developer content should show whenever a user views the developer page and returns to the landing page. To do this, we need to navigate to the Personalization menu, click on the Signal tab and click on Plus Icon.

Create signal

Input Developer page view as name and click on the + SEE MORE CRITERIA OPTIONS button.

Click on the Current Page button, input /developer as the Match, and click on the Save and Close button.

Click on the current page button Input match

Create Components and Composition

To get started, navigate to the Canvas tab, select the Component Library, and click on the Plus Icon.

Create Component

Input Image as the component name, and then change the Component Icon to an image.

Create component

Parameter Name Help Text Type
img hero image Cloudinary

Next, add properties of img as shown above, and then click on OK.

Component Properties Added Property

Then click on the Save and Close button.

Now that we have created the Image Component, it will serve as a blueprint / building block for creating our event landing page.

With that done, we can leverage the Image blueprint component to create our event landing page component. To get started, click on the Plus Icon, input LandingPage as the component name, check the Composition Component, navigate to the Slots section, and click on the Plus Icon to create a slot.

Create landingPage

Input Event as the Slot Name, 0 as the Minimum, 2 as the Maximum (the default section and the developer section), select the Image and Personalization as the allowed components, and click OK.

Create composition with slot

Then click on the Save and Close button.

With that done, we can start using the LandingPage component to compose our event landing page. To do this, navigate to the Composition tab, and click on the Plus Icon to create a composition.

Create composition

Select the LandingPage as the composition type, input Landingpage as the name, and Create.

Input events as the slug and click on the Plus Icon to add a component to map out a new component.

slug

PS: The slug inputted will come in handy when searching for our composition.

Select the Image and add the corresponding image for the developer hero section.

select Image component add image from cloudinary images from cloudinary

Next, we need to click on the Personalize This button, click on the Add Criteria button, and Select the Developer page view Signal we created earlier.

add personalization click on the Add Criteria button select signal

We must repeat the same step for the default page by selecting a marketter image from Cloudinary without adding personalization.

Hover on the image and click on the plus icon to add a new image marketter image

Finally, we need to click on the Personalization menu, input Personalized Event Page, and click the Save and publish button.

click Personalization save and publish

Navigate back using the < Compositions button and click the Publish button. This makes our composition available to third-party applications.

Publish changes

First, we need to install the required dependencies by running the command below:

npm install @uniformdev/context @uniformdev/context-react @uniformdev/canvas-react @uniformdev/canvas-cloudinary @uniformdev/canvas

As part of the installation process, we also need to install Uniform CLI, a dependency required to generate the Uniform context manifest. The manifest contains instructions on how to classify users using our application. To do this, run the command below on a terminal:

npm install -D @uniformdev/cli
Code language: CSS (css)

Configure Next.js to download Manifest

Next, we need to modify the script section of the package.json file as shown below:

{
  "name": "uniform-dynamic-page",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "npm run download:manifest && next dev",
    "build": "npm run download:manifest && next build",
    "download:manifest": "uniform context manifest download --output ./contextManifest.json",
    "start": "next start",
    "lint": "next lint"
  },
//remaining section goes here
}
Code language: JSON / JSON with Comments (json)

With that done, we can run the command below on a terminal to download the manifest.

npm run download:manifest
Code language: CSS (css)

We should see a contextManifest.json file in the root directory.

Configure Next.js with Uniform

First, we need to modify the _app.js file by adding the manifest as a global context, as shown below:

import '../styles/globals.css';
import { UniformContext } from '@uniformdev/context-react';
import { Context, enableContextDevTools } from '@uniformdev/context';

import manifest from '../contextManifest.json';

const context = new Context({
  manifest,
  defaultConsent: true,
  plugins: [enableContextDevTools()],
});

function MyApp({ Component, pageProps }) {
  return (
    <UniformContext context={context}>
      <Component {...pageProps} />
    </UniformContext>
  );
}
export default MyApp;
Code language: JavaScript (javascript)

The snippet above does the following:

  • Imports the required dependencies
  • Creates a context using the manifest and enables the Uniform dev tool
  • Wraps the application with context using the UniformContext component

Secondly, we need to create a rule that our application will use when personalizing content based on visited pages. To do this, create a content/content.json file in the root directory and add the snippet below:


[
    {
      "id": "personalized-for-developer",
      "url": "/developer",
      "fields": {
        "title": "Home",
        "description": "You triggered the developer signal"
      },
      "pz": {
        "crit": [
          {
            "l": "developerPageView",
            "op": ">",
            "r": 0
          }
        ]
      }
    },
    {
      "id": "default",
      "url": "/",
      "type": "Home",
      "fields": {
        "title": "Home",
        "description": "As you navigate around, content will change."
      }
    }
]
Code language: JSON / JSON with Comments (json)

The snippet above does the following:

  • Creates a rule that triggers the developerPageView Signal whenever the developer page is visited and triggers personalization on the homepage
  • Creates a default rule to show default content

Getting composable data from Uniform and Adding Personalization

To do this, we need to modify the index.js file inside the pages folder as shown below:

import Head from 'next/head';
import { Header } from '../components/header';
import {
  createCloudinaryEnhancer,
  CLOUDINARY_PARAMETER_TYPES,
} from '@uniformdev/canvas-cloudinary';
import { CanvasClient, EnhancerBuilder, enhance } from '@uniformdev/canvas';
import { Composition, Slot } from '@uniformdev/canvas-react';
import { Personalize } from '@uniformdev/context-react';
import content from '../content/content.json';

async function enhancer(composition) {
  const enhancedComposition = { ...composition };
  //enhancing with Cloudinary
  const enhancers = new EnhancerBuilder().parameterType(
    CLOUDINARY_PARAMETER_TYPES,
    createCloudinaryEnhancer()
  );

  await enhance({ composition: enhancedComposition, enhancers, context: {} });
  return enhancedComposition;
}

export async function getStaticProps() {
  //fetching data from uniform
  const client = new CanvasClient({
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
  });

  const { composition } = await client.getCompositionBySlug({
    slug: 'events',
  });

  //using cloudinary enhnacer on the comoposition
  await enhancer(composition);

  return {
    props: {
      composition,
    },
  };
}

export default function Home({ composition }) {
  return (
    <div>
      <Head>
        <title>Event Landing Page</title>
        <meta name='description' content='Event Landing Page in Nextjs' />
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <main>
        <Header />
        <section className='flex h-[500px]'>
          <div className='w-1/2 bg-[#d8dbe2] h-full flex justify-center items-center'>
            <h1 className='text-4xl px-4 lg:px-5 font-medium'>
              {' '}
              Welcome to our event; we cater for your need
              <span className='text-[#292961]'> accordingly</span>
            </h1>
          </div>
          <Personalize
            variations={content}
            name='eventLandingPersonalized'
            component={() => (
              <Composition
                data={composition}
                resolveRenderer={() => {
                  const DefaultComponent = ({ img }) => {
                    return (
                      <div className='w-full h-full'>
                        <img
                          alt='hero'
                          src={img[0].baseurl}
                          className='h-full w-full object-fit'
                        />
                      </div>
                    );
                  };
                  return DefaultComponent;
                }}
              >
                <Slot name='event' />
              </Composition>
            )}
          />
        </section>
      </main>
    </div>
  );
}
Code language: JavaScript (javascript)

The snippet above does the following:

  • Imports the required dependencies
  • Creates an enhancer helper function to enhance the Cloudinary-based composition returned from Uniform
  • Gets data from Uniform using the getStaticProps function. The function also does the following:
    • Creates a CanvasClient instance using the API key and Project ID we saved earlier.
    • Uses the instance to get composition by passing in the events (we configured this on the Uniform platform) as a slug.
    • Uses the Cloudinary helper function to enhance the data returned by the composition.
  • Line 63 – 87: Uses the Personalize component to activate personalization by passing in the content rule, a unique name eventLandingPersonalized, and uses the Composition component to render the personalized image

With that done, we can restart our development server using the command below:

npm run dev

We can also validate our personalization by navigating between the homepage and the developer page.

This post discussed how to personalize images on an event landing page using Cloudinary and Uniform. With Uniform, we can improve our digital experience, personalize our data, and improve application performance with only a single API call.

These resources might also be helpful:

Back to top

Featured Post