# The Uniform manifest

> The manifest describes the parameters that Uniform uses during the classification process.

Source: https://docs.uniform.app/docs/guides/classification/manifest

In order for the Uniform tracker to classify a visitor, it
needs to know what to track. The Uniform manifest provides
this information.

The Uniform manifest is a JSON object that describes the
[classification](../classification) criteria that are configured
in Uniform. The settings included in the manifest are defined in
a Uniform project under the sections **Personalization** and
**Testing**. The Uniform tracker uses the manifest in order to
know how to classify visitors.

## When to retrieve the manifest

A basic decision you must make is whether to incorporate the manifest
into your application (build-time), or for your application to include
logic to retrieve the manifest itself (runtime).

| Scenario | Option | Notes |
| --- | --- | --- |
| Optimize application performance | Build-time | Your application application does not need to make an additional request to fetch the manifest. |
| Minimize runtime dependencies | Build-time | Every additional API your application requires at runtime creates another dependency for your application. Bundling the manifest at build-time eliminates the dependency on the availability of the Uniform Manifest API at runtime. |
| Application rebuilds are expensive | Runtime | If the application can retrieve the manifest itself, the manifest does not have to be bundled with the application. |
| Manifest changes frequently | Runtime | If the manifest changes often, it may be easier to have the application retrieve the manifest when it needs it. |

## How to retrieve the manifest

In order for classification and personalization to work, your
application needs to have access to the manifest.

> **Uniform API key is required:**
>
> All of these approaches require an API key with the following permissions:
>
> - Uniform Context > Manifest > Read
>
> If you need an API key, you can [create one](https://docs.uniform.app/docs/guides/apis#create-api-key) in the Uniform dashboard.

### CLI

These steps will you to download the manifest to a file `manifest.json` from a terminal.

1. If it's not already installed, [install the CLI](https://docs.uniform.app/docs/guides/cli/installation-and-setup#install-globally) globally.
2. If it's not already installed, install the package `@uniformdev/context` globally.
3. Run the following command:

   _For the US region:_

   ```shell
     uniform context manifest download \\
       -o ./manifest.json \\
       -p <UNIFORM_PROJECT_ID> \\
       -k <UNIFORM API KEY>
   ```

   _For the EU region:_

   ```shell
     uniform context manifest download \\
       -o ./manifest.json \\
       -apiHost https://eu.uniform.app \\
       -p <UNIFORM_PROJECT_ID> \\
       -k <UNIFORM API KEY>
   ```

   > **What has changed:**
   >
   > When the command finishes, a file `manifest.json` is created.

### Npm package

A type `ManfestClient` is available in the npm package `@uniformdev/context`. The following code demonstrates how to use this type to retrieve the manifest.

_For the US region:_

```js
import { ManifestClient } from '@uniformdev/context/api';

const manifestClient = new ManifestClient({
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

manifestClient.get().then(manifest => {
  //
  // Do something with the manifest.
});
```

_For the EU region:_

```js
import { ManifestClient } from '@uniformdev/context/api';

const manifestClient = new ManifestClient({
  apiHost: 'https://eu.uniform.app',
  apiKey: "[!!! UNIFORM API KEY !!!]",
  projectId: "[!!! UNIFORM PROJECT ID !!!]",
});

manifestClient.get().then(manifest => {
  //
  // Do something with the manifest.
});
```

### Npm script

These steps will allow you to download the manifest to a file `manifest.json` using an npm script.

1. If it's not already added to your application, [install the CLI](https://docs.uniform.app/docs/guides/cli/installation-and-setup#install-in-a-project).
2. If it's not already added to your application, install the package `@uniformdev/context` in the project.
3. Add the following file:

_For the US region:_

`.env`

```properties
UNIFORM_PROJECT_ID=<UNIFORM PROJECT ID>
UNIFORM_API_KEY=<UNIFORM API KEY>
```

_For the EU region:_

`.env`

```properties
UNIFORM_CLI_BASE_URL=https://eu.uniform.app
UNIFORM_PROJECT_ID=<UNIFORM PROJECT ID>
UNIFORM_API_KEY=<UNIFORM API KEY>
```

1. Add the following to the `scripts` section of `package.json`:

   ```json
   "download:manifest": "uniform context manifest download -o ./manifest.json",
   ```
2. You can run the command from a terminal, or as a part of another npm script using the following command:

   `npm`

   ```shell
   npm run download:manifest
   ```

   `pnpm`

   ```shell
   pnpm run download:manifest
   ```

   `yarn`

   ```shell
   yarn download:manifest
   ```

   > **What has changed:**
   >
   > When the command finishes, a file `manifest.json` is created.

### REST API

The manifest can be downloaded using the REST API.

_For the US region:_

**Fetch**

```js
const manifestUrl = new URL('https://uniform.app/api/v2/manifest');

manifestUrl.searchParams.set('preview', 'false');
manifestUrl.searchParams.set('projectId', "[!!! UNIFORM PROJECT ID !!!]");

fetch(manifestUrl, {
  headers: {
    accept: "application/json",
    "x-api-key": "[!!! UNIFORM API KEY !!!]",
  }
})
.then(response => response.json())
.then(manifest => {
  // Do something with the manifest.
});
```

**cURL**

```
curl -X 'GET' \
  'https://uniform.app/api/v2/manifest?preview=false&projectId=[!!! UNIFORM PROJECT ID !!!]' \
  -H 'accept: application/json' \
  -H 'x-api-key: [!!! UNIFORM API KEY !!!]'
```

_For the EU region:_

**Fetch**

```js
const manifestUrl = new URL('https://eu.uniform.app/api/v2/manifest');

manifestUrl.searchParams.set('preview', 'false');
manifestUrl.searchParams.set('projectId', "[!!! UNIFORM PROJECT ID !!!]");

fetch(manifestUrl, {
  headers: {
    accept: "application/json",
    "x-api-key": "[!!! UNIFORM API KEY !!!]",
  }
})
.then(response => response.json())
.then(manifest => {
  // Do something with the manifest.
});
```

**cURL**

```
curl -X 'GET' \
  'https://eu.uniform.app/api/v2/manifest?preview=false&projectId=[!!! UNIFORM PROJECT ID !!!]' \
  -H 'accept: application/json' \
  -H 'x-api-key: [!!! UNIFORM API KEY !!!]'
```

## Examples

### Runtime retrieval with SSG & edge-side personalization

With edge-side personalization, it is critical that the
same manifest is available to the Uniform tracker that
runs on the server and in the front-end application.
The general process is:

- Retrieve the manifest on the server.
- Inject the manifest into the front-end application in a script tag.
- Configure the front-end application to load the manifest from the script tag.

**Next.js (page router)**

1. Add the following file:

   `lib/context.js`

   ```jsx
   import { Context } from "@uniformdev/context";
   import { NextCookieTransitionDataStore } from "@uniformdev/context-next";
   import { NextPageContext } from "next";

   export default function createUniformContext(manifest, serverContext) {
     return new Context({
       defaultConsent: true,
       manifest,
       transitionStore: new NextCookieTransitionDataStore({
         serverContext,
       }),
     });
   }
   ```

   > **Note:**
   >
   > This function creates the Uniform tracker. It is used to
   > create both the server-side tracker and the client-side
   > tracker. If you already have a function like this, change
   > it so you can pass the manifest into it (instead of reading
   > the manifest from a file).
2. In your `_document` file, add the following code:

   _For the US region:_

   ```jsx
   import { ManifestClient } from "@uniformdev/context/api";
   import createUniformContext from "../lib/context";

   async function getManifest() {
     const manifestClient = new ManifestClient({
       apiKey: process.env.UNIFORM_API_KEY,
       projectId: process.env.UNIFORM_PROJECT_ID,
     });
     return manifestClient.get();
   };
   ```

   _For the EU region:_

   ```jsx
   import { ManifestClient } from "@uniformdev/context/api";
   import createUniformContext from "../lib/context";

   async function getManifest() {
    const manifestClient = new ManifestClient({
      apiHost: 'https://eu.uniform.app',
      apiKey: process.env.UNIFORM_API_KEY,
      projectId: process.env.UNIFORM_PROJECT_ID,
    });
    return manifestClient.get();
   };
   ```

   > **Note:**
   >
   > This function runs on the server. It reads the latest
   > published manifest from your Uniform project. Since
   > it runs on the server, it has access to environment
   > variables.
3. In the function `getInitialProps`, add the following code:

   ```jsx
   static async getInitialProps(ctx) {
     const manifest = await getManifest();
     const serverTracker = createUniformContext(manifest, ctx);
     enableNextSsr(ctx, serverTracker);
     const initialProps = await Document.getInitialProps(ctx);
     return {...initialProps, manifest};
   }
   ```

   > **Note:**
   >
   > This creates the Uniform tracker used during the server-side
   > rendering. The tracker is configured to use the manifest
   > retrieved from Uniform. Finally, the manifest is made
   > available to the document as a prop.
4. In the function `render`, add the following code in the tag `Head`:

   ```jsx
   <script id="manifest" type="application/json" 
     dangerouslySetInnerHTML={{__html: JSON.stringify(manifest)}} 
   />
   ```

   > **Note:**
   >
   > This injects the manifest into the page so it is available
   > on the code that runs on the client.
5. In your `_app` file, add the following code:

   ```jsx
   import { UniformContext } from "@uniformdev/context-react";
   import createUniformContext from "../lib/context";

   // IMPORTANT: importing all components registered in Canvas
   import "../components/canvasComponents";

   import "../styles/styles.css";

   function MyApp({ Component, pageProps, serverUniformContext }) {
     let manifest = { project: {} };
     if (typeof window !== "undefined") {
       const json = document.getElementById("manifest")?.innerHTML;
       if (json) {
         manifest = JSON.parse(json);
       }
     }
     const clientContext = createUniformContext(manifest);
     return (
       <UniformContext
         context={serverUniformContext ?? clientContext}
       >
         <Component {...pageProps} />
       </UniformContext>
     );
   }

   export default MyApp;
   ```

   > **Note:**
   >
   > This creates the client-side tracker using the manifest
   > that was injected by the server-side code that you added
   > in the previous step.

**Next.js (app router)**
