---
title: Host a frontend with Optimizely
slug: cms-saas/docs/host-a-front-end-with-optimizely
docTags: 
createdAt: 2026-07-30T20:18:10.000Z
---

Optimizely CMS (SaaS) is a headless system, so you must develop and host the frontend application separately. You can host the frontend with Optimizely DXP and connect it to your CMS (SaaS) instance to enable Visual Builder previews.

You can use Optimizely to build and host your NextJS or Astro site's frontend with an Optimizely backend for Optimizely Content Management System (SaaS, CMS 12, and CMS 13).

Supported rendering modes are Static Site Generation (SSG), Server Side Rendering (SSR), and Incremental Static Regeneration (ISR). NextJS supports all three. Astro 5 and Astro 7 support SSG and SSR, and you can add ISR to an Astro SSR site with a Redis cache and Optimizely Graph webhooks. See [Astro ISR caching and Optimizely Graph webhooks](docId\:v6s-PLCwm52JSc9IMEReT). Astro requires Node.js 22.12.0 or later, and odd-numbered Node.js releases are not supported. Support for other frameworks will be added in the future.

You should use Optimizely Graph with your frontend to sync content to the backend. Use your editor to edit the front-end site.

:::hint{type="info"}
**Note**

The frontend hosting SLA is directly tied to your CMS SLA, meaning they share the same service level agreement. This ensures consistent performance expectations across both your content management and its delivery.
:::

In addition to CMS, you gain access to the DXP management portal, where you can deploy and manage your frontend while editing and previewing content in CMS.

:::hint{type="info"}
**Note**

See CMS sample ([github.com/episerver/content-js-sdk](https://github.com/episerver/content-js-sdk)) for information about developing a NextJS frontend for CMS.
:::

## Environment

Each backend has its own frontend. (A back end can have multiple front ends, but a front end cannot have multiple back ends.) The front ends are separate sites and are primarily intended to communicate through Optimizely Graph. The content stored in the CMS is transferred to Optimizely Graph, where the corresponding frontend site can read the content.

The following environment variables are available for the build and for the site at runtime. You can add app settings through the Management Portal UI, which are included as variables for the build and at runtime.

- `OPTIMIZELY_CMS_URL`
- `OPTIMIZELY_GRAPH_GATEWAY`
- `OPTIMIZELY_GRAPH_SECRET`
- `OPTIMIZELY_GRAPH_SINGLE_KEY`
- `OPTIMIZELY_GRAPH_APP_KEY`

## Build the frontend code package

1. Clone or build a site according to the instructions at [content-js-sdk](https://github.com/episerver/content-js-sdk) to create a demo site or a site from scratch.
2. Use `yarn` or `npm` to download and manage third-party libraries. Exclude the build output folder (`.next` for NextJS, `dist` for Astro) and the `node_modules` folder from the code package. The **install** and **build** steps are executed during deployment to the frontend environment, which generates new folders.
3. Make sure to include `yarn.lock-file` in the code package (`package-lock.json` in case of `npm`).
4. Zip the source code into a package with name: `<name>.head.app.<version>.zip` For example: `site.head.app.1.0.0.zip`

The code package must contain a `package.json` in the root. The **build** script runs when deploying the site to build content and **start** script defined in `package.json` starts the site.

**package.json for NextJS**

```json
{
  "scripts": {
    "build": "next build",
    "start": "next start",
  },
}
```

**package.json for Astro (SSR)**

```json
{
  "scripts": {
    "build": "astro build",
    "start": "node ./dist/server/entry.mjs"
  }
}
```

When deploying the package, **build** runs for each deployment, which builds new static content when the site gets built.

:::hint{type="info"}
**Note**

Your deployment package must include exactly one lock file:

- `package-lock.json` (npm), or
- `yarn.lock` (yarn)

If the lock file is missing, deployment may fail during container preparation with a non-descriptive error such as:

`Failed to prepare container in repository 'frontend' on ACR`
:::

Generate a lock file without installing dependencies:

```bash
npm install --package-lock-only
```

## Deploy the frontend

To deploy, generate a key in the **API** tab (see below), and select the environments you intend to deploy to.

Begin with installing `EpiCloud` to manage deployments of code packages. You can install and import it using this PowerShell (Powershell Module EpiCloud 1.10 or higher):

```powershell
Install-Module EpiCloud
Import-Module EpiCloud
```

Then, to deploy the code package:

```powershell
# Set up variables for the environment to deploy to
$projectId = "projectId"
$clientKey = "clientKey"
$clientSecret = "clientSecret"
$targetEnvironment = "Test1"

# Connect EpiCloud module to prepare for deployment
Connect-EpiCloud -ProjectId $projectId -ClientKey $clientKey -ClientSecret $clientSecret

# Upload code package
$sasUrl = Get-EpiDeploymentPackageLocation
Add-EpiDeploymentPackage -SasUrl $sasUrl -Path .\site.head.app.1.0.0.zip

# Deploy code package to the front-end environment and complete the deployment
$deployment = Start-EpiDeployment -DeploymentPackage "site.head.app.1.0.0.zip" -TargetEnvironment $targetEnvironment -Wait
$deployment | Complete-EpiDeployment -Wait
```

## DXP management portal features

You should be using Opti ID to sign in. First, check that Opti ID is enabled on your Product access for the account:

1. Log into CMS Developer Portal ([https://paasportal.episerver.net/](https://paasportal.episerver.net/)).
2. Go to **CMS** > **Product Access** > **Developer Portal** (frontend) > **Details** tab.
3. Confirm that **Opti ID Enabled** is selected.
4. Go to **Admin Center** > **Users** > \{select a user} > **Add Product Access** to ensure your user has Power User access to the **Developer portal (front end)** product.
5. Click **Developer Portal** from the top navigation in CMS, or go to the [DXP management portal URL](https://paasportal.episerver.net/), to log in to the DXP management portal and view your frontend hosting project.

### Deployment tab

Track the status of deployments and available environments.

![DXP management portal Deployment tab showing recent deployments and target environments](https://files.readme.io/7f5256b28c9c6948ed44eb6267014dffe94baf106a5bfabc37fcd1700ae37acd-image.png)

- **Recent Deployments** – Displays deployment. The **Start (UTC)** column shows when the deployment was run. Click on the link to display the deployment log. You can filter the **Recent Deployments** list from the **Target Environment menu**.
- **View deployment log** – Select a deployment from the **Recent Deployments** list to display the log for information about the deployment's success or failure. The following image shows a sample successful deployment.

![Deployment log showing a successful frontend deployment](https://files.readme.io/8a7c5ffbabf0cc29ac4c2123152079e0a8fda49be46081d64b03593718d0556a-DXP-deployment-log-success.png)

The following image shows a failed deployment.

![Deployment log showing a failed frontend deployment](https://files.readme.io/5bf237996098bdd288f97610068f0dfbfb2e9acd6ecd59c2b3cb3f1cf6da3a41-image.png)

### Troubleshoot tab

Troubleshoot issues encountered by exporting or viewing real-time logs, restarting the app, purging CDN cache, and more.

![DXP management portal Troubleshoot tab](https://files.readme.io/025a7c6d58c59b369c21067892fc750664d1c956e1c8e89e97a9dccd18d1ec9b-image.png)

- **Restart site** – Select **Environment** and **Site** and click **Restart Web App**. See [Restart a web app](docId:2G9RawnZlX8HvaghmUBvN).
- **CDN Cache** – Click **Purge Cache** to clear the cache if you, for example, had a problem with an image that needs a version number. See [Purge CDN cache](docId\:JMjiDskJ5UFKmpc0HUu2W).
- **Application Logs** – Stream live logs from your instance so you can see what actually happens. You can also generate a download link. See [Configure logging](docId\:LjN1r6TV1wDwIiwlQWCZt).
  - **Open Log Stream Window** – Click to stream a live log from your application.
- **Project Security** – Select the level of security you want (**Medium** or **I'm under attack**). For example, if you experience a distributed denial of service (DDoS) attack or multiple bots attempt to attack your site, select **I'm under attack** to help mitigate Layer 7 DDoS attacks. Validated users access your website, and suspicious traffic is blocked. See Cloudflare's [Under Attack mode](https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/) article.

![Project Security setting in the DXP management portal Troubleshoot tab](https://files.readme.io/63a08335acd662720eeda82e2919e98daacf43a377cdb1b39f670fde7bccff74-image.png)

- **Environment information** – Select the environment and **Click Get Outbound IPs** to generate an allow list of outbound IP addresses of the user infrastructure hosting their site.

### API tab

Manage deployment API, Graph, and other credentials. The **API** tab is where you generate the keys you need to trigger deployments.

![DXP management portal API tab](https://files.readme.io/89839b3472e92772ff2f520de439d4b195e5a4934e739f8f514bdc5d67d2d569-image.png)

Click **Add API Credentials** to generate the keys you need to trigger deployments.

![Add API Credentials dialog in the DXP management portal](https://files.readme.io/0289ba6d2b4e52343dfb7fba457c1fc535b7226d37aca442704faeb9473454a0-image.png)

### App Settings tab

The **App Settings** tab lets you configure and control settings related to your application. App Setting and secret names must be 1–127 characters. See [Environment variables and app settings in Azure App Service](https://learn.microsoft.com/en-us/azure/app-service/reference-app-settings?tabs=kudu%2Cdotnet) for a list of available app setting environment variables.

Learn more about [Deploying to Optimizely Frontend Hosting](https://world.optimizely.com/blogs/szymon-uryga/dates/2025/6/deploying-to-optimizely-frontend-hosting-a-practical-guide/) from Optimizely's blogs.

## Configure Visual Builder

To see your frontend preview in Visual Builder:

1. Go to **Settings > Import Data** to import a content pack or content model into CMS.
2. Go to **Settings > Applications** to create and configure an application in CMS.
3. Deploy the frontend source code from the DXP management portal. Make sure your site has preview routes configured.
4. Go to **Settings > Applications > Select your application > Hostnames > Add hostname** to adjust the application configuration in CMS to map domains. Use the hostname from the DXP management portal to map to the app. This enables the site content to show up in the Visual Builder.
5. Go to **Settings > Scheduled jobs** to reindex content in Optimizely Graph.
