# Activate personalization

> Activating personalization in your application involves adding components that can execute personalization instructions.

Source: https://docs.uniform.app/docs/guides/personalization/activate-personalization

> **Note:**
>
> The following section is only relevant if you are not using Uniform to manage your personalization placement and variations such as when using Uniform apps for headless CMSs like [Contentful](https://docs.uniform.app/docs/integrations/content/contentful/uniform-in-contentful), [Contentstack](https://docs.uniform.app/docs/integrations/content/contentstack/uniform-in-contentstack), [Sanity](https://docs.uniform.app/docs/integrations/content/sanity/sanity-plugin) or [Kontent.ai](https://docs.uniform.app/docs/integrations/content/kontent/uniform-in-kontent).
>
> If you are using Uniform's visual editor to manage layout in your application this section doesn't apply and no additional configuration is required in your front-end application. You should skip this section.

Activating personalization in your application involves adding
components that can execute personalization instructions. By
default, Uniform executes personalization on the client. However,
Uniform also supports edge-side personalization.

## Personalization modes

Uniform supports a variety of personalization modes. Each has its
own advantages and disadvantages. The available modes depend
on the rendering mode you use.

|  | Server side (SSR) | Static site (SSG) |
| --- | --- | --- |
| Description | The application renders on a server in its entirety before it reaches the client. | The application is rendered at build-time. |
| Time to first byte (TTFB) | Affected by time needed to load content. | Optimized by content being fetched at build-time. |
| Scalability | Increased server load requires increased server costs. | Instant and global. |
| Application size | Application size is irrelevant because the application renders on demand. | Very large sites may take a long time to render. |
| Personalization modes | - Client side<br>- Server side | - Client-side<br>- Edge-side |

### Client-side

> **Warning:**
>
> Classification must be enabled before you can add personalization
> to your app. For more information, see the guide on
> [classification activation](https://docs.uniform.app/docs/guides/classification/add-classification).

**Next.js**

1. Find the page component where you want to add personalization.
   To make these instructions easier to follow, the following
   page component is used:

   ```jsx
   export async function getStaticProps() {
     return {
       props: {
         fields: {
           title: "My Title",
           description: "My Description",
         },
       },
     };
   }
   export default function MyPage({ fields }) {
     const { title, description } = fields;
     return (
       <MyComponent title={title} description={description} />
     );
   }
   ```
2. Add the following code to the page component:

   ```jsx
   const variants = [
     {
       "id": "personalized-content",
       "fields": {
         "title": "Personalized Home",
         "description": "This is personalized content."
       },
       "pz": {
         "crit": [
           {
             "l": "someSignal",
             "op": ">",
             "r": 0
           }
         ]
       }
     },
     {
       "id": "default-content",
       "fields": {
         "title": "Default Home",
         "description": "This is default content."
       }
     }
   ]
   ```

   > **Note:**
   >
   > This represents the personalized content and the criteria used
   > to determine when to use the content. For more information, see
   > the reference on [personalization criteria format](https://docs.uniform.app/docs/learn/products/context#personalization-format).
3. Add the following code to the page component:

   ```jsx
   export async function getStaticProps() {
     return {
       props: {
         variations,
         fields: {
           title: "My Title",
           description: "My Description",
         },
       },
     };
   }
   export default function MyPage({ fields }) {
     const { title, description } = fields;
     return (
       <MyComponent title={title} description={description} />
     );
   }
   ```
4. Open the component that you want to personalization. To make
   these instructions easier to follow, the following component
   is used as an example:

   ```jsx
   export const MyComponent = ({fields}) => {
     const { title, description } = fields;
     return (
       <div>
         <div>{title}</div>
         <div>{description}</div>
       </div>
     )
   };
   ```

   > **Note:**
   >
   > Personalization can be added to any component.
5. Add a new component:

   ```jsx
   import { Personalize } from "@uniformdev/context-react";
   import { MyComponent } from "./MyComponent";
   export const PersonalizedComponent = ({variations}) => {
     return (
      <Personalize 
        variations={variations}
        name="my-example"
        component={MyComponent}
      />
     )
   };
   ```

   > **Note:**
   >
   > The _Personalize_ component determines which variation is
   > the best match and uses the properties on the variation
   > as the props for the component _MyComponent_.
6. Add the following code to the page component:

   ```jsx
   import { PersonalizedComponent } from "../src/components/PersonalizedComponent";
   export async function getStaticProps() {
     return {
       props: {
         variations,
       },
     };
   }
   export default function MyPage({ variations }) {
     return (
       <PersonalizedComponent variations={variations} />
     );
   }
   ```

### Edge-side

If you are using a CDN that supports running custom logic, you
can move the execution of personalization from the client to
the edge.

> **Tip:**
>
> Instructions on configuration for specific CDNs is available in
> the [CDN integrations](https://docs.uniform.app/docs/integrations/cdn) section:
>
> - [Akamai EdgeWorkers](https://docs.uniform.app/docs/integrations/cdn/akamai/akamai-edge-personalization)
> - [Cloudflare Workers](https://docs.uniform.app/docs/integrations/cdn/cloudflare/cloudflare-edge-personalization)
> - [Netlify Edge Functions](https://docs.uniform.app/docs/integrations/cdn/netlify/netlify-edge-personalization)
> - [Vercel Edge Middleware](https://docs.uniform.app/docs/integrations/cdn/vercel/add-edge-middleware)

The configuration for edge-side personalization is basically the
same as client-side personalization. The difference is that the
output mode for the Uniform context is changed to _edge mode_.

**Next.js**

1. Add the following package to your app:

   ```bash
   npm install @uniformdev/context-next
   ```
2. Open the file where you added the Uniform context object.

   > **Note:**
   >
   > This is probably the file `/pages/_app.jsx`.
3. Add the following code:

   ```jsx
   ...
   import { NextCookieTransitionDataStore } from "@uniformdev/context-next";
   ...
   const context = new Context({
     manifest,
     transitionStore: new NextCookieTransitionDataStore({}),
   });
   ```
4. Add the prop `outputType` to the `UniformContext` component:

   ```jsx
   ...
   function MyApp({ Component, pageProps }) {
     return (
       <UniformContext context={context} outputType="edge">
         <Component {...pageProps} />
       </UniformContext>
     );
   }
   ```

> **Tip:**
>
> Next steps: If you haven't already done so, you must configure the component
> responsible for executing personalization. The steps needed depend
> on the [CDN](https://docs.uniform.app/docs/integrations/cdn) you deploy your app to.

### Server-side

This is a traditional server-side rendering mode (SSR), where the
application renders on the server with all the data and state it
has access to at the request time.

> **Tip:**
>
> Before you start, classification must be enabled before you can add personalization
> to your app. For more information, see the guide on
> [classification activation](https://docs.uniform.app/docs/guides/classification/add-classification).

**Next.js**

> **Tip:**
>
> For more information on server-side rendering with Next.js, see
> the [Next.js docs](https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props).

1. Add the following package to your app:

   ```
   @uniformdev/context-next
   ```
2. Open the default document.

   > **Note:**
   >
   > This is probably the file `/pages/_document.js`.
3. Add the following code:

   ```jsx
   ...
   class MyDocument extends Document {
     static async getInitialProps(ctx) {
       return await Document.getInitialProps(ctx);
     }
     render() {
       return (
         ...
       );
     }
     export default MyDocument;
   }
   ```
4. Add the following code:

   ```jsx
   ...
   import { Context } from '@uniformdev/context';
   class MyDocument extends Document {
     static async getInitialProps(ctx) {
       const context = new Context({
       }),
       return await Document.getInitialProps(ctx);
     }
     render() {
       return (
         ...
       );
     }
     export default MyDocument;
   }
   ```
5. Add the following code:

   ```jsx
   ...
   import { Context } from '@uniformdev/context';
   import manifest from "../lib/uniform/contextManifest.json";
   class MyDocument extends Document {
     static async getInitialProps(ctx) {
       const context = new Context({
         manifest,
       }),
       return await Document.getInitialProps(ctx);
     }
     render() {
       return (
         ...
       );
     }
     export default MyDocument;
   }
   ```

   > **Note:**
   >
   > You should have downloaded the manifest file before starting this section.
6. Add the following code:

   ```jsx
   ...
   import { Context } from '@uniformdev/context';
   import manifest from "./contextManifest.json";
   import { NextCookieTransitionDataStore } from "@uniformdev/context-next";
   class MyDocument extends Document {
     static async getInitialProps(ctx) {
       const serverTracker = new Context({
         manifest,
         transitionStore: new NextCookieTransitionDataStore({}),
       }),
       return await Document.getInitialProps(ctx);
     }
     render() {
       return (
         ...
       );
     }
     export default MyDocument;
   }
   ```
7. Add the following code:

   ```jsx
   ...
   import { Context } from '@uniformdev/context';
   import manifest from "./contextManifest.json";
   import { NextCookieTransitionDataStore } from "@uniformdev/context-next";
   import { enableNextSsr } from '@uniformdev/context-next';
   class MyDocument extends Document {
     static async getInitialProps(ctx) {
       const serverTracker = new Context({
         manifest,
         transitionStore: new NextCookieTransitionDataStore({}),
       }),
       enableNextSsr(ctx, serverTracker);
       return await Document.getInitialProps(ctx);
     }
     render() {
       return (
         ...
       );
     }
     export default MyDocument;
   }
   ```
8. Make the following change:

   ```jsx
   ...
   function MyApp({
     Component,
     pageProps,
     serverUniformContext,
   }) {
     return (
       <UniformContext context={serverUniformContext ?? context}>
         <Component {...pageProps} />
       </UniformContext>
     );
   }
   export default MyApp;
   ```
