Deploy to the SaaS environment

Xperience by Kentico enables you to deploy, host, and maintain Xperience websites in a Software-as-a-Service (SaaS) environment. You can deploy to multiple environments to isolate the production and non-production application instances.

Kentico manages the deployment infrastructure and selected third-party services for you – currently Microsoft Application Insights and Twilio SendGrid. This allows you to focus on website and content development.

Develop a website for deployment to the SaaS environment:

  1. Get access to your Xperience Portal project.
  2. Prepare a .NET project for deployment to the SaaS environment.
  3. Develop and configure features in your project.
  4. Deploy your application to the SaaS environment.
  5. Manage your deployed application in Xperience Portal.

SaaS environments are not a substitute for staging

Be aware that different SaaS environments are not meant for staging your website content. Deploying packages with large volume of files and content between environments is not efficient.

  • The maximum size of the deployment package is 2 gigabytes. Binary files and media libraries are bundled in the deployment package.
  • Non-production environments (QA and UAT) only serve to test the functionality of your project. Any data or content edited in these environments will not be promoted to the Production environment.
  • After promoting a build to the Production environment, production data can be added. Use the workflow feature to prevent incomplete data from appearing publicly.
  • Only the latest deployed package can be promoted to the next environment.
  • Backup policies are different for non-production enviroments and the Production environment. Using QA and UAT environments for staging poses a small but non-negligible risk that you lose your staged data.

Prepare a project for deployment to the SaaS environment

  1. Create an Xperience project and the project database.

  2. Configure the Xperience application:

    1. Enable Microsoft Application Insights
    2. Enable managed SendGrid integration
    3. Configure Cloudflare CDN.
    4. (Optional) Configure Azure Blob storage folder mapping for media library files and any unmanaged binary files referenced by your application. Consider this configuration, especially if your application works with binary files stored outside of the dedicated ~/assets directory that is mapped to the blob by default. Persisting binary data outside of the blob storage can be unreliable and lead to data loss in case the hosting service recycles the application (e.g., due to infrastructure changes).
    5. (Optional) Define a custom static page to display when your application is unavailable.
  3. Build the project. Run the following command from the project’s root directory or build the project using Visual Studio.

     dotnet build

The project is now ready for further development and customization. You can add content to the project or extend the connected Xperience administration.

Project templates for deployment to the SaaS environment

Xperience provides the kentico-xperience-mvc and kentico-xperience-sample-mvc .NET project templates as a starting point for developing Xperience websites.

A project template for SaaS deployment (installed with the --cloud parameter) contains the following:

  • An Xperience .NET application.
  • Adjustments for SaaS deployment in the application’s service collection and middleware pipeline within the Program.cs file.
    • WebApplication.UseKenticoCloud must be called in the middleware pipeline before WebApplication.UseKentico. See Configure new projects.
  • A configuration file for the Continuous Deployment repository, used to deploy database objects.
  • The Export-DeploymentPackage.ps1 PowerShell script that creates a deployment package for the project.
  • StorageInitializationModule.cs class with methods mapping folders containing media library and binary files to Azure Blob storage and local storage for development. See Azure Blob storage.

Configure the Xperience application for deployment to the SaaS environment

Environment identification extension methods

Use IsQa() and IsUat() extension methods (available in the Kentico.Xperience.Cloud namespace) alongside native .NET HostingEnvironmentExtensions methods IsDevelopment() and IsProduction() to identify the currently active environment.

For example, use the environment identification extension methods to integrate Twilio SendGrid in QA, UAT, and production environments but not in your local development environment.

Environment identification in Program.cs

using Kentico.Xperience.Cloud;


WebApplicationBuilder builder = WebApplication.CreateBuilder(args);


if (builder.Environment.IsQa() || builder.Environment.IsUat() || builder.Environment.IsProduction())
    // Code executed in QA, UAT, and Production environments

Microsoft Application Insights integration

Xperience integrates Application Insights for ASP.NET Core applications to enable monitoring and aggregation of metrics for your website:

  • Event log – errors and warnings from the Xperience event log.
  • .NET exceptions and errors – in addition to errors that are included in the Xperience event log, also covers exceptions that can occur before the Xperience application is fully running.
  • (Optional) Client-side telemetry

You can view the Application Insights logs for your deployments in Xperience Portal using the corresponding applications under the Monitoring section:

  • Event log – displays entries from the Xperience event log and any custom messages sent via the Application Insights SDK.
  • Exceptions – displays all .NET exceptions (errors) from Application Insights.

Enabling the Application Insights integration is also helpful if you ever need to debug or monitor your application with the Kentico support team.

Enable Microsoft Application Insights integration

  1. Open your Xperience project in Visual Studio and edit the Program.cs file.

  2. Call WebApplicationBuilder.Services.AddXperienceCloudApplicationInsights when building the web application.

    Enabling AppInsights integration
     using Kentico.Xperience.Cloud;
     WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

    Refer to Microsoft’s documentation on how to use Application Insights in Visual Studio in a development environment.

  3. (Optional) Enable client-side telemetry.

  4. Rebuild the solution.

Cloudflare CDN

The SaaS environment integrates Cloudflare CDN to ensure better application performance and availability by distributing the network load across the CDN data centers and by caching website resources.

Cloudflare CDN performs caching as described in Default Cache Behavior.

  • Files with the Default cached extensions (images, videos, CSS, JS, PDF, etc.) are cached. By default, the cache time-to-live (TTL) is based on the response’s HTTP status code – see Edge TTL.
  • The HTML output of pages is not cached.

You can control the CDN caching for supported file extensions by setting the Cache-Control HTTP header directives for each response. For example:

  • no-cache, private, no-store, max-age=0 – disables caching
  • max-age=<seconds> – enables caching with the specified time-to-live (TTL). For more information, see Retention versus Freshness (TTL).

There are several ways to set HTTP headers, for example, by using the ResponseCache attribute to set Cache-Control directives. See Response caching in ASP.NET Core to learn how to set HTTP headers in ASP.NET Core.

For example, the following code shows how to set the Cache-Control header for static files in your application’s Program.cs file:



builder.Services.Configure<StaticFileOptions>(o =>
    o.OnPrepareResponse = context =>
        // Caches static files for 7 days
        context.Context.Response.Headers.Append("Cache-Control", "public,max-age=604800");




Define a custom App Offline file

When the application is offline, for example, when scheduled Xperience Portal project maintenance is in progress, a generic .NET static page is displayed when accessing the application.

Create an app_offline.htm_ file in the project’s root to replace the default generic page. The file will be packaged with the deployment package. See Deploy.

Use the file name suffixed with an underscore (_), as app_offline.htm is not a valid custom App Offline name in Xperience.

See Microsoft documentation for more information about the App Offline file (app_offline.htm).

Deploy to the SaaS environment

Once you have your Xperience project prepared and configured in a local development environment, deploy the application to the SaaS environment by creating a deployment package and uploading it to your Xperience Portal project where it is automatically deployed into the QA environment.

You need to create and upload a new deployment package to update an existing deployment.

Create a deployment package

A deployment package is a ZIP archive with application libraries and static files, and a $CDRepository folder with serialized objects, and optionally a $StorageAssets folder for media library files.

The deployment package is limited by a maximum size of 2GB.

Follow the procedure to build your application and create a deployment package:

  1. Use Continuous Deployment to serialize database objects to the file system:

    1. Edit the $CDRepository/repository.config file according to your object filtering and deployment requirements. See Exclude objects from CI/CD.

      You cannot adjust the location of the Continuous Deployment repository. The deployment process expects the $CDRepository folder to be in the project root.

    2. Prepare migration scripts for any database changes not covered by Continuous Deployment.

    3. Run the CD store command from the project’s root directory:

       dotnet run --no-build -- --kxp-cd-store --repository-path ".\$CDRepository"
  2. Deploy Media library files and other unmanaged binary files used by the application to Azure Blob storage, as Continuous Deployment does not serialize these files.

  3. Create the deployment package with the Export-DeploymentPackage.ps1 script.

    On Windows environments, the executing account must have permissions to run PowerShell scripts from external sources:

     # Bypass all execution checks for the current user
     Set-ExecutionPolicy Bypass -Scope CurrentUser -Force

    See Set-ExecutionPolicy for other types of permission levels.

    • Refer to the list of parameters before running the script.

        .\Export-DeploymentPackage.ps1 -AssemblyName "DancingGoat"
      • -AssemblyName – the name of the main web application assembly used during project publishing.

        • The value must be equal to the assembly name of the Xperience project (by default, the assembly name is equal to the project .csproj file name without an extension).
      • (Optional) -OutputPackagePath – the full path where the deployment package will be exported. Must include the package file name and extension.

        • For example, ./
        • When omitted, the deployment package is exported to the directory from which the script was executed.
      • (Optional) -KeepProductVersion – by default, the deployment package is created with a Build number equal to the source project’s package version, suffixed with the export date and time in format ‘yyyyMMddHHmm’.

        • Add this parameter if you wish to exclude the date and time from the Build number.
        • The Build number is displayed in the Deployment history within Xperience Portal.
      • (Optional)-StorageAssetsDeploymentMode [-Create] [-CreateUpdate] – determines whether the export preserves or overwrites the storage assets already present in Azure Blob storage:

        • When omitted, the -Create mode is used, and existing storage assets will not be overwritten and only new assets are added.

        • Use the -CreateUpdate parameter to allow overwriting of existing storage assets.

          If your deployment package contains media library files, the StorageAssetsDeploymentMode value must match the RestoreMode element value in the CD configuration file. See Reference - CI/CD object types.

The deployment package is now created, and you can deploy to the SaaS environment by uploading the deployment package to your Xperience Portal project.

Upload a deployment package to your Xperience Portal project

Once you have created a deployment package, trigger the deployment to the QA environment by uploading a deployment package to your Xperience Portal project directly from Xperience Portal or programmatically using Xperience Portal API.

Uploading a deployment package to Xperience Portal is unavailable during scheduled Xperience Portal project maintenance and initial project creation.

Upload a deployment package from Xperience Portal

  1. Access your Xperience Portal project.
  2. Navigate to the Deployments application.
  3. Under the QA environment, select Upload deployment package.
  4. Choose a valid deployment package (a ZIP archive with a maximum size of 2GB) and select Upload. You will be redirected to the Deployments application after the upload is complete.
  5. Allow a few minutes for the deployment to be displayed in the Deployment history section, where you can check the status of the deployment.

After the deployment finishes, your site is ready and running in the QA environment. Access the deployed application with the URL displayed under the QA environment section in the Deployments application in your Xperience Portal project.

To debug the deployment, you can download an archive with deployment logs under the Deployment history section.

Upload a deployment package using Xperience Portal API

You can upload the deployment package programmatically by sending a POST request authenticated with your Personal access token (PAT) to the deployment Xperience Portal API endpoint:

  1. Generate a Personal access token (PAT) and store it in a local file.

  2. Get your PROJECT_GUID in Xperience Portal Dashboard, in the Project info section, or from any URL when accessing Xperience Portal, for example,<PROJECT_GUID>/dashboard.

  3. Send a POST request to the deployment API endpoint. You can use the following PowerShell or cURL examples:

    Upload using PowerShell
     # Due to a PowerShell issue, we recommended disabling the progress bar to boost the performance significantly. 
     # See for more information.
     # Disable the progress bar
     $ProgressPreference = 'SilentlyContinue'
     # Upload the deployment package
     $headers = @{ Authorization = "Bearer <PERSONAL_ACCESS_TOKEN>" }
     Invoke-RestMethod -Uri<PROJECT_GUID> -Method Post -InFile <FILE_PATH> -ContentType "application/zip" -Headers $headers
     # Enable the progress bar
     $ProgressPreference = 'Continue'
    Upload using cURL
     curl -X POST -T <FILE_PATH> -H 'Content-Type: application/zip' -H 'Authorization: Bearer <PERSONAL_ACCESS_TOKEN>'<PROJECT_GUID>
  4. Navigate to the Deployments application.

  5. Allow a few minutes for the deployment progress to be displayed in the Deployment history section, where you can check the deployment progress.

After the deployment finishes, your site is ready and running in the QA environment. Access the deployed application with the URL displayed under the QA environment section in the Deployments application in your Xperience Portal project.

To debug the deployment, you can download an archive with deployment logs under the Deployment history section.