# Front-end management of Sitecore

> Uniform enables you to use content from Sitecore to power omnichannel digital experiences without depending on Sitecore to management the front-end.

Source: https://docs.uniform.app/docs/integrations/content/sitecore/front-end-management

Uniform enables you to use content from Sitecore to power omni-channel digital experiences without depending on Sitecore to management the front-end. But if you already a Sitecore site, you already have a front-end. You have the following options when adopting Uniform:

- Build an entirely new front-end - You are planning a new front-end and are only using content from Sitecore.
- Migrating the front-end from Sitecore - You want to retain your existing front-end, but you don't want to manage it using Sitecore presentation details.

## Build new front-end

If you are doing a site redesign, you are creating your front-end
from scratch. You don't need to worry about
[migrating your existing Sitecore front-end](./migrate-existing).
Your focus is on creating front-end components that can access
content from Sitecore items.

In addition, you may create new front-end components after you
have finished migrating renderings & layouts from Sitecore and
need to create new front-end components.

> **Tip:**
>
> This example uses Next.js as the front-end framework, but you
> can use any front-end technology you want. The layout and
> components defined in Canvas are technology agnostic.

### Create web app

1. Open a command-line interface (CLI).
2. Enter the following commands:

   ```bash
   npx create-next-app headless-sitecore-site
   cd headless-sitecore-site
   ```
3. Create a file named `.env`
4. Add a file `.env` and define the following variables:

| Name | Value |
| --- | --- |
| `UNIFORM_API_SITENAME` | `website` |
| `UNIFORM_API_KEY` | Your Uniform API key. Use the same value as you configured on the Canvas Integration Service in Sitecore. |
| `UNIFORM_PROJECT_ID` | Your Uniform Project ID. Use the same value as you configured on the Canvas Integration Service in Sitecore. |

The file will look like the following:

_For the US region:_

```
UNIFORM_API_TOKEN=
UNIFORM_PROJECT_ID=
UNIFORM_API_URL=
```

_For the EU region:_

```
UNIFORM_API_TOKEN=
UNIFORM_PROJECT_ID=
UNIFORM_API_URL=
UNIFORM_CLI_BASE_EDGE_URL=https://eu.uniform.global
UNIFORM_CLI_BASE_URL=https://eu.uniform.app
```

#### Add npm packages

To add Uniform functionality to your web app, you
must add a number of npm packages. Some of these packages
are publicly available and some require an npm access
token.

Enter the following commands:

```bash
yarn add dotenv @uniformdev/canvas @uniformdev/canvas-react @uniformdev/cli
yarn add @uniformdev/canvas-sitecore
```

### Add Uniform config

You must configure Next.js to load Uniform settings when it runs.

1. Open the file `next.config.js`.
2. Change the contents to the following:

   ```js
   const { uniformNextConfig } = require('@uniformdev/next-server');
   module.exports = uniformNextConfig();
   ```

#### Create front-end component

> **Info:**
>
> Coming soon.

#### Map component name to implementation

Each component defined in Canvas has a _public ID_. When you
defined the component in Canvas, you specified this value.

When your web app reads composition definitions from Canvas,
the composition and the components that are assigned to the
composition are identified using this value.

You must provide instructions to your web app on how to map the
_public ID_ to the front-end implementation of that component.
In your web app, React components provide that implementation.

Create a file `lib/resolveRenderer.js`:

```js
import ManagedContent from '../components/ManagedContent';
const mapping = {};
mapping['managedContent'] = ManagedContent;
export const resolveRenderer = (component) => {
  if (component?.type) {
    const implementation = mapping[component.type]
    if (implementation) return implementation;
  }
  return DefaultNotImplementedComponent
};
```

### Add Uniform to page

In Canvas you have a composition that represents the home page
and describes the layout for the page. You have a number of
React components that represent the implementation of those
components. Now you must configure the Next.js app to use the
information from the Canvas composition to render
the page using the React components you implemented.

#### Add composition component

Replace the contents of the file `pages/index.jsx` with the following:

```js
import Head from 'next/head';
import { UniformComposition, UniformSlot } from "@uniformdev/canvas-react";
import { resolveRenderer } from "../lib/resolveRenderer";
export default function Home({ composition }) {
  return (
    <UniformComposition data={composition} resolveRenderer={resolveRenderer}>
      <>
        <Head>
          <title>{_name}</title>
        </Head>
        <div id="MainPanel">
          <UniformSlot name="main" />
        </div>
      </>
    </UniformComposition>
  );
}
```

> **About this code:**
>
> The component Composition accepts props that represent the
> composition (which is retrieved from Canvas) and a function
> that resolves the React component that corresponds to the
> public id for a component from Canvas.
>
> This code also adds a component to render the slot _main_.
> You defined this slot when you defined the composition
> component.

#### Retrieve the composition

1. Add the following code to the top of the file `pages/index.jsx`:

_For the US region:_

```js
import Head from 'next/head';
import {
    CanvasClient,
} from "@uniformdev/canvas";
import { UniformComposition, UniformSlot } from "@uniformdev/canvas-react";
import { resolveRenderer } from "../lib/resolveRenderer";
async function getComposition(slug) {
    const client = new CanvasClient({
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
    });
    const { composition } = await client.getCompositionBySlug({
    slug,
    });
    return composition;
}
export default function Home({ composition }) {
    return (
    <UniformComposition data={composition} resolveRenderer={resolveRenderer}>
        <>
        <Head>
            <title>{_name}</title>
        </Head>
        <div id="MainPanel">
            <UniformSlot name="main" />
        </div>
        </>
    </UniformComposition>
    );
}
```

_For the EU region:_

```js
import Head from 'next/head';
import {
    CanvasClient,
} from "@uniformdev/canvas";
import { UniformComposition, UniformSlot } from "@uniformdev/canvas-react";
import { resolveRenderer } from "../lib/resolveRenderer";
async function getComposition(slug) {
    const client = new CanvasClient({
    apiHost: 'https://eu.uniform.app',
    edgeApiHost: 'https://eu.uniform.global',
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
    });
    const { composition } = await client.getCompositionBySlug({
    slug,
    });
    return composition;
}
export default function Home({ composition }) {
    return (
    <UniformComposition data={composition} resolveRenderer={resolveRenderer}>
        <>
        <Head>
            <title>{_name}</title>
        </Head>
        <div id="MainPanel">
            <UniformSlot name="main" />
        </div>
        </>
    </UniformComposition>
    );
}
```

1. Add the following code to the file `pages/index.jsx`:

_For the US region:_

```jsx
import Head from 'next/head';
import {
    CanvasClient,
} from "@uniformdev/canvas";
import { UniformComposition, UniformSlot } from "@uniformdev/canvas-react";
import { resolveRenderer } from "../lib/resolveRenderer";
async function getComposition(slug) {
    const client = new CanvasClient({
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
    });
    const { composition } = await client.getCompositionBySlug({
    slug,
    });
    return composition;
}
export async function getStaticProps() {
    const slug = "/";
    const composition = await getComposition(slug);
    return {
    props: { composition },
    }
}
export default function Home({ composition }) {
    return (
    <UniformComposition data={composition} resolveRenderer={resolveRenderer}>
        <>
        <Head>
            <title>{_name}</title>
        </Head>
        <div id="MainPanel">
            <UniformSlot name="main" />
        </div>
        </>
    </UniformComposition>
    );
}
```

_For the EU region:_

```jsx
import Head from 'next/head';
import {
    CanvasClient,
} from "@uniformdev/canvas";
import { UniformComposition, UniformSlot } from "@uniformdev/canvas-react";
import { resolveRenderer } from "../lib/resolveRenderer";
async function getComposition(slug) {
    const client = new CanvasClient({
    apiHost: 'https://eu.uniform.app',
    edgeApiHost: 'https://eu.uniform.global',
    apiKey: process.env.UNIFORM_API_KEY,
    projectId: process.env.UNIFORM_PROJECT_ID,
    });
    const { composition } = await client.getCompositionBySlug({
    slug,
    });
    return composition;
}
export async function getStaticProps() {
    const slug = "/";
    const composition = await getComposition(slug);
    return {
    props: { composition },
    }
}
export default function Home({ composition }) {
    return (
    <UniformComposition data={composition} resolveRenderer={resolveRenderer}>
        <>
        <Head>
            <title>{_name}</title>
        </Head>
        <div id="MainPanel">
            <UniformSlot name="main" />
        </div>
        </>
    </UniformComposition>
    );
}
```

#### Add enhancer

When you retrieve the composition from Canvas, Sitecore item ids
are included in the data. You must use an enhancer to retrieve
the fields for those items.

> **Info:**
>
> Coming soon.

### Start the web app

When you run the web app, you should see the page from the default
Sitecore site, but Sitecore isn't handling page rendering. Sitecore
is only acting as a headless CMS.

1. In the terminal, enter the following command:

   ```bash
   yarn dev
   ```
2. Open your browser to `http://localhost:3000`
