# Uniform conference tutorial (Next.js)

> This developer tutorial guides you through the process of adding Uniform functionality to web applications powered by Contentful.

Source: https://docs.uniform.app/docs/integrations/content/contentful/uniform-in-contentful/uniformconf-nextjs-tutorial

This tutorial guides you through adding
personalization to the UniformConf site built using Next.js.
By the end of this tutorial you will have a
personalized Next.js application with content and
personalization configured by content authors in
Contentful using the Uniform app from the Contentful
marketplace:

- Content authors can assign enrichments to entries to
  identify the visitor's interests.
- Content authors can define the conditions that must be met in
  order for each hero component to be displayed on the home page.
- When the visitor's interests are identified, the home page
  displays personalized content.

## Prerequisites

Before you get started, be sure you have the following:

You must have access to a Uniform team with the ability to create new projects. If you are an active customer or a partner, please get in touch with your Uniform team administrator colleague and ask for an invite.

If you are not sure or your company does not have a Uniform team, you can request a sandbox [here](https://uniform.dev/try?utm_source=docs).

1. **Administrator access to Contentful** - to import content and add the Uniform app to your Contentful space.
2. **Administrator access to Uniform** - to configure the
   personalization settings that are available in Contentful.
3. **[Node.js](https://nodejs.dev) (version 14 or greater)** - installed on your machine to work with the Next.js app.
4. **Uniform Context browser extension** - to facilitate development and
   testing personalization on the Next.js app. You can get the extension
   [here](https://chrome.google.com/webstore/detail/uniform-context/dcmlokofjljnfjcknpmhjocogllfbhkg).
   This isn't required to use Uniform Context, but it makes development
   and testing much easier.

## Create Uniform project

In Uniform, a project is the basic unit of organization. A project
is where you will define the criteria you want to use to configure
personalization.

1. Log into Uniform.
2. On the Projects page, click **(+)** to create a new project.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-add-project.png)
3. Enter the following for the project name:

   ```
   UniformConf for Contentful
   ```
4. Scroll down and click **Empty project**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-empty-project.png)
5. Click **Continue**.
6. Your project is created and you are taken to the project home page.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-project-home-page.png)

## Configure Contentful

### Load sample content into Contentful

1. In Contentful, create a [content management token](https://www.contentful.com/developers/docs/references/authentication/#getting-a-personal-access-token).

   > **About this step:**
   >
   > This token is needed to load data into your Contentful space.
   > Note this value because you will need to add it to your `.env` file later.
2. In Contentful, create a [content delivery access token](https://www.contentful.com/developers/docs/references/authentication/#api-keys-in-the-contentful-web-app).

   > **About this step:**
   >
   > This access token is needed to read content from your Contentful space.
   > Note this value because you will need to add it to your `.env` file later.
3. Clone the following repository:

   ```
   https://github.com/uniformdev/uniform-docs-examples
   ```
4. Check out the following branch:

   ```
   apps/contentful/nextjs/no-uniform
   ```
5. Add the following file:

   ```shell
   NEXT_PUBLIC_CONTENTFUL_SPACE_ID=<YOUR CF SPACE ID>
   NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN=<YOUR CF CONTENT DELIVERY ACCESS TOKEN>
   CONTENTFUL_MANAGEMENT_TOKEN=<YOUR CF MANAGEMENT TOKEN>
   ```
6. Open a terminal in the root of the repository.
7. Enter the following commands:

   ```
   npm install
   npm run cf:import
   ```
8. In Contentful, confirm you have a entries in the content model, content, and media sections.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-content-model-loaded.png)

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-content-loaded.png)

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-media-loaded.png)

   > **About this step:**
   >
   > You might notice there are two hero content types: _Enriched Hero_
   > and _Personalized Hero_. There is nothing special about
   > these content types - yet. You will assign [enrichment tags](../uniform-in-contentful#enrichment-tagging)
   > to the former and [personalization criteria](../uniform-in-contentful#personalization-criteria) to the latter.

### Install Marketplace app

You must install and configure the Uniform app from the Contentful Marketplace to your space.

1. Install the [Marketplace app](../uniform-in-contentful).

   > **Info:**
   >
   > Be sure to note the Uniform API key you create. You will need this value in a later step.

## Configure space

Now you need to add classification and personalization settings
to Contentful. This involves the following:

- Add enrichment tagging to the content type Enriched Hero.
- Assign enrichment tags to Enriched Hero content entries.
- Add personalization criteria to the content type Personalized Hero.
- Assign personalization criteria to Personalized Hero content entries.
- Create a content type to define a list of Personalized Hero entries.
- Configure a content entry for the list of Personalized Hero entries for the home page.

> **Tip:**
>
> If you prefer to get Contentful configured
> and import the finished configuration into your Contentful
> space, you can skip to the [finished configuration](#finished-configuration)
> section.

### Configure Enriched Hero entries

Uniform personalization depends on the Uniform tracker. This
is a client-side component that captures visitor activity.
When the visitor views a page with an enriched hero, you
want the Uniform tracker to keep track of the persona associated
with the hero. This enables you to understand the personas the
visitor's activity matches.

1. In Contentful, navigate to **Apps > Manage apps**.
2. Open the Uniform app.
3. In the **ENRICHMENT TAGGING** section, from the dropdown select **Enriched Hero**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-app-enrichment-tags-selected.png)

   > **About this step:**
   >
   > This adds a new field to the content type _Enriched Hero_.
4. Click **Save**.
5. Open the content type **Enriched Hero**. Notice the field **Enrichment Tags**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-content-type-enriched-hero-updated.png)
6. Open the entry **Marketer Content**.
7. Scroll down to the field **Enrichment Tags**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-field-no-enrichments-defined.png)
8. Click on the word **here** to open a new tab with the Uniform Enrichments page.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-no-enrichments.png)
9. Click **(+)** to create a new enrichment.
10. Enter the following values:

    - **Name**: `Persona`
    - **Public ID**: `1`

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-add-enrichment.png)
11. Click **Save**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-enrichment-added.png)
12. Click **Add value**.
13. Enter the following values:

    - **Name**: `Marketer`
    - **Public ID**: `1`

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-add-enrichment-value-marketer.png)
14. Click **Save**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-marketer-value-added.png)
15. In Contentful, refresh the entry page.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/field-tags-no-enrichments-selected.png)
16. Click on the word **here**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/field-tags-enrichment-select.png)
17. Click **Select > Enrichment: Marketer**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/field-tags-enrichment-marketer-selected.png)
18. Click **Add**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/field-tags-enrichment-marketer-added.png)
19. Click **Publish**.
20. In Uniform, add another value to the enrichment **Persona**:

    - **Name**: `Developer`
    - **Public ID**: `2`

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-developer-value-added.png)
21. Click **Publish**.

    > **About this step:**
    >
    > When settings are configured under personalization, they're not
    > available to be used in an application until they're published.
22. In Contentful, set the value on the field **Enrichment Tags** on the following **Enriched Hero** entries:

    | Title | Enrichment Tags |
    | --- | --- |
    | Developer Content | Enrichment: Developer |
23. Publish the entries.

### Configure Personalized Hero entries

Personalized Hero entries provide the personalized content that
will be displayed on the home page. The specific entry that's
used when a visitor views the home page depends on the visitor's
activity.

1. In Uniform, navigate to **Optimization > Signals**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-no-signals.png)
2. Click the red **(+)** button.
3. Enter the following values:

   - **Name**: `Registered for Event`
   - **Public ID**: `registeredForEvent`

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-registered-signal-name.png)
4. Click **Cookie**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-registered-signal-criteria.png)
5. Enter the following values:

   - **Cookie Name**: `unfrmconf_registered`
   - **Comparison**: equals
   - **Match**: `true`

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-registered-signal-configured.png)
6. Click **Save and close**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-registered-signal-added.png)
7. In Uniform, add another signal using the following settings:

   - **Name**: `UniformConf Campaign`
   - **Public ID**: `uniformconfCampaign`
   - **Criteria**: Query String
   - **Query String Name**: `utm_campaign`
   - **Comparison**: equals
   - **Match**: `unfrmconf`

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-campaign-signal-added.png)
8. Click **Publish**.

   > **About this step:**
   >
   > When settings are configured under personalization, they're not
   > available to be used in an application until they're published.
9. In Contentful, navigate to **Apps > Manage apps**.
10. Open the Uniform app.
11. In the **PERSONALIZATION CRITERIA** section, from the dropdown select **Personalized Hero**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-app-personalization-criteria-selected.png)

    > **About this step:**
    >
    > This adds a new field to the content type _Personalized Hero_.
12. Click **Save**.
13. Open the content type **Personalized Hero**. Notice the field **Personalization Criteria**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-content-type-personalized-hero-updated.png)
14. Open the entry **Marketering Hero**.
15. Scroll down to the field **Personalization Criteria**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-field-no-criteria-defined.png)
16. Click **Add Criteria**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-field-criteria-selected.png)
17. Click **Select > Enrichment: Marketer**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-field-criteria-marketer-selected.png)

    > **About this step:**
    >
    > By default, the criteria is set to match when the enrichment
    > score is **greater than 0**. The enrichment score is set to
    > 50 when a page with the _Enriched Hero_ on it's viewed. This
    > means the criteria will match if the page is viewed at least
    > one time.
18. Click **Publish**.
19. Edit the following **Personalized Hero** entries:

    | Title | Personalization criteria |
    | --- | --- |
    | Call for papers open now! | Signal: UniformConf Campaign |
    | Can't wait to see you soon at UniformConf! | Signal: Registered for Event |
    | Developer Hero | Enrichment: Developer |
20. Publish the entries.

### Configure list of Personalized Heroes

You want to select the Personalized Hero entries that can appear
on the home page. This is done by creating a new entry that you
can use to select and order the heroes.

1. In Contentful, navigate to **Apps > Manage apps**.
2. Open the Uniform app.
3. In the **PERSONALIZATION LISTS** section, click **+ Create New**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-app-create-new-list.png)
4. Enter the following value and click **Confirm**:

   ```
   Personalized Hero List
   ```

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-app-create-list-added.png)
5. Click **Save**.
6. Navigate to **Content model**. Notice a new content type **Personalized Hero List**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-content-type-personalized-hero-list-created.png)
7. Add a new entry using the content type **Personalized Hero List**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-list-entry-created.png)
8. For the field **List Name**, enter the following:

   ```
   Home Page Heros
   ```
9. Click **Link existing entries**.
10. Filter the search by the content type **Personalized Hero** and select the following entries:

    - Call for papers open now!
    - Can't wait to see you soon at UniformConf!
    - Developer Hero
    - Marketer Hero
    - Welcome to UniformConf

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-list-entries-selected.png)
11. Click **Insert 5 entries**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-list-entries-added.png)
12. Drag the entries into the following order:

    1. Can't wait to see you soon at UniformConf!
    2. Call for papers open now!
    3. Developer Hero
    4. Marketer Hero
    5. Welcome to UniformConf

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-list-entries-sorted.png)

    > **About this step:**
    >
    > The order of the entries in the list is significant because
    > the personalization criteria is evaluated in order. The
    > first match is the entry that's displayed. This creates
    > a priority for the personalization instructions. This is
    > important because it's possible a visitor matches multiple
    > criteria. It also affects the way you should go about testing
    > that personalization works.
13. Click **Publish**.

### Finished configuration

This section guides you through the process of importing the
finished configuration into your Contentful space.

> **Tip:**
>
> If you followed the steps above, you can skip this section.

1. In Uniform, add the following permissions to your Uniform API key:

   ```
   Uniform Context > Enrichments > Create
   Uniform Context > Enrichments > Update
   Uniform Context > Signals > Create
   Uniform Context > Signals > Update
   ```

   > **Warning:**
   >
   > You should always assign the minimal permissions required
   > to meet your requirements. Since this you are going to
   > load configuration from a code repository into Uniform,
   > you need permissions to write to Uniform.
   >
   > For more details on permissions, see the [administrator guide](https://docs.uniform.app/docs/guides/roles-and-permissions).
2. Open a terminal in the root of the repository.
3. Enter the following command:

   ```
   npm run uniform:push
   ```

   > **About this step:**
   >
   > This imports the finished versions of the enrichments and signals.
4. In Uniform, navigate to **Optimization > Enrichments**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-developer-value-added.png)

   > **About this step:**
   >
   > You will see the _Persona_ enrichment with two values.
5. Navigate to **Signals**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/uniform-campaign-signal-added.png)

   > **About this step:**
   >
   > You will see two signals.
6. In the terminal, enter the following command:

   ```
   npm run cf:import-finished
   ```

   > **About this step:**
   >
   > This imports the finished versions of the content types,
   > content entries, and media.
7. In Contentful, open the content type **Enriched Hero**.
8. For the field **Enrichment Tags**, click **Settings**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-finished-tags-settings.png)
9. Click **Appearance**.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-finished-tags-appearance-default.png)
10. Click the Uniform logo.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/cf-finished-tags-appearance-uniform.png)
11. Click **Confirm**.
12. Click **Save** to save the changes to the content type.
13. Repeat these steps for the following content types:

    | Content type | Field |
    | --- | --- |
    | Personalized Hero | Personalization Criteria |
    | Personalized Hero List | List Items |

## Update Next.js app

Uniform is designed to require minimal Uniform-specific product
knowledge so developers can incorporate it into their apps as
easily as possible. This section guides you through the process
of adding personalization to the Next.js app.

> **Tip:**
>
> If you learn better by studying a fully implemented, working
> example, see the [finished code](#finished-code) section.

### Add Uniform environment variables

Add the following values to your `.env` file. You collected
these values when you created the Uniform API key:

| Uniform value | Environment variable |
| --- | --- |
| API Key | `UNIFORM_API_KEY` |
| Project ID | `UNIFORM_PROJECT_ID` |

> **About this step:**
>
> These environment variables are needed in order for the npm
> build script to communicate with Uniform.

### Download manifest

The Next.js application needs to have access to the personalization
settings from Uniform. Uniform can generate a manifest that contains
this information so you can use the settings in your application.

> **Tip:**
>
> In most cases, when using Uniform in an application that uses static
> site generation, you should generate the manifest before building
> the application. This ensures the latest manifest is available to
> the application.

1. Open a terminal in the root of the repository.
2. Enter the following command:

   ```
   npm install -D @uniformdev/cli
   npm install @uniformdev/context
   ```

   > **About this step:**
   >
   > This adds a reference to the package with the Uniform CLI,
   > which is a tool that enables you to interact with Uniform
   > from a command-line interface. It also adds a reference to
   > the package that includes a Uniform CLI extension for
   > interacting with Uniform Context from a CLI.
3. Add the following to `package.json`:

   ```json
   {
       "name": "contentful-uniformconf-nextjs",
       "description": "UniformConf for Contentful",
       "version": "0.1.0",
       "private": true,
       "scripts": {
       "cf:export": "node ./content/cf/export.cjs",
       "cf:import": "node ./content/cf/import.cjs",
       "start": "next start",
       "download:manifest": "uniform context manifest download --output ./contextManifest.json",
       "dev": "run-s download:manifest dev:next",
       "dev:next": "next dev",
       "build": "run-s download:manifest build:next",
       "build:next": "next build",
       "export": "next export",
       "ci:build": "next build && next export",
       "lint": "next lint"
       },
       "dependencies": {
   ...
   ```

   > **About this step:**
   >
   > This adds a new script that downloads the manifest from
   > Uniform, saves it to a file named `contextManifest.json`,
   > and incorporates it into the scripts that start and build
   > the application.
4. Add the following to your `.gitignore` file:

   ```
   # uniform
   contextManifest.json
   ```

   > **About this step:**
   >
   > This ensures the manifest file doesn't get added to your source code repository.

### Add Context to app

Adding Uniform Context to your application involves two primary
tasks. One is making the manifest available to the application.
This is required because it establishes the parameters for
tracking and personalization. Two is creating a "context" object
that's maintains state for Uniform Context within the app.

1. Open a terminal in the root of the repository.
2. Enter the following command:

   ```
   npm install @uniformdev/context-react cookie
   ```

   > **About this step:**
   >
   > This adds a reference to the package that enables you to add
   > Uniform Context into applications build using React.
3. Open the file `./pages/_app.jsx` in your text editor.
4. Add the following code:

   ```jsx
   import Navbar from "../components/Navbar";
   import Footer from "../components/Footer";
   import "../styles/style.css";
   import { 
       Context, 
   } from "@uniformdev/context";
   const context = new Context({
   });
   ...
   ```
5. Add the following code:

   ```jsx
   import Navbar from "../components/Navbar";
   import Footer from "../components/Footer";
   import "../styles/style.css";
   import { 
     Context, 
   } from "@uniformdev/context";
   import manifest from "../contextManifest.json";
   const context = new Context({
     manifest,
   });
   function MyApp({
     Component,
     pageProps,
   }) {
     return (
       <>
         <Navbar /%}
         <Component {...pageProps} /%}
         <Footer /%}
       <>
     );
   }
   export default MyApp;
   ```
6. Add the following code:

   ```jsx
   ...
   const context = new Context({
       defaultConsent: true,
       manifest,
   });
   ...
   ```
7. Add the following code:

   ```jsx
   import Navbar from "../components/Navbar";
   import Footer from "../components/Footer";
   import "../styles/style.css";
   import { 
       Context, 
   } from "@uniformdev/context";
   import { UniformContext } from "@uniformdev/context-react";
   import manifest from "../contextManifest.json";
   const context = new Context({
       defaultConsent: true,
       manifest,
   });
   function MyApp({
       Component,
       pageProps,
   }) {
       return (
       <UniformContext context={context}>
           <Navbar /%}
           <Component {...pageProps} /%}
           <Footer /%}
       </UniformContext>
       );
   }
   export default MyApp;
   ```
8. Add the following code:

   ```jsx
   import Navbar from "../components/Navbar";
   import Footer from "../components/Footer";
   import "../styles/style.css";
   import { 
     Context, 
     enableContextDevTools,
   } from "@uniformdev/context";
   import { UniformContext } from "@uniformdev/context-react";
   import manifest from "../contextManifest.json";
   const context = new Context({
     defaultConsent: true,
     manifest,
     plugins: [
       enableContextDevTools(),
     ],
   });
   function MyApp({
     Component,
     pageProps,
   }) {
     return (
       <UniformContext context={context}>
         <Navbar /%}
         <Component {...pageProps} /%}
         <Footer /%}
       </UniformContext>
     );
   }
   export default MyApp;
   ```

   > **About this step:**
   >
   > This enables the Uniform browser extension. Production sites
   > usually don't have this enabled, but it can be very helpful
   > during development and testing.

### Start app

1. In the terminal, enter the following command:

   ```
   npm run dev
   ```
2. Open a browser window to `http://localhost:3000` to view the UniformConf application.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-initial.png)
3. If you have the Chrome extension installed, you should see
   that the Uniform logo is now in full color (previously it was
   black and white). This means that Uniform Context was detected
   on the site.

   ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-initial-with-extension.png)

### Activate tracking

In Contentful you assigned enrichment tags to entries based on
the **Enriched Hero** content type. The Uniform tracker is able
to use these enrichment tags to track the visitor. The tracker
can do this automatically, as long as the enrichment tags are
included in the props for the page.

1. Open the file `./lib/cf/fetch.js` in your text editor.
2. Add the following code:

   ```jsx
   function getFields(entry) {
     const { fields } = entry;
     if (fields?.image) {
       fields.image = fields.image.fields.file.url;
     }
     if (!fields.id && entry.sys?.id) {
       fields.id = entry.sys?.id;
     }
     if (fields.unfrmOptEnrichmentTag) {
       fields.enrichments = fields.unfrmOptEnrichmentTag;
       delete fields.unfrmOptEnrichmentTag;
     }
     return fields;
   }
   ```
3. Open the file `./components/Hero.jsx` in your text editor.
4. Add the following code:

   ```jsx
   export const Hero = ({
     title,
     description,
     buttonText,
     image,
     buttonLinkSlug,
     enrichments,
   }) => {
   ```
5. Add the following code:

   ```jsx
   import Link from "next/link";
   import Splitter from "./Splitter";
   import { Track } from "@uniformdev/context-react";
   export const Hero = ({
     title,
     description,
     buttonText,
     image,
     buttonLinkSlug,
     enrichments,
   }) => {
     return (
       <Track behavior={enrichments}>
         <div className="pt-24">
           ...
         </div>
         <Splitter />
       </Track>
     );
   };
   ```
6. Open the file `./components/Navbar.jsx` in your text editor.
7. Add the following code:

   ```jsx
   import React, { useState, useEffect } from "react";
   import Link from "next/link";
   import { useRouter } from "next/router";
   import { useScrollPosition } from "@n8tb1t/use-scroll-position";
   import NavMenu from "./NavMenu";
   import Logo from "./Logo";
   import { useUniformContext } from "@uniformdev/context-react";
   ...
   const Nav = () => {
     const [submenuVisible, setSubmenuVisible] = useState(false);
     const [isScrolled, setScrolled] = useState(false);
     const { context } = useUniformContext();
     const router = useRouter();
     ...
   ```
8. Add the following code:

   ```jsx
   ...
           <ActionLink
             isScrolled={isScrolled}
             onClick={async () => {
                 setSubmenuVisible(false);
                 await context.forget(true);
                 document.cookie =
                   "unfrmconf_registered=; Path=/; samesite=lax; Expires=Thu, 01 Jan 1970 00:00:01 GMT;";
               }
             }
             label="Forget me"
             icon={<LockIcon /%}}
           />
   ...
   ```
9. In the terminal, enter the following command:

   ```
   npm install cookie
   ```
10. Open the file `./components/RegistrationForm.jsx` in your text editor.
11. Add the following code:

    ```jsx
    import { useUniformContext } from '@uniformdev/context-react';
    import React from 'react';
    import { useState } from 'react';
    import Splitter from './Splitter';

    export const RegisterForm = (fields) => {
      const [registered, setRegistered] = useState(
        typeof document !== 'undefined' ? !!document.cookie.match(/unfrmconf_registered/) : false
      );
      const { context } = useUniformContext();
      const onRegister = () => {
        document.cookie = 'unfrmconf_registered=true; path=/; samesite=lax';
        setRegistered(true);
      };
      ...
    ```
12. Add the following code:

    ```jsx
    import { useUniformContext } from '@uniformdev/context-react';
    import { parse } from 'cookie';
    import React from 'react';
    import { useState } from 'react';
    import Splitter from './Splitter';
    export const RegisterForm = (fields) => {
      const [registered, setRegistered] = useState(
        typeof document !== 'undefined' ? !!document.cookie.match(/unfrmconf_registered/) : false
      );
      const { context } = useUniformContext();
      const onRegister = () => {
        document.cookie = 'unfrmconf_registered=true; path=/; samesite=lax';
        context.update({
          cookies: parse(document.cookie)
        });
        setRegistered(true);
      };
    ...
    ```
13. Open a browser window to `http://localhost:3000/developers` to view a page with an enrichment tag assigned.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers.png)
14. Open the browser extension and navigate to **Dimensions**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers-extension-initial.png)

    > **About this step:**
    >
    > This shows that the tracker collected data, but it's not very
    > intuitive. It says that the dimension "1_2" has a score of "50."
    > The "1_2" is a combination of the public IDs for the enrichment
    > **Persona** and the enrichment value **Developer**.
15. In the extension, click **Settings**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers-extension-settings.png)
16. Click **Manage Connection to Uniform**.
17. Enter the _Quick Connect Code_ you used to configure the app in Contentful.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers-extension-settings-set.png)

    > **About this step:**
    >
    > These settings give the browser extension the ability to read
    > metadata directly from Uniform. This makes it possible to
    > translate "1_2" into something meaningful.
18. Click **Save**.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers-extension-connected.png)
19. In the extension, click **Dimensions**. Now you will see more meaningful descriptions of what the tracker has collected.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-developers-extension-dimensions.png)
20. In your browser, navigate to `http://localhost:3000/marketers`.
21. Open the browser extension. Now you will see that you have scores for 2 enrichments.

    ![](https://docs.uniform.app/images/integrations/content/contentful/uniform-in-contentful/tutorials/uniformconf-nextjs/localhost-page-marketers-extension-dimensions.png)

    > **About this step:**
    >
    > You can see that tracking is working. The next step is
    > to personalize the visitor's experience based on this
    > information that has been tracked.

### Activate personalization

In Contentful you configured a content entry that represents
a personalized list of hero entries for the home page. Uniform
provides a React component that can execute the personalization
settings configured in the list. This section describes how to
add that component to the front-end application.

1. Open the file `./lib/cf/fetch.js` in your text editor.
2. Add the following code:

   ```jsx
   function getFields(entry) {
     const { fields } = entry;
     if (fields?.image) {
       fields.image = fields.image.fields.file.url;
     }
     if (!fields.id && entry.sys?.id) {
       fields.id = entry.sys?.id;
     }
     if (fields.unfrmOptEnrichmentTag) {
       fields.enrichments = fields.unfrmOptEnrichmentTag;
       delete fields.unfrmOptEnrichmentTag;
     }
     if (fields.unfrmOptPersonalizationCriteria) {
       fields.pz = fields.unfrmOptPersonalizationCriteria;
       delete fields.unfrmOptPersonalizationCriteria;
     }
     return fields;
   }
   ```

   > **About this step:**
   >
   > This code should look familiar because it's similar to the
   > code you added to rename the field for the enrichment tags. In
   > this case, the personalization criteria is stored in Contentful
   > in a field `unfrmOptPersonalizationCriteria`, where Uniform
   > expects the field `pz`.
3. Add the following code:

   ```jsx
   export async function fetchVariations(id) {
     const entry = await fetch(id);
     const { unfrmOptP13nList } = entry;
     return unfrmOptP13nList.map(getFields);
   }
   ```
4. In Contentful, open the content entry **Home Page Heroes**.
5. Navigate to **Info** and note the **ENTRY ID**.
6. Open the file `./pages/index.jsx`.
7. Make the following changes:

   ```jsx
   import { Hero } from "../components/Hero";
   import { fetchVariations } from "../lib/cf/fetch";
   export async function getStaticProps() {
     const fields = await fetchVariations("29zgaRj1vU1idUq3ydCQeU");
     return { 
       props: { ...fields }
     }
   }
   export default function Home(props) {
     return <Hero {...props} />}
   };
   ```

   > **About this step:**
   >
   > For the call to `fetchVariations`, make sure you use the entry
   > ID for the _Home Page Heros_ entry.
8. Make the following changes:

   ```jsx
   import { Hero } from "../components/Hero";
   import { Personalize } from '@uniformdev/context-react';
   import { fetchVariations } from "../lib/cf/fetch";
   export async function getStaticProps() {
     const fields = await fetchVariations("29zgaRj1vU1idUq3ydCQeU");
     return { 
       props: { ...fields }
     }
   }
   export default function Home({ variations }) {
     return (
       <Personalize
         variations={variations}
         name="heroPersonalized"
         component={Hero}
       />}
     );
   };
   ```

   > **About this step:**
   >
   > The **Personalize** component receives the collection of the
   > possible variations that were configured in the personalized
   > list in Contentful and is able to evaluate the personalization
   > criteria to find a match.

### Finished code

We provide a finished version of the UniformConf application
that you can get running in your preferred environment.

**Local machine**

1. Clone the following repository:

   ```
   https://github.com/uniformdev/uniform-docs-examples
   ```
2. Check out the following branch:

   ```
   apps/contentful/nextjs/context-activated
   ```
3. Set variables in `.env` to match the settings that apply to your
   Contentful and Uniform environments.
4. Enter the following command:

   ```
   npm install
   ```
5. Enter the following command:

   ```
   npm run dev
   ```

   > **About this step:**
   >
   > This will start the Next.js app in develop mode on port 3000.

## Next steps

Now that you have a fully functional Next.js application powered
with content from Contentful and personalized using Uniform
Context, you can use this as a starting point for exploring
everything Uniform has to offer, including:

- **Presentation builder** - Uniform Canvas offers a tool that
  gives content authors control over presentation within
  constraints defined by developers, in a way that fits
  into modern digital production processes.
