Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 538 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

17.latest (LTS)

Loading...

Loading...

Fundamentals

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Get to know Umbraco

All the fundamentals of using Umbraco - from making a local installation to extending the backend.

In this part of the Umbraco CMS documentation, you can get to know the product and the default functionality. It is here you start your Umbraco journey with the installation, setup, and basics of working with the CMS.

Cover

Setup

Find requirements for both local development and hosting as well as guides for installing and upgrading Umbraco CMS.

Cover

Backoffice

Learn about the different sections found in the Umbraco CMS backoffice and get an overview of the available features.

Cover

Data

Dive a little deeper and learn how to create different types of data directly from the Umbraco CMS backoffice.

Cover

Design

Get to know the different options the Umbraco CMS backoffice provides for designing your website.

Cover

Code

A high-level overview of working with some of the more advanced elements like services and notifications.

Umbraco CMS Documentation

Your main resource when building and managing an Umbraco CMS website.

Umbraco CMS is a flexible and editor-friendly Content Management System (CMS) that allows you to create beautiful and modern websites. Use the latest version of .NET, integrate with your favorite services, and help your customers launch a website tailored to their specific needs.

Learn more about Umbraco CMS and get an overview of the top features on Umbraco.com.

The documentation for Umbraco CMS provides information for experienced Umbraco and .NET developers. It also offers guides and high-level articles for people starting out with the CMS.

Creating a Basic WebsiteConfigurationRequirementsUsing Notifications

Legacy Documentation

Resources and links for older versions of Umbraco CMS.

This documentation platform covers only supported versions of the Umbraco CMS, excluding version 8. If you use an unsupported version, you need to go elsewhere.

Learn more about how long each major version of Umbraco is supported.

Legacy versions on GitHub

When a major version of Umbraco CMS goes End of Life (EOL), the documentation for this version will be unpublished 3 months later.

The documentation for all EOL versions will continue to be available on the UmbracoDocs GitHub repository.

Our Umbraco

The documentation for Umbraco 7 and 8 lives on .

Setup

Information on the requirements to setup, install & upgrade Umbraco

How to install and configure your Umbraco installation.

Requirements

Defines the system requirements to run Umbraco.

Umbraco installation steps and guidelines.

Covers the steps to upgrade your copy of Umbraco to a newer version.

Information about server setup for Umbraco including information about permissions and load balancing.

How to configure your Umbraco installation. Includes information about all of Umbraco's configuration files and options.

How to install the latest nightly builds.

Installation
Upgrade your project
Server setup
Configuration
Installing Nightly Builds
our.umbraco.com

Umbraco 7 Documentation

Umbraco 8 Documentation

Built-in Property Editors

Fundamentals

Learn the basics of working with Umbraco CMS. How to install and setup your first site is also included in this section.

Install Umbraco CMS

Ready to get started with Umbraco? Head over to the Setup section to learn how to install Umbraco CMS.

Tutorials

Find detailed step-by-step guides on everything from building a site from scratch to implementing a custom maintenance page.

Cover
Cover
Cover

Installation

Instructions on installing Umbraco on various platforms using various tools.

Install the latest .NET Software Development Kit (SDK)

Before you install Umbraco, you must ensure that you can run it on your machine.

  • Identify and install the latest .NET SDK.

Install Umbraco using CLI

The fastest way to get the latest version of Umbraco up and running is by using the command line (CLI).

  1. Open your command line.

  2. Install the Umbraco templates:

  1. Create a new project:

  1. Navigate to the newly created project folder. It will be the folder containing the .csproj file:

  1. Build and run the newly created Umbraco site:

  1. The console will output a message similar to: [10:57:39 INF] Now listening on: https://localhost:44388

We recommend setting up a developer certificate and running the website under HTTPS. If that has not yet been configured, run the following command:

  1. Open your browser and navigate to that URL.

  2. Follow the instructions to finish up the installation of Umbraco.

Members of the Umbraco Community have created a website that makes the installation of Umbraco a lot easier for you. You can find the website at . On the website, you can configure your options to generate the required script to run. Click on the Install Script tab to get the commands you need to paste into the terminal. This tab also includes the commands for adding a starter kit or unattended install which creates the database for you.

Alternative Methods for Installing Umbraco

There are numerous ways to install Umbraco. Below, you can find links to different installation methods that will help you install and set up Umbraco projects.

.NET CLI, included with the .NET Software Development Kit (SDK), can be used to install or uninstall .NET templates from NuGet. This can be done by using the dotnet new command on any OS. The underlying Template Engine enables the creation of custom templates which make new project bootstrapping much faster. With a few steps you can have an Umbraco project running without the need for a code editor.

Visual Studio is used to write native code and managed code supported by .NET and many others. Its built-in tools provide the ability to develop and execute applications for any platform. Developers will be able to install Umbraco without ever having to leave Visual Studio.

Learn how to run an already installed local installation of Umbraco.

Visual Studio Code is an editor with an embedded webserver (through the IIS Express extension). A fast way to get you up and running with Umbraco.

From Umbraco v9 and above you can use the Nightly Builds to get the latest version to use and test before it is released. Learn how to install the Nightly builds to get started.

Since Umbraco 9 it has been possible to run Umbraco CMS natively on Linux or macOS High Sierra. To get Umbraco running you will need to follow some steps.

Use the Unattended installs when spinning up Umbraco instances on something like Azure Web Apps to avoid having to run through the installation wizard.

Running Umbraco on Linux/macOS

Since Umbraco 9 it has been possible to run Umbraco CMS natively on Linux or macOS High Sierra 10.13 and newer.

With Umbraco CMS on .NET Core, Linux and macOS is natively supported with SQLite as the database.

In the below section, we describe how to get started with running Umbraco CMS on Linux or macOS.

How to get started running Umbraco CMS on Linux or macOS

To get started with Umbraco CMS first have a look at the .

Once you've made sure you meet the requirements it is time to install the Umbraco Templates on your system.

To do this follow the

Upgrade your project

Choose the guide fitting your upgrade situation and learn more about the recommended approach.

In this section, you will find resources to upgrade your Umbraco CMS project.

Before upgrading, it is recommended to read the article. This will give you an understanding of what goes on and the different topics you need to consider.

Upgrade Guides

Block Editors

The Block Editors are property editors that enabled you to build advanced editor tools using a set of predefined Document Types.

This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.

Umbraco CMS currently ships with two Block Editors: the Block List and the Block Grid.

Logging With Load Balancing

Umbraco v8+ uses Serilog for logging. When load balancing Umbraco consideration should be given as to how the log files from each server will be accessed.

There are many Serilog Sinks available and one of these may be appropriate to store logs for all servers in a central repository such as Azure Application Insights or Elmah.io.

For more information, see .

Block List

Block Grid

Customizing Block Editors

Creating custom views for blocks

Learn how to create custom views for the blocks used in your Block Grid or Block List property editors.

- how to upgrade Umbraco across major, minor, and patch versions.
  • Upgrade Unattended - configure Umbraco to upgrade in an unattended mode, avoiding the need to click through the installation wizard.

  • Version Specific Upgrades - details of changes to be aware of when upgrading to specific versions.

  • Downgrades and Re-running Migrations - discusses the possibility of downgrading to a previous version, along with the related topic of re-running the migrations that have occurred during an upgrade.

  • upgrade introduction
    Upgrade Details
    SeriLog Provided Sinks
    guide.

    With the templates installed on your system, it is now possible to create Umbraco projects.

    To create a project, there are two options:

    • Continue creating projects using the .NET CLI.

    • Create new projects using Visual Studio (only macOS).

    To create new projects using Visual Studio, you can use the Install using Visual Studio guide.

    Once you create a new project it will use SQLite by default on Linux/macOS.

    If you prefer using SQL Server as your database, you can either install it locally or run it via Docker.

    requirements for running Umbraco CMS
    Install using .NET CLI
    https://psw.codeshare.co.uk
    .NET CLI installation
    Visual Studio installation
    Run Umbraco on IIS
    VS Code installation
    Installing Nightly Builds
    Running Umbraco on Linux/macOS
    Install Umbraco unattended
    dotnet new install Umbraco.Templates
    dotnet new umbraco --name MyProject
    cd MyProject
    dotnet run
    dotnet dev-certs https --trust

    Requirements

    Browsers

    The Umbraco UI works in all modern browsers:

    • Chrome (Latest)

    • Edge (Chromium)

    • Firefox (Latest)

    • Safari (Latest)

    Local Development

    Below you can find the minimum requirements to run Umbraco on your machine:

    • One of the

    • One of the following .NET Tools or Editors:

      • with the

    Umbraco can be installed with a SQLite or SQL Server database and configured with a . For SQL Server, indicating a minimum supported version of SQL Server 2016.

    When using Visual Studio as your primary Integrated Development Environment (IDE) we recommend .

    Are you using Microsoft SQL as your data? The Umbraco Data Access Layer (DAL) does not support case-sensitive naming. When you use Microsoft SQL as your database, ensure that the database is created using a case-insensitive (CI) collation variant. For example, SQL_Latin1_General_CP1_CI_AS. Learn more about in the official Microsoft documentation.

    Hosting

    Recommendation requirements to run Umbraco

    As Umbraco releases are aligned to the .NET release cadence, it's also aligned with Microsoft's Long-term support policy for the underlying framework. For the best experience, we would recommend that you ensure to be on the latest and supported Microsoft versions to run and host Umbraco CMS:

    • and other

    For more information, see the article in the Microsoft documentation.

    You can use to manage the hosting infrastructure. All Umbraco Cloud plans are hosted on Microsoft Azure, which gives your site a proven and solid foundation.

    Other recommendation

    • Ability to set file permissions to include create/read/write (or better) for the user that "owns" the Application Pool for your site. This would typically be NETWORK SERVICE.

    Database Account Roles

    The database account used in the connection string will need permission to read and write from tables. It will also require permission to create schema during installs and upgrades:

    • The db_owner role has full permissions on the database.

    • To use an account with more restricted permissions, the db_datareader and db_datawriter roles will be needed for normal use to read from and write to the database. The db_ddladmin role, which can modify the database schema, is required for installs and upgrades of the CMS and/or any packages that create database tables.

    For more information on the Database-level roles, see the .

    For more information on how to create a database user via SQL, you can check the .

    Property Editors

    Learn more about the default property editors that ships with an Umbraco installation.

    A Property Editor is the editor that a Data Type references. A Data Type is defined by a user in the Umbraco backoffice and references a Property Editor. In Umbraco a Property Editor is defined in a JSON manifest file and associated JavaScript files.

    Are you looking for the Grid Layout or Nested Content?

    The following Property Editors have been removed with the release of Umbraco 14:

    • Grid Layout

    • Nested content

    We recommend using the or the instead.

    When creating a Data Type, specify the property editor for the Data Type to use by selecting from the "Property editor" list (as shown below).

    Umbraco comes pre-installed with many useful property editors.

    More information

    Tutorials

    Upgrade Unattended

    Learn how to enable unattended upgrades, allowing your project to upgrade without your interference.

    When upgrading your Umbraco project, you can enable the upgrade to run unattended. This means that you will not need to run through the installation wizard when upgrading.

    Are you running a load-balanced setup with multiple servers and environments?

    Check out the section about Unattended upgrades in a load-balanced setup.

    Enable the unattended upgrade feature

    1. Add the Umbraco:Cms:Unattended:UpgradeUnattended configuration key.

    2. Set the value of the key to true.

    Run the upgrade

    With the correct configuration applied, the project will be upgraded on the next boot.

    Boot order

    The Runtime level uses Run instead of Upgrade to allow the website to continue to boot up directly after the migration is run. This happens instead of initiating the otherwise required restart.

    The upgrade is run after Composers but before Components, and the UmbracoApplicationStartingNotification. This is because the migration requires services that are registered in Composers, and Components require that Umbraco and the database are ready.

    Unattended upgrades in a load-balanced setup

    Follow the steps outlined below to use unattended upgrades in a load-balanced setup.

    1. .

    2. Deploy to all environments.

    3. Set the Umbraco:CMS:Unattended:UpgradeUnattended configuration key to true for the Main server only.

    Server setup

    This section describes different ways of setting up servers for use with Umbraco

    Secure Sockets Layer (SSL) and HTTPS

    We strongly encourage the use of HTTPS with Umbraco installations especially in production environments. Using HTTPS will greatly enhance the security of your website, see the Security reference for more information.

    To ensure a stable and smoothly running Umbraco installation, these permissions need to be set correctly.

    Information about hosting a v9 application using IIS.

    Information on how to deploy Umbraco in a Load Balanced scenario and other details to consider when setting up Umbraco for load balancing.

    Best practices for running Umbraco on Azure Web Apps.

    The runtime mode setting optimizes Umbraco for the best development experience or optimal production environment.

    Sidebar

    This section explains how the concept of infinite editing using the Sidebar in the Umbraco backoffice works.

    Sidebar was previously called Infinite editor.

    This feature enables you to work with your content without losing the context of what you are doing.

    Document Types are in different sections than content but the sidebar enables you to make changes to them directly from the content you are editing.

    Sidebar

    In the example showcased above, new options are being added to a Data Type, without losing the context of the content. The example also shows how you can edit images, without being sent to the 'Media' section.

    Customize

    The sidebar is a feature that comes out of the box with Umbraco. The feature can be customized, which enables you as a developer to improve the workflow for your editors.

    Upgrades in Umbraco

    Introduces upgrades in Umbraco, describing what to consider when planning an upgrade.

    What is involved in an upgrade

    When upgrading to a new version of Umbraco, there are four key aspects of the migration to be aware of.

    Database schema and content

    Label

    Schema Alias: Umbraco.Label

    UI Alias: Umb.PropertyEditorUi.Label

    Returns: String

    Label is a non-editable control and can only be used to display a pre-set value.

    Data Type Definition Example

    Load Balancing the Backoffice

    This article contains specific information about load balancing the Umbraco backoffice. Ensure you read the and relevant articles about general load balancing principles before you begin.

    By default, the Umbraco load balancing setup assumes there is a single backoffice server and multiple front-end servers. From version 17, it's possible to load balance the backoffice. This means there's no need to differentiate between backoffice servers and front-end servers. However, this requires some additional configuration steps.

    Server Role Accessor

    Umbraco has the concept of server roles to differentiate between backoffice servers and front-end servers. Since all servers will be backoffice servers, we need to add a custom IServerRoleAccessor to specify this.

    SignalR In Load Balanced Environments

    When load balancing the backoffice, we also need to take care of the client-to-server communication outside of web requests. Umbraco uses SignalR to abstract away these types of communication. This also allows us to support load balancing by replacing how the communication is done by introducing a backplane.

    Introducing a SignalR Backplane

    A SignalR backplane is akin to a load balancer for direct client-to-server web traffic. It keeps track of which client is connected to which server. So that when a client sends a message, it arrives at the right server. It also allows any connected server to send a message to all clients, even those that are not directly connected to it.

    Radiobutton List

    Schema Alias: Umbraco.RadioButtonList

    UI Alias: Umb.PropertyEditorUi.RadioButtonList

    Returns: string

    Pretty much like the name indicates this Data type enables editors to choose from list of radio buttons and returns the value of the selected item as string.

    Data Type Definition Example

    Downgrades and Re-running Migrations

    Discusses the possibility of downgrading to a previous version, along with the related topic of re-running the migrations that have occurred during an upgrade

    Downgrades are not strictly supported

    Downgrades are not a supported feature of the Umbraco product.

    The primary reason for this is that the Umbraco migration scheme only supports upward migrations.

    When updating to a new version, often there are migrations to run that will make changes to the Umbraco schema and data. This is being done to bring the database to a state that will support the functionality of the version being upgraded to.

    There isn't an equivalent downward migration that will undo these changes.

    Entity Data Picker

    Schema Alias: Umbraco.EntityDataPicker

    UI Alias: Umb.PropertyEditorUi.EntityDataPicker

    Returns: Umbraco.Cms.Core.Models.EntityDataPickerValue

    Supported Data Source Types:

    The Entity Data Picker property editor allows editors to pick one or more entities from a configurable data source. The selected entities are stored as an array of strings, where each string represents the ID of the selected entity.

    Textarea

    Schema Alias: Umbraco.TextArea

    UI Alias: Umb.PropertyEditorUi.TextArea

    Returns: String

    Textarea is an HTML textarea control for multiple lines of text. It can be configured to have a fixed character limit, as well as define how big the space for writing can be. By default, there is no character limit unless it's specifically set to a specific value like 200 for instance. If you don't specify the number of rows, 10 will be the amount of rows the textarea will be occupying, unless changed to a custom value.

    Date Time Editors

    The Date Time property editors provide interfaces for selecting dates, times, and time zones. Each editor is designed for specific use cases, from basic date selection to comprehensive date/time handling with time zone support.

    These property editors replace the legacy [Date Time](../date-time.md) property editor. They offer more focused functionality and specific return types (such as DateOnly, TimeOnly, DateTime, or DateTimeOffset). You can switch from the legacy Date Time editor by changing your properties to use the new editors.

    Microsoft Visual Studio 2022 version 17.14 or higher.

    • Optional: JetBrains Rider version 2025.3.0.1 and higher

  • .NET Core CLI

  • SQL connection string (SQL Server)

  • Node.js version 24.11.1 and higher

  • IIS Supported releases

  • SQL Server Supported releases

  • SQLite

  • .NET 10.0 and higher
    .NET 10 - Supported OS versions
    Visual Studio Code
    IISExpress extension
    connection string
    support is aligned with Microsoft
    finding and downloading the Software Development Kits (SDKs) for Visual Studio
    collation modes
    Windows Supported releases
    MacOs Supported releases
    Ubuntu Supported distributions
    Linux Packages
    .NET Supported releases
    Host and deploy ASP.NET Core applications
    Umbraco Cloud
    Microsoft documentation
    Microsoft documentation
    Block Editor
    Rich Text Editor Blocks
    Built-in Property Editors in Umbraco
    Customizing Data Types
    How to create a custom Property Editor
    File & folder permissions
    Hosting v9+ in IIS
    Load Balanced setup
    Running Umbraco on Azure Web Apps
    Runtime modes

    Umbraco HQ offers a training course covering the basic concepts and features needed for building an Umbraco CMS website. The course targets frontend and backend developers, designers, and technical users who want to build a website from scratch in Umbraco,

    Explore the Fundamentals Training Course to learn more about the topics covered and how they can enhance your Umbraco development skills.

    Boot the Main server, and the upgrade will run automatically.
  • Wait for the upgrade to complete.

  • Boot the Read-Only servers and ensure they do not show the “Upgrade Required” screen.

  • Upgrade Umbraco via NuGet
    Start by implementing a custom IServerRoleAccessor that pins the role as SchedulingPublisher:

    You can now register this accessor either in Program.cs or via a Composer:

    This will ensure that all servers are treated as backoffice servers.

    Load Balancing Repository Caches

    One of the issues with load balancing the backoffice is that all servers will have their own repository caches. This means that if you make a change on one server, it won't be reflected on the other servers until their cache expires.

    To solve this issue, a cache versioning mechanism is used. This is similar to optimistic concurrency control. Each server has a version number for its cache. When a server makes a change, it updates the version identifier. The other servers can then check the version identifier before accessing the cache. If the cache is out of date, they invalidate it.

    This means the server needs to check the version identifier before a cache lookup. By default, this behavior is disabled. It's only required when load balancing the backoffice.

    You can enable this on the Umbraco builder, either in Program.cs or via a Composer:

    SignalR

    The Umbraco Backoffice uses SignalR for multiple things, including real-time updates and notifications. When load balancing the backoffice, it's important to ensure that SignalR is configured correctly. See the SignalR in a Backoffice Load Balanced Environment document for information regarding this.

    Background Jobs

    If you have custom recurring background jobs that should only run on a single server, you'll need to implement IDistributedBackgroundJob. See Scheduling documentation for more information.

    Temporary File Storage

    When load balancing the backoffice, temporary files uploaded through /umbraco/management/api/v1/temporary-file, for instance media uploads, must be accessible across all server instances.

    Temporary files are saved to umbraco/Data/TEMP/TemporaryFile/ by default.

    Azure deployments using scale out: No additional configuration is required, as the umbraco folder is shared between instances.

    Other Environments: Configure a shared storage location using the Umbraco:CMS:Hosting:TemporaryFileUploadLocation setting.

    Ensure this path points to a location accessible by all server instances, such as a shared drive or volume.

    Advanced Scenarios: You can implement a custom ITemporaryFileRepository for external storage solutions such as Azure Blob Storage.

    Load Balancing Overview
    Choosing the right backplane

    Choosing the right backplane comes down to a few factors:

    • Message throughput

    • Cost

    • What infrastructure you already have in place

    Microsoft has a good list of available backplanes in its SignalR load balancing article, including a list of well known third party offerings.

    Code examples

    The following code examples show how you can activate SignalR load balancing using an Umbraco composer.

    Both Umbraco and these composers use .AddSignalR(). This duplication isn't a concern as the underlying code registers the required services as singletons.

    Using existing infrastructure

    It is possible to use your existing database as a backplane. If this database is hosted in Azure it is not possible to enable Service Broker which will have an impact on message throughput. Nevertheless, it might be sufficient to cover your needs. For more information, check out the GitHub page.

    • Add a reference to the IntelliTect.AspNetCore.SignalR.SqlServer NuGet package.

    • Add the following composer to your project:

    Azure SignalR Service

    • Set up a resource as described in the Microsoft tutorial.

    • Make sure the connectionstring is set up under the following key: Azure:SignalR:ConnectionString.

    • Add a reference to Microsoft.Azure.SignalR NuGet package.

    • Add the following composer to your project:

    Given that, it can't be guaranteed that a database from a later version will work with an earlier one.

    If you wish to downgrade to an earlier version of Umbraco, it's best to also revert to a compatible database backup. You will need one from the version you are downgrading to.

    Other factors that may preclude downgrading include packages you may be using. They may not be compatible with the lower version or support downgrades themselves.

    Particular downgrades are possible and safe

    That said, between some versions, a downgrade may be possible and perfectly safe. There may be no migrations that run between them. Or, as is often the case, migrations are backward compatible (for example, adding a new, nullable field to a database table).

    You will need to determine this for yourself, likely via reviewing the changes and migrations between versions and testing.

    Once you have done that, this article will explain how to proceed with downgrading.

    Downgrade process

    Downgrading the Umbraco application itself is straightforward. In the same way as when upgrading, you update the dependency on Umbraco in your project, you do the same when downgrading:

    dotnet add package Umbraco.Cms --version <VERSION>

    If you try to start Umbraco, it's likely you will find an exception thrown on boot indicating a problem with the migration state. This is because the version of Umbraco you are running now doesn't recognize the state stored by the higher version you were running previously.

    To resolve this, you need to query the Umbraco database.

    There are two migration states stored for the CMS - for the core migrations and the pre-migrations (which run at different times on start-up).

    You can find the current state of these via:

    You then need to find the latest state for the version of Umbraco you want to downgrade to.

    To find the earlier states you have to look in the source code, specifically here for the pre-migrations and here for the core ones.

    Each migration is commented with the version it was added, so you can read off the latest one for the version you wish to run.

    Having found the state you need, you set it via a query of the form:

    Then restart Umbraco.

    Re-running Migrations

    A related topic is if you want to re-run the migrations from a prior version to the version you are on.

    This isn't something that should be needed in normal usage of Umbraco. Umbraco handles running the necessary migrations on start-up and keeps track of its state. However, if investigating an upgrade-related issue or testing an upgrade before running it in production, it's useful to know how to do this.

    Again you need to manipulate the migration state stored in the database.

    You can update these values to an earlier state, and on start-up Umbraco will recognize that it's not at the latest. It will re-run the migrations from the earlier state to the current one.

    For example, let's say you are running 16.2, and want to re-run the core migrations for 15 and 16. Here you would set the core migration state to the latest one from 14, via:

    And then restart Umbraco.

    Migrations are written to be idempotent, so they can be run multiple times. If the change the migration is making is already detected to be there, it should skip without throwing an exception.

    With Models Builder

    Without Models Builder

    Picker
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<EntityDataPickerTest>
    @{
        Layout = null;
    }
    <html lang="en">
    <head>
        <title>Entity Data Picker</title>
    </head>
    <body>
    @if (Model.MyEntityPicker is null)
    {
        <p>No entity picker value found</p>
    }
    else
    {
        <p>Data source: <strong>@Model.MyEntityPicker.DataSource</strong></p>
        <p>Picked IDs:</p>
        <ul>
            @foreach (string id in Model.MyEntityPicker.Ids)
            {
                <li>@id</li>
            }
        </ul>
    }
    </body>
    </html>
    appsettings.json
    {
        "Umbraco": {
            "CMS": {
                "Unattended": {
                    "UpgradeUnattended": true
                }
            }
        }
    }
     public class StaticServerAccessor : IServerRoleAccessor
    {
        public ServerRole CurrentServerRole => ServerRole.SchedulingPublisher;
    }
    umbracoBuilder.SetServerRegistrar(new StaticServerAccessor());
    umbracoBuilder.LoadBalanceIsolatedCaches();
    using Umbraco.Cms.Core.Composing;
    
    namespace Umbraco.Cms.Web.UI.SignalRLoadBalancing;
    
    public class SignalRComposer : IComposer
    {
        public void Compose(IUmbracoBuilder builder)
        {
            var connectionString = builder.Config.GetUmbracoConnectionString();
            if (connectionString is null)
            {
                return;
            }
    
            builder.Services.AddSignalR().AddSqlServer(connectionString);
        }
    }
    using Umbraco.Cms.Core.Composing;
    
    namespace Umbraco.Cms.Web.UI.SignalRLoadBalancing;
    
    public class SignalRComposer : IComposer
    {
        public void Compose(IUmbracoBuilder builder) => builder.Services.AddSignalR().AddAzureSignalR();
    }
    select value from umbracoKeyValue where [key] = 'Umbraco.Core.Upgrader.State+Umbraco.Core.Premigrations'
    select value from umbracoKeyValue where [key] = 'Umbraco.Core.Upgrader.State+Umbraco.Core'
    update umbracoKeyValue
    set value = '{state value}'
    where [key] = 'Umbraco.Core.Upgrader.State+Umbraco.Core'
    update umbracoKeyValue
    set value = '{EEF792FC-318C-4921-9859-51EBF07A53A3}'
    where [key] = 'Umbraco.Core.Upgrader.State+Umbraco.Core'
    @using Umbraco.Cms.Core.Models
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
    @{
        Layout = null;
        var entityDataPickerValue = Model.Value<EntityDataPickerValue>("myEntityPicker");
    }
    <html lang="en">
    <head>
        <title>Entity Data Picker</title>
    </head>
    <body>
    @if (entityDataPickerValue is null)
    {
        <p>No entity picker value found</p>
    }
    else
    {
        <p>Data source: <strong>@entityDataPickerValue.DataSource</strong></p>
        <p>Picked IDs:</p>
        <ul>
            @foreach (string id in @entityDataPickerValue.Ids)
            {
                <li>@id</li>
            }
        </ul>
    }
    </body>
    </html>
    Firstly there's the update of your Umbraco database's schema and how the content is stored. On occasion changes are necessary to support a new feature. This might be adding new tables or columns, or updating the stored data. This is something Umbraco takes care of for you. When Umbraco starts up and is running a newer version, the necessary changes will be detected and applied.

    As a developer responsible for the Umbraco website, there's nothing specific you need to do here. We will communicate key migrations that will happen on major version upgrades. As if you have a large site and significant amounts of data need to be updated, the migration could take some time to complete.

    Minor or patch versions may contain schema and content updates too, but they won't be extensive.

    Supported features

    Secondly you should review your use of property editors to ensure that they are available on the new version. It's rare for these to be removed, but it can happen when better alternatives are available. These are only removed in major versions and with plenty of notice on the announcements repository. Property editors for retirement will also have been indicated as legacy on earlier versions.

    Project customizations

    The third aspect is determining and verifying that your own code customizations are compatible with the new version. This includes C# server-side functionality, Razor templates and JavaScript backoffice extensions.

    Extensive efforts are made to avoid breaking changes that would cause issues for these types of customization other than in a major version update.

    Third-party packages

    Finally you should consider the packages you are using on your project. You will need to verify that the package will work with the new version of Umbraco. Or that a compatible upgrade of the package is available or planned.

    As above, breaking changes that would prevent packages from working other than in a major version update are avoided.

    Considerations for major version upgrades

    For the reasons described, projects always need to be considered case by case when upgrading to new versions.

    Umbraco communicates about the breaking changes in release blog posts and on the documented version specific upgrade details. There will be extended release candidate periods to ensure upgrades can be tested and to help package developers support new major versions.

    Breaking changes are minimized but there will be cases when such updates are needed. How straightforward the upgrade will be depends on the breaking changes included in the major and whether your project(s) are impacted by them.

    Before you upgrade

    The following lists a few things to be aware of before initiating an upgrade of your Umbraco CMS project.

    • Sometimes, there are exceptions to general upgrade guidelines. These are listed in the version-specific guide. Be sure to read this article before moving on.

    • Ensure your setup meets the requirements for the new versions you will be upgrading your project to.

    • Things may go wrong for different reasons. Be sure to always keep a backup of both your site's files and the database. This way, you can always return to a version that you know works.

    • Before upgrading to a new major version, check if the packages you're using are compatible with the version you're upgrading to. On the package's page on the , check the "Umbraco versions" field.

    Value type

    If you want to set a value other than a String, you can define the data using one of the other available Data Types. These include Decimal, Date/time, Time, Integer, and Big integer.

    There is also a Value Type: Long string if you need to set a long string value for your Label.

    Content Example

    Label Content Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Label Data Type definition
    Radiobutton List Data Type Definition

    You can use dictionary items to translate the values of a Radiobutton List property editor in a multilingual setup. For more details, see the Creating a Multilingual Site article.

    Content Example

    Radiobutton List Content

    MVC View Example

    Typed

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Data Type Definition Example
    Textarea Data Type Definition

    Settings

    Content Example

    Without a character and rows limit

    Textarea Content Example

    With a character limit and rows limit

    Textbox Content Example With Limits

    MVC View Example

    Without Models Builder

    With Models Builder

    Add value programmatically

    See the example below to learn how a value can be added or changed programmatically to a Textarea property. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Umbraco CMS currently ships with four Date Time editors:
    Editor
    Purpose
    Use Cases
    Return Type
    Preview

    Date selection

    Birthdays, deadlines, event dates

    DateOnly

    Time selection

    Business hours, schedules, time-based events

    TimeOnly

    Running Umbraco in Docker using Docker Compose

    Running Umbraco on docker locally using docker compose

    This article shows how to run Umbraco locally in Docker using Docker Compose. You can use either SQL Server or SQLite for development.

    This setup is intended for local development only. It is not recommended for production environments.

    Prerequisites

    Before you can run Umbraco in Docker, make sure the following are installed:

    • .NET SDK with Umbraco Templates v16 or higher

    • Docker Desktop

    Installing

    To install Umbraco using the provided Dockerfile and Docker Compose setup, follow these steps:

    Option 1: Using SQL Server

    1. Create a folder and navigate into it:

    1. Create a new Umbraco project with Docker support:

    1. Add Docker Compose files:

    The -P flag is required to specify the correct paths in the docker-compose file. The project is now ready to run with Docker Compose.

    The folder structure should now look like this:

    • MyDockerProject/

      • Database/

        • Dockerfile

        • healthcheck.sh

    The project now includes docker files for both Umbraco and the SQL server database.

    It also includes additional scripts to launch and configure the database and a .env file with the database password.

    1. Run the following command from the root folder (where docker-compose.yml is located):

    1. Access the site at http://localhost:44372.

    Option 2: Using SQLite

    1. Create a new folder and navigate into it:

    1. Create a new Umbraco project:

    1. Add a Dockerfile

    To speed up the build process, add a .dockerignore file to exclude unnecessary folders like .git, bin, and obj.

    1. Build the container:

    1. Run the container:

    1. Access the site at http://localhost:8080.

    Useful Commands

    There are some useful commands you can use to manage the docker containers:

    • docker compose down --volumes: Deletes containers and the volumes they use. This is useful if you want to start from scratch.

    Be careful with this command, as it deletes your database and all data in it.

    • docker compose up --build: Rebuild the images and start the containers. This is useful if you have made changes to the project and want to see them reflected on the running site.

    • docker compose watch: Start the containers and watch the default models folder. This means that if the project uses a source-code models builder the images are automatically rebuilt and restarts when you change the models.

    Bind Mounts (SQL Server setup)

    The docker compose file uses bind mounts for the following folders:

    • /wwwroot/media

    • /wwwroot/scripts

    • /wwwroot/css

    This is not meant to be used in production.

    For local development, however, this means that the files necessary for development are available from outside the container in your IDE. This allows development even though the project is running in docker.

    Template Options (SQL Server only)

    The umbraco-compose template supports:

    • -P or --project-name: The name of the project. This is required and used to set the correct paths in the docker-compose file.

    • -dbpw or --DatabasePassword: Used to specify the database password. This is stored in the .env file and defaults to: Password1234.

    File And Folder Permissions

    Information on file and folder permissions required for Umbraco sites

    To ensure a stable and smoothly running Umbraco installation, these permissions need to be set correctly. These permissions should be set up before or during the installation of Umbraco.

    The main account that requires 'modify' file permissions to be set on the folders below, is the account used start Umbraco. If Umbraco is hosted in IIS this will be the Application Pool Identity for the IIS website. Usually IIS APPPOOL\appPoolName or a specific local account or in some circumstances Network Service. If in doubt, ask your server admin / hosting company. Additionally, the Internet User (IUSR) account and IIS_IUSRS account only require 'read only' access to the site's folders.

    Generally, when developing locally with Visual Studio or Rider, permissions do not need to be strictly applied.

    If you have any specific static files/media items/etc, you should add the appropriate permissions accordingly.

    The permissions documentation should allow you to run a plain Umbraco install successfully.

    File / folder
    Permission
    Comment

    Decimal

    Schema Alias: Umbraco.Decimal

    UI Alias: Umb.PropertyEditorUi.Decimal

    Returns: decimal

    Data Type Definition Example

    Decimal Content Example

    In the example above the possible values for the input field would be [8, 8.5, 9, 9.5, 10]

    All other values will be removed in the content editor when saving or publishing.

    If the value of Step Size is not set then all decimal values between 8 and 10 is possible to input in the content editor.

    Content Example

    MVC View Example

    With Models Builder

    Without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Member Picker

    Schema Alias: Umbraco.MemberPicker

    UI Alias: Umb.PropertyEditorUi.MemberPicker

    Returns: IPublishedContent

    The member picker opens a panel to pick a specific member from the member section. The value saved is of type IPublishedContent.

    Data Type Definition Example

    Content Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    DateTime

    Schema Alias: Umbraco.DateTime

    UI Alias: Umb.PropertyEditorUi.DatePicker

    Returns: DateTime

    Displays a calendar UI for selecting dates which are saved as a DateTime value.

    New Date Time property editors are available. They offer more focused functionality and time zone support. These editors will eventually replace the current Date Time property editor, so consider using them for new implementations.

    Data Type Definition Example

    There is one setting available for manipulating the DateTime property.

    The setting involves defining the format. The default date format in the Umbraco backoffice is YYYY-MM-DD HH:mm:ss, but you can change it to a different format. See for the supported formats.

    Content Example

    MVC View Example - displays a datetime

    With Models Builder

    Without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Color Picker

    Schema Alias: Umbraco.ColorPicker

    UI Alias: Umb.PropertyEditorUi.ColorPicker

    Returns: String (Hexadecimal)

    Returns: Umbraco.Cms.Core.PropertyEditors.ValueConverters.ColorPickerValueConverter.PickedColor (When using labels)

    The Color picker allows you to set some predetermined colors that the editor can choose between.

    It is possible to add a label to use with the color.

    Data Type Definition Example

    Content Example

    Example with Models Builder

    Example without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Without labels

    With labels

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Block Level Variance

    An intro to achieving content variance at block level.

    In a variant context, a Block Editor behaves like any other Umbraco property editor by default. The Blocks contained within the editor "belong" to the Document variant, and there is no connection between Blocks across variants.

    In other words, both Block content and structure can vary between each Document variant.

    Default Block Editor behavior in the backoffice

    This is the desired behavior for many cases. However, in some cases it is preferable to have a shared Block structure across all variants, where only the Block content varies.

    This is known as Block Level Variance:

    Block Level Variance in the backoffice

    Block Level Variance is achieved when:

    • The Document Type is configured for variance, and

    • The Block Editor property is not configured for variance, and

    • The Block Editor property editor is configured to use that do vary.

    The "unexposed" Block state

    When adding a new variant Block to one Document variant, it is automatically added to all variants of the Document.

    The Block will start out in an "unexposed" state for all other Document variants than the one where it was added. It will remain like that for each variant until it is edited in that variant.

    The "unexposed" state is visualized by a dimmed-down icon and title (or likely a missing title, if is used):

    "Unexposed" Blocks are omitted from the published Document output. So, you do not need to worry about defensive coding to avoid rendering these Blocks.

    Invariance vs. Block Level Variance

    It is entirely possible to mix and match variance and invariance within the scope of Block Level Variance. Invariance is fully supported, both at Block level and at Block property level.

    Invariance within Block Level Variance follows the same rules as invariance at Document level:

    • Invariant content is added to and updated across all Document variants.

    • Invariant content is explicitly published for all published Document variants when one or more variants are published.

    Examples

    Consider a Document with English and Danish language variants, which is published in both languages.

    • An editor opens the English variant.

    • They add an invariant Block, and

    • They re-publish the English variant.

    Result: The new block will appear in both the English and Danish published content.

    • An editor opens the Danish variant.

    • They update an invariant property value in a variant Block, and

    • They re-publish the Danish variant.

    Result: The updated property value appears in both the English and Danish published content.

    Structure vs. Block Level Variance

    The Block Editor structure is invariant for Block Level Variance. This means that the structure follows the same rules for invariance as outlined in the section above.

    In other words: If an editor changes the order of the Blocks in one Document variant, it changes for all Document variants. The change is applied to all published Document variants, as soon as one or more variants are published.

    Member Group Picker

    Schema Alias: Umbraco.MemberGroupPicker

    UI Alias: Umb.PropertyEditorUi.MemberGroupPicker

    Returns: string

    The Member Group Picker opens a panel to pick one or more member groups from the Member section. The value saved is of type string (comma separated IDs).

    Data Type Definition Example

    Content Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    You can also add multiple groups by creating a comma separated string with the desired member group IDs.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Eye Dropper Color Picker

    Schema Alias: Umbraco.ColorPicker.EyeDropper

    UI Alias: Umb.PropertyEditorUi.EyeDropper

    Returns: string

    The Eye Dropper Color picker allows you to choose a color from the full color spectrum using HEX and RGBA.

    Data Type Definition Example

    Content Example

    Example with Models Builder

    Example without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Configuration

    In this article you can learn about the different options you have for configuring the Rich Text Editor (RTE).

    Toolbar

    You have full control over which options should be available on the RTE.

    Toolbar: All options enabled

    In the example above, all 38 options have been enabled. These options include font styles like bold and italics, bullet lists, and options to embed videos and insert images.

    You can customize the look of the toolbar:

    • Enhance the capabilities of the toolbar by enabling or disabling extensions.

    • Use the Toolbar designer to group together items and add additional rows if needed.

    Statusbar

    As well as the toolbar, you can configure extensions for the statusbar.

    Stylesheets

    To apply custom styles to the Rich Text Editor, you can select from any existing stylesheets.

    Stylesheets can be created in the Settings section. To learn more about this feature, see the article.

    Dimensions

    Define height and width of the editor displayed in the content section.

    Maximum size for inserted images

    Define the maximum size for images added through the Rich Text Editor.

    If inserted images are larger than the dimensions defined here, the images will be resized automatically.

    Overlay Size

    Select the width of the link picker overlay. The overlay size comes in three sizes: Small, Medium, Large, and Full.

    Available Blocks

    Blocks can be added as elements in the Rich Text Editor. Configuration and rendering of Blocks are described in the article.

    Image Upload Folder

    Images added through the RTE are by default added to the root of the Media library.

    Sometimes you might want to add the images to a specific folder. This folder can be configured using the "Image Upload Folder" setting.

    Ignore User Start Nodes

    Some of the backoffice users might be restricted to a specific part of the content tree. When the "Ignore User Start Nodes" is checked, the users can pick any piece of content from the content tree, when adding internal links through the RTE.

    Toggle

    Schema Alias: Umbraco.TrueFalse

    UI Alias: Umb.PropertyEditorUi.Toggle

    Returns: Boolean

    Toggle is a standard checkbox which saves either 0 or 1, depending on the checkbox being checked or not.

    Data Type Definition Example

    The Toggle property has a setting which allows you to set the default value of the checkbox, either checked (true) or unchecked (false).

    It is also possible to define a label, that will be displayed next to the checkbox on the content.

    Content Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Email Address

    In this article you can learn how to use the build in email property editor

    Schema Alias: Umbraco.EmailAddress

    UI Alias: Umb.PropertyEditorUi.EmailAddress

    Returns: String

    Displays an email address.

    Settings

    The Email Address Property Editor does not come with any further configuration. The property can be configured once it has been added to a Document Type.

    Content Example

    MVC View Example

    Without Modelsbuilder

    With Modelsbuilder

    Add value programmatically

    See the example below to learn how a value can be added or changed programmatically to an Email-address property. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    The value sent to an EmailAddress property needs to be a correct email address, For example: .

    It is recommended that you set up validation on this property, in order to verify whether the value added is in the correct format.

    Custom CSS properties

    Customize the appearance of the Rich Text Editor with custom CSS properties.

    You can customize the appearance of the Rich Text Editor using CSS properties by defining them in your CSS files.

    For example, to set the minimum height of all Rich Text Editors throughout the backoffice. You could use the following CSS rule:

    :root {
        --umb-rte-min-height: 300px;
    }

    For general information on working with stylesheets and JavaScript in Umbraco, check Stylesheets and JavaScript.

    If you wanted to target a specific Rich Text Editor, you can set the stylesheet directly in the configuration.

    Custom CSS properties reference

    The following CSS properties are available for customization:

    CSS Property
    Description
    Default Value

    The CSS custom properties may change in future versions of Umbraco. You can always find the latest values in the in the Umbraco CMS GitHub repository.

    Migrate content to Umbraco 15

    This article will help you migrate content to Umbraco 15, and outline options to skip this content migration

    Umbraco 15 changes the internal data format of all .

    If you maintain a large Umbraco site with extensive Block Editor usage, the upgrade to Umbraco 15+ might require a long-running content migration. For the duration of the migration, your site will be unresponsive and unable to serve requests.

    You can track the progress of the migration in the logs.

    It is advised to before upgrading. This will make the migration run faster.

    Parallelizing the content migration

    Local IIS With Umbraco

    This article describes how to run an Umbraco 9 site on a local IIS server.

    This is a quick guide on getting your Umbraco website running locally on IIS.

    The guide will assume you already have IIS configured and know your way around it, as well as having a local website you wish to host.

    Setting up prerequisites

    First, you need to ensure you have "Development time IIS support installed". To check this, go to the Visual Studio installer, click modify and check on the right side under "ASP.NET and web development":

    Once that is installed you should set up a new IIS site - and make sure to add the hostname to your hosts file as well. Here is my setup for an example:

    Install using Visual Studio

    A guide to install Umbraco CMS using Visual Studio.

    Prerequisites

    • Install the newest .

      • In Visual Studio 2022, the .NET CLI templates are enabled to appear, by default. For information on how to enable .NET CLI templates in Visual Studio 2019, see the

    Advanced Techniques With Flexible Load Balancing

    This describes some more advanced techniques that you could achieve with flexible load balancing

    The election process that runs during the startup of an Umbraco instance determines the server role that instance will undertake.

    There are two server roles to be aware of for flexible load balancing:

    • SchedulingPublisher - The Umbraco instance usually used for backoffice access, responsible for running scheduled tasks.

    • Subscriber - A scalable instance that subscribes to content updates from the SchedulingPublisher server, not recommended to be used for backoffice access.

    Running Umbraco On Azure Web Apps

    This section describes best practices with running Umbraco on Azure Web Apps

    What are Azure Web Apps

    They have been called a few names in the past, many people still know Azure Web Apps as Azure Web Sites.

    App Service is a fully Managed Platform for professional developers that brings a rich set of capabilities to web, mobile and integration scenarios. Quickly create and deploy mission critical web Apps that scale with your business by using Azure App Service.

    Umbraco will run on Azure Web Apps but there are some configuration options and specific Azure Web Apps environment limitations to be aware of.

    Time Only

    Schema Alias: Umbraco.TimeOnly

    UI Alias: Umb.PropertyEditorUi.TimeOnlyPicker

    Returns: TimeOnly?

    The Time Only property editor provides an interface for selecting times. It excludes date and time zone information, and returns strongly-typed TimeOnly values.

    Numeric

    Schema Alias: Umbraco.Integer

    UI Alias: Umb.PropertyEditorUi.Integer

    Returns: Integer

    Numeric is an HTML input control for entering numbers. Since it's a standard HTML element the options and behaviour are all controlled by the browser and therefore is beyond the control of Umbraco.

    Data Type Definition Example

    Repeatable Textstrings

    Schema Alias: Umbraco.MultipleTextstring

    UI Alias: Umb.PropertyEditorUi.MultipleTextString

    Returns: array of strings

    The Repeatable textstrings property editor enables a content editor to make a list of text items. For best use with an unordered-list.

    Data Type Definition Example

    Checkbox List

    Schema Alias: Umbraco.CheckBoxList

    UI Alias: Umb.PropertyEditorUi.CheckBoxList

    Returns: IEnumerable<string>

    Displays a list of preset values as a list of checkbox controls. The text saved is an IEnumerable collection of the text values.

    Unlike other property editors, the Option IDs are not directly accessible in Razor.

    Collection

    Schema Alias: Umbraco.ListView

    UI Alias: Umb.PropertyEditorUi.Collection

    Returns: IEnumerable<IPublishedContent>

    Collection displays a collection of categories when it is enabled on a Document Type with children.

    Document Blueprints

    Learn how to create and use Document Blueprints in Umbraco.

    Document Blueprints were previously called Content Templates.

    Document Blueprints Overview

    A Document Blueprint allows editors to preconfigure a content node. It serves as a reusable starting point when creating new content.

    Document Picker

    Schema Alias: Umbraco.ContentPicker

    UI Alias: Umb.PropertyEditorUi.DocumentPicker

    Returns: IPublishedContent

    The Document Picker opens a panel to pick a specific page from the content structure. The value saved is the selected nodes .

    The Document Picker was formerly known as the Content Picker in version 13 and below.

    Textbox

    How to use the TextBox property editors in Umbraco CMS.

    Schema Alias: Umbraco.TextBox

    UI Alias: Umb.PropertyEditorUi.TextBox

    Returns: String

    Textbox is an HTML input control for text. It can be configured to have a fixed character limit. The default maximum amount of characters is 512 unless it's specifically changed to a lower amount.

    Data Type Definition Example

    Date Only

    Schema Alias: Umbraco.DateOnly

    UI Alias: Umb.PropertyEditorUi.DateOnlyPicker

    Returns: DateOnly?

    The Date Only property editor provides an interface for selecting dates without including time or time zone information. It focuses purely on date selection and returns a DateOnly value.

    Rich Text Editor

    Schema Alias: Umbraco.RichText

    UI Alias: Umb.PropertyEditorUi.Tiptap

    Returns: HTML

    With the release of Umbraco 16, .

    The Rich Text Editor property editor is highly configurable and based on . Depending on the configuration setup, it provides editors a lot of flexibility when working with content.

    User Picker

    Schema Alias: Umbraco.UserPicker

    UI Alias: Umb.PropertyEditorUi.UserPicker

    Returns: IPublishedContent

    The user picker opens a panel to pick a specific user from the Users section. The value saved is of type IPublishedContent.

    Data Type Definition Example

    Data

    This section focuses on how to create data using the Umbraco backoffice

    This section focuses on how to create data using the Umbraco backoffice.

    There are three kinds of content in Umbraco:

    • Your normal website content exists in the content section.

    • Media content such as images, videos, and PDFs are stored in the Media section.

    • Finally, Members, are used for user profiles and frontend authentication which you can find in the Members section.

    Default Document Types

    On this page, you will find the default Document Types in Umbraco. If you want to use these document types, you can create them in the Settings section.

    On this page, you will find the default Document Types in Umbraco. If you want to use these Document Types, you can create them in the Settings section.

    Document Type

    A Document Type defines the content structure and fields that can be used across different content items. When creating a Document Type without a template, you focus solely on structured content without tying it to a specific design or layout. This is ideal for content that doesn’t require direct front-end rendering, such as reusable blocks or items managed within a headless CMS setup.

    Use a Document Type without a template for structured, reusable content like metadata schemas, settings, or components such as product details and author profiles.

    @{
        if (Model.HasValue("pageLabel")){
            <p>@(Model.Value("pageLabel"))</p>
        }
    }
    @{
        if (!string.IsNullOrEmpty(Model.PageLabel))
        {
            <p>@Model.PageLabel</p>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
        
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
        
        // Set the value of the property with alias 'pageLabel'. 
        content.SetValue("pageLabel", "A pre-set string value");
        
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'pageLabel'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MyLabel).Alias, "A pre-set string value");
    }
    @if (Model.HasValue("colorTheme"))
    {
        var value = Model.Value("colorTheme");
        <p>@value</p>
    }
    @if (Model.ColorTheme != null)
    {
        var value = Model.ColorTheme;
        <p>@value</p>
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
        
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
        
        // Set the value of the property with alias 'colorTheme'
        content.SetValue("colorTheme", "water");
                
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'colorTheme'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.ColorTheme).Alias, "water");
    }
    @{
        if (Model.HasValue("description")){
            <p>@(Model.Value<string>("description"))</p>
        }
    }
    @if (!Model.HasValue(Model.Description))
    {
       <p>@Model.Description</p>
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of your page
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
    
        // Get the page using the GUID you've just defined
        var content = ContentService.GetById(guid);
    
        // Set the value of the property with alias 'description'
        content.SetValue("description", "This is some text for the text area!");
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
    
        // Set the value of the property with alias 'description'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Description).Alias, "This is some text for the text area!");
    }

    A fundamental principle in Umbraco is that all content types have a definition (Document Types, Media Types, Member Types). These definitions are highly customizable, meaning you can add properties and have complete control over how the data is organized.

    Defining Content

    Defining Document Types, adding properties, and creating content.

    Creating Media

    Defining Media Types and uploading files to the media section, using upload fields and image cropper.

    Creating Members

    Defining Member Types and creating members for authentication and user profiles.

    Customizing Data Types

    Creating and editing Data Types.

    Scheduled Publishing

    Schedule when content should be published / unpublished automatically.

    Adding Tabs

    Overview of how to add and reorder tabs, convert a group to a tab, and manage the “Generic” tab

    Users

    Control who has access to the Umbraco backoffice and what permissions they have.

    Relations

    An introduction to Relations and Relation Types, creating, and managing relationships between different entities in Umbraco.

    Dictionary Items

    Using Dictionary Items, you can store a value for each language. Dictionary Items have a unique key that is used to fetch the value of the Dictionary Item.

    Content Version Cleanup

    How to keep the noise down whilst ensuring your important content versions stick around indefinitely.

    Umbraco Marketplace
    Element Types
    Umbraco Flavored Markdown
    Block Level Variance in the backoffice - with an unexposed block
    Stylesheets in the Backoffice
    Blocks in Rich Text Editor
    Enhance and customize the capabilities of the Rich Text Editor toolbar
    Statusbar with Word Count extension enabled

    /wwwroot/css

    Modify / Full control

    Should always have modify rights as the folder and its files are used for css files.

    /wwwroot/media

    Modify / Full control

    Should always have modify rights as the folder and its files are used for Media files uploaded via the Umbraco CMS backoffice.

    /wwwroot/umbraco

    Modify / Full control

    Should always have modify rights as the folder and its files are used by packages. Not part of your project by default.

    /wwwroot/scripts

    Modify / Full control

    Should always have modify rights as the folder and its files are used for script files.

    /appSettings*.json

    Modify / Full control

    Only needed for setting database and a global identifier during installation. So can be set to read-only afterwards for enhanced security.

    /App_Plugins

    Modify / Full control

    Should always have modify rights as the folder and its files are used by packages. Not part of your project by default.

    /umbraco

    Modify / Full control

    Should always have modify rights as the folder and its files are used for cache and storage.

    /Views

    Modify / Full control

    Should always have modify rights as the folder and its files are used for Templates and Partial views

    --umb-rte-min-height

    The minimum height of the rich-text-editor

    100%

    --umb-rte-max-height

    The maximum height of the rich-text-editor

    100%

    --umb-rte-width

    The width of the rich-text-editor

    unset

    --umb-rte-min-width

    The minimum width of the rich-text-editor

    unset

    --umb-rte-max-width

    The maximum width of the rich-text-editor

    100%

    --umb-rte-height

    The height of the rich-text-editor

    Rich Text Editor component base class

    100%

    setup.sql

  • startup.sh

  • MyDockerProject/

    • Your project files

    • Dockerfile

    • .dockerignore

  • .env

  • docker-compose.yml

  • /Views
  • /models

  • -p or --Port: Used to specify the port the site will run on. Defaults to 44372.

    Content Service
    Content Example
    Content Service
    Media Picker Data Type Definition
    Member Picker Content
    MomentJS.com
    Content Service
    Data Type Definiton
    Content Example
    Content Service
    Color Picker Data Type Definition
    Color Picker Content
    Content Service
    Member Group Picker Type Definition
    Member Grouep Picker Content
    Content Service
    Eye Dropper Color Picker Data Type Definition
    Eye Dropper Color Picker Content
    Content Service
    True/False Data Type Definition
    No Edit Content Example
    Content Service
    [email protected]
    Checkbox Example
    Single email address content example
    It is possible to parallelize the content migration. This will speed up the migration for large sites.

    For certain content structures, parallel content migration will fail. Therefore, parallel content migration is strictly opt-in.

    If parallel content migration fails, the database state will be rolled back to the last known good state. You can then disable parallel content migration, and try the migration again.

    To enable parallel content migration, add an IComposer implementation to configure the ConvertBlockEditorPropertiesOptions before initiating the upgrade process:

    Opting out of the content migration

    It is strongly recommended to let the migration run as part of the upgrade. However, if you are upgrading to Umbraco versions 15, 16, or 17, you can opt out of the migration. Your site will continue to work, albeit with a certain degree of performance degradation.

    Blocks in Rich Text Editors might not work as expected if you opt out of the content migration.

    You can opt out of migrating each Block Editor type individually. To opt-out, add an IComposer implementation to configure the ConvertBlockEditorPropertiesOptions before initiating the upgrade process:

    Subsequently, you are responsible for performing the content migration yourself. This must be done before upgrading past Umbraco 17.

    Custom code is required to perform the content migration. You can find inspiration in the core migrations:

    • ConvertBlockListEditorProperties for Block List properties.

    • ConvertBlockGridEditorProperties for Block Grid properties.

    • ConvertRichTextEditorProperties for Rich Text Editor properties.

    This custom code should not run while editors are working in the Umbraco backoffice.

    The site may require a restart once the content migration is complete.

    Block Editors
    clean up old content versions

    These new terms replace 'Master and Replica', in Umbraco versions 7 and 8.

    Explicit SchedulingPublisher server

    It is recommended to configure an explicit SchedulingPublisher server since this reduces the amount of complexity that the election process performs.

    The first thing to do is create a couple of small classes that implement IServerRoleAccessor one for each of the different server roles:

    then you'll need to replace the default IServerRoleAccessor for the your custom registrars. You'll can do this by using the SetServerRegistrar() extension method on IUmbracoBuilder from a Composer.

    Now that your subscriber servers are using your custom SubscriberServerRoleAccessor class, they will always be deemed 'Subscriber' servers and will not attempt to run the automatic server role election process or task scheduling.

    By setting your SchedulingPublisher server to use your custom SchedulingPublisherServerRoleAccessor class, it will always be deemed the 'SchedulingPublisher' and will always be the one that executes all task scheduling.

    Subscriber servers - Read-only database access

    This description pertains only to Umbraco database tables

    In some cases infrastructure admins will not want their front-end servers to have write access to the database. By default front-end servers will require write full access to the following tables:

    • umbracoServer

    • umbracoNode

    This is because by default each server will inform the database that they are active and more importantly it is used for task scheduling. Only a single server can execute task scheduling and these tables are used for servers to use a server role election process without the need for any configuration. So in the case that a subscriber server becomes the SchedulingPublisher task scheduler, it will require write access to all of the Umbraco tables.

    In order to have read-only database access configured for your front-end servers, you need to implement the Explicit SchedulingPublisher server configuration mentioned above.

    Now that your subscriber servers are using your custom SubscriberServerRoleAccessor class, they will always be deemed 'Subscriber' servers and will not attempt to run the automatic server role election process or task scheduling. Because you are no longer using the default ElectedServerRoleAccessor they will not try to ping the umbracoServer table.

    If using SqlMainDomLock on Azure WebApps then write-permissions are required for the following tables for all server roles including 'Subscriber'.

    • umbracoLock

    • umbracoKeyValue

    SQL Server Replica databases cannot be used as they are read-only without replacing the default MainDomLock with a custom provider.

    Controlling how often the load balancing instructions from the database are processed and pruned

    The configurations can be adjusted to control how often the load balancing instructions from the database are processed and pruned.

    Below is shown how to do this from a JSON configuration source.

    Options:

    • TimeToRetainInstructions - The timespan to keep instructions in the database; records older than this number will be pruned.

    • MaxProcessingInstructionCount - The maximum number of instructions that can be processed at startup; otherwise the server cold-boots (rebuilds its caches)

    • TimeBetweenSyncOperations - The timespan to wait between each sync operations

    • TimeBetweenPruneOperations - The timespan to wait between each prune operation

    These setting would normally be applied to all environments as they are added to the global app settings. If you need these settings to be environment specific, we recommend using environment specific appSetting files.

    mkdir MyDockerProject
    cd MyDockerProject
    dotnet new umbraco -n MyDockerProject --add-docker
    dotnet new umbraco-compose -P "MyDockerProject"
    docker compose up
    mkdir MyDockerSqliteProject
    cd MyDockerSqliteProject
    dotnet new umbraco -n MyDockerSqliteProject
    FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
    WORKDIR /app
    EXPOSE 8080
    
    FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
    ARG BUILD_CONFIGURATION=Release
    WORKDIR /src
    COPY ["MyDockerSqliteProject/MyDockerSqliteProject.csproj", "MyDockerSqliteProject/"]
    RUN dotnet restore "MyDockerSqliteProject/MyDockerSqliteProject.csproj"
    COPY . .
    WORKDIR "/src/MyDockerSqliteProject"
    RUN dotnet build "MyDockerSqliteProject.csproj" -c  $BUILD_CONFIGURATION -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "MyDockerSqliteProject.csproj" -c  $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "MyDockerSqliteProject.dll"]
    docker build -t umbraco-sqlite .
    docker run -p 8080:8080 umbraco-sqlite
    @Model.MyDecimal
    @Model.Value("MyDecimal")
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'myDecimal'. 
        content.SetValue("myDecimal", 3);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'myDecimal'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MyDecimal).Alias, 3);
    }
    @{
        if (Model.HasValue("author"))
        {
            var member = Model.Value<IPublishedContent>("author");
            @member.Name
        }
    }
    @{
        if (Model.Author != null)
        {
            var member = Model.Author;
            @member.Name
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Create a variable for the GUID of the member ID
        var authorId = Guid.Parse("ed944097281e4492bcdf783355219450");
    
        // Set the value of the property with alias 'author'. 
        content.SetValue("author", authorId);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'author'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Author).Alias, udi);
    }
    @Model.DatePicker
    @Model.Value("datePicker")
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'datePicker'
        content.SetValue("datePicker", DateTime.Now);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
    
        // Set the value of the property with alias 'datePicker'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.DatePicker).Alias, DateTime.Now);
    }
    @{
         // Model has a property called "Color" which holds a Color Picker editor
        var hexColor = Model.Color;
        // Define the label if you've included it
        String colorLabel = Model.Color.Label;
    
        if (hexColor != null)
        {
            <div style="background-color: #@hexColor">@colorLabel</div>
        }
    }
    @using Umbraco.Cms.Core.PropertyEditors.ValueConverters
    @{
        // Model has a property called "Color" which holds a Color Picker editor
        var hexColor = Model.Value("Color");
        // Define the label if you've included it
        var colorLabel = Model.Value<ColorPickerValueConverter.PickedColor>("Color").Label;
    
        if (hexColor != null)
        {
            <div style="background-color: #@hexColor">@colorLabel</div>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'color'. 
        // The value set here, needs to be one of the colors on the Color Picker
        content.SetValue("color", "38761d");
    
        // Save the change
        ContentService.Save(content);
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'color'. 
        // The value set here, needs to be one of the colors on the Color Picker
        content.SetValue("color", "{'value':'000000', 'label':'Black', 'sortOrder':1, 'id':'1'}");
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'color'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Color).Alias, "38761d");
    }
    @if (Model.HasValue("memberGroup"))
    {
        var memberGroup = Model.Value<string>("memberGroup"); 
        <p>@memberGroup</p>
    }
    @if (!string.IsNullOrEmpty(Model.MemberGroup))
    {
        <p>@Model.MemberGroup</p>
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
        
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'memberGroup'. The value is the specific ID of the member group
        content.SetValue("memberGroup", 1067);
                
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Set the value of the property with alias 'memberGroup'. 
        content.SetValue("memberGroup", "1067","1068");
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'memberGroup'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MemberGroup).Alias, 1067);
    }
    @{
        var color = Model.Color?.ToString();
    
        if (color != null)
        {
            <body style="background-color: @color"></body>
        }
    }
    @{
        var color = Model.Value<string>("Color");
    
        if (color != null)
        {
            <body style="background-color: @color"></body>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'color'.
        content.SetValue("color", "#6fa8dc");
        
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'color'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Color).Alias, "#6fa8dc");
        
        // Set the value of the property with alias 'theme'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Theme).Alias, "rgba(111, 168, 220, 0.7)");
    }
    @{
        if (!Model.Value<bool>("myCheckBox"))
        {
            <p>The Checkbox is not checked!</p>
        }
    }
    @{
        if (!Model.MyCheckbox)
        {
            <p>The Checkbox is not checked!</p>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
        
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'myCheckBox'
        content.SetValue("myCheckBox", true);
                
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'myCheckBox'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MyCheckBox).Alias, true);
    }
    @if (Model.HasValue("email"))
    {
        var emailAddress = Model.Value<string>("email");
        <p>@emailAddress</p>
    }
    @if (!string.IsNullOrWhiteSpace(Model.Email))
    {
        <p>@Model.Email</p>
    }
    @using Umbraco.Cms.Core.Services;
    
    @inject IContentService Services;
    @{
        // Get access to ContentService
        var contentService = Services;
    
        // Create a variable for the GUID of your page
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
    
        // Get the page using the GUID you've just defined
        var content = contentService.GetById(guid);
        // Set the value of the property with alias 'email'
        content.SetValue("email", "[email protected]");
    
        // Save the change
        contentService.Save(content);
    }
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_0_0;
    
    namespace UmbracoDocs.Samples;
    
    public class DisableBlockEditorMigrationComposer : IComposer
    {
        [Obsolete]
        public void Compose(IUmbracoBuilder builder)
            => builder.Services.Configure<ConvertBlockEditorPropertiesOptions>(options =>
            {
                // setting this to true will parallelize the migration of all Block Editors
                options.ParallelizeMigration = true;
            });
    }
    DisableBlockEditorMigrationComposer.cs
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_15_0_0;
    
    namespace UmbracoDocs.Samples;
    
    public class DisableBlockEditorMigrationComposer : IComposer
    {
        [Obsolete]
        public void Compose(IUmbracoBuilder builder)
            => builder.Services.Configure<ConvertBlockEditorPropertiesOptions>(options =>
            {
                // setting this to true will skip the migration of all Block List properties
                options.SkipBlockListEditors = false;
    
                // setting this to true will skip the migration of all Block Grid properties
                options.SkipBlockGridEditors = false;
    
                // setting this to true will skip the migration of all Rich Text Editor properties
                options.SkipRichTextEditors = false;
            });
    }
    public class SchedulingPublisherServerRoleAccessor : IServerRoleAccessor
    {
        public ServerRole CurrentServerRole => ServerRole.SchedulingPublisher;
    }
    
    public class SubscriberServerRoleAccessor : IServerRoleAccessor
    {
        public ServerRole CurrentServerRole => ServerRole.Subscriber;
    }
    // This should be executed on your single `SchedulingPublisher` server
    builder.SetServerRegistrar<SchedulingPublisherServerRoleAccessor>();
    
    // This should be executed on your `Subscriber` servers
    builder.SetServerRegistrar<SubscriberServerRoleAccessor>();
    {
        "Umbraco": {
            "CMS": {
                "Global": {
                    "DatabaseServerMessenger": {
                        "MaxProcessingInstructionCount": 1000,
                        "TimeBetweenPruneOperations": "00:01:00",
                        "TimeBetweenSyncOperations": "00:00:05",
                        "TimeToRetainInstructions": "2.00:00:00"
                    }
                }
            }
        }
    }
    IIS site example

    For the path you want to point it at the root of your site - where the .csproj file is.

    Add permissions to NuGet cache folder

    You might need to change permissions for the NuGet cache folder - C:\users\<username>\.nuget\packages. The user or group (IIS_IUSRS) that the IIS site is running on requires Read permissions on this folder because this is where some of the files for Umbraco and Umbraco packages are being served from during development. If the IIS user or group does not have permission to read from the NuGet cache folder, you could run into a DirectoryNotFoundException while running the site.

    When the site is published these files are copied from the NuGet cache folder to wwwroot/umbraco and wwwroot/App_Plugins and these folders will typically have the correct permissions. For more information on setting permissions, see the File and folder permissions article.

    Add new launch profile

    At this point you can go to your Visual Studio solution of the site and in the Properties folder there is a launchSettings.json file, that looks like this:

    You can add a new profile called IIS, and point it at your local domain. Here it is with my example domain:

    At this point IIS will be added to the launch profiles, and you can run the site from Visual Studio by choosing IIS in the dropdown:

    Launch profiles

    And finally the site is running from your local IIS:

    Local IIS site
    Checking the IIS module exists
    article.
  • Check the Requirements to ensure you have everything you need to start your Umbraco project.

  • Quick Start

    This is an abbreviated version of the installation steps. Jump to the Create a new project section for a more thorough guide.

    • Open Visual Studio.

    • Go to File > New > Project, search for Umbraco.

    • Choose Umbraco Project (Umbraco HQ) then click Next.

    • Choose or specify the parameters, leave the default or leave them all empty.

    • Click Create.

    • Use CTRL+F5 to run the project and start the Umbraco installer.

    Video Tutorial

    Create a new Umbraco project

    To install Umbraco, follow these steps:

    1. Install the latest .NET SDK.

    2. Run dotnet new install Umbraco.Templates to install the project templates.

    Create the Visual Studio project

    Go to File > New > Project and search for Umbraco in the Search for templates field.

    The Create a new project dialog in Visual Studio.

    Once you select Umbraco Project (Umbraco HQ) navigate to the next step by clicking Next.

    Configure project

    In this step, you will be able to give your project a name specific to the project you are creating.

    The Configure your new project dialog in Visual Studio.

    Refrain from changing the Solution name, as this will cause a namespace conflict with the CMS itself.

    Additional information

    In the next step, you are able to specify some additional parameters like the Target framework. The rest are optional.

    The Additional information dialog in Visual Studio.

    You can then click the Create button and your Umbraco Project will be ready for you.

    Overview of files in the project solution

    Running the site

    You can now run the site through Visual Studio using F5 or the Debug button.

    Follow the installation wizard and after a few steps, you will get a message saying the installation was a success.

    Next steps

    You are now ready to start building your Umbraco project. Have a look below for different resources on the next steps.

    • Getting Started with Umbraco

    • Tutorial: Create a website from scratch

    • Find different options for hosting your Umbraco website

    • Learn about configuration in Umbraco CMS

    Umbraco dotnet templates
    .NET CLI Templates in Visual Studio

    Recommended configuration

    You need to add these configuration values. E.g in a json configuration source like appSettings.json:

    You can also copy the following JSON directly into your Azure Web App configuration via the Advanced Edit feature.

    image

    Remember to add an ASPNETCORE_ENVIRONMENT variable with values Development, Staging, or Production.

    The minimum recommended Azure SQL Tier is "S2", however noticeable performance improvements are seen in higher Tiers

    If you are load balancing or require the scaling ("scale out") ability of Azure Web Apps then you need to consult the Load Balancing documentation. This is due to the fact that a lot more needs to be configured to support scaling/auto-scaling.

    Storage

    It is important to know that Azure Web Apps uses a remote file share to host the files to run your website. This is due to the files running your website do not exist on the machine running your website. In many cases this isn't an issue. It can become one if you have a large amount of IO operations running over remote file-share.

    Issues with read-only filesystems

    Although Umbraco can be configured to use environmental storage it still requires its working-directory to be writable. If Umbraco is deployed to a read-only file system it will fail to boot.

    For example, Azure's Run from Package feature is not supported by Umbraco. To check if your web app is using this feature you can check the WEBSITE_RUN_FROM_PACKAGE environment variable.

    Scaling

    If you require the scaling ("scale out") ability of Azure Web Apps you need to consult the Load Balancing documentation. This is due to the fact that a lot more needs to be configured to support scaling/auto-scaling.

    Web worker migrations

    It's important to know that Azure Web Apps may move your website between their 'workers' at any given time. This is normally a transparent operation. In some cases you may be affected by it if any of your code or libraries use the following variables:

    • Environment.MachineName (or equivalent)

    When your site is migrated to another worker, these variables will change. You cannot rely on these variables remaining static for the lifetime of your website.

    How to find the Linux App Service Logs

    The quickest way to get to your logs is using the following URL template and replacing {app} with your Web App name:

    https://{app}.scm.azurewebsites.net/api/logstream

    You can also find this in the KUDU console by clicking Advanced Tools > Log Stream on the Web App in the Azure Portal.

    Web App secret management

    Consult the Azure Key Vault documentation if you would like to directly reference Azure Key Vault Secrets to your Azure Web App.

    You can read more about them here
    Configuration

    You can configure this property editor in the same way as any standard property editor, using the Data Types admin interface.

    To set up a property using this editor, create a new Data Type and select Time Only from the list of available property editors.

    You will see the configuration options as shown below.

    Time Only property editor configuration
    • Time format - Specifies the level of precision for time values shown and stored by the editor.

    Time format

    • HH:mm - Displays hours and minutes (e.g., 14:30). Suitable for most general use cases.

    • HH:mm:ss - Displays hours, minutes, and seconds (e.g., 14:30:45). Use this when you need more precise timing.

    Editing experience

    Adding or editing a value

    You will be presented with a time input. Unlike date-time editors, this editor focuses only on the time component.

    Time Only property editor interface

    Rendering

    The value returned will have the type TimeOnly?.

    Display the value

    With Models Builder:

    Without Models Builder:

    Add values programmatically

    This property editor stores values as a JSON object. The object contains the time as an ISO 8601 string with a default date and UTC offset.

    Storage format

    The property editor stores values in this JSON format:

    The property editor handles time-only values. Date is set to a default value (0001-01-01) and offset to +00:00 for storage consistency. The date component is ignored in the Time Only context.

    1. Create a C# model that matches the JSON schema.

    2. Convert your existing time value to DateTimeOffset for storage.

      If you have a TimeOnly:

      If you have a DateTime:

    3. Create an instance of the class with the DateTimeOffset value.

    4. Inject the IJsonSerializer and use it to serialize the object.

    5. Inject the IContentService to retrieve and update the value of a property of the desired content item.

    Numeric Data Type Definition

    Minimum

    This allows you to set up a minimum value. If you will always need a minimum value of 10 this is where you set it up and whenever you use the datatype the value will always start at 10. It's not possible to change the value to anything lower than 10. Only higher values will be accepted.

    Step Size

    This allows you to control by how much value should be allowed to increase/decrease when clicking the up/down arrows. If you try to enter a value that does not match with the step setting then it will not be accepted.

    Maximum

    This allows you to set up a maximum value. If you will always need a maximum value of 100 this is where you set it up. It's not possible to change the value to anything higher than 100. Only lower values will be accepted.

    Settings

    Content Example

    Numeric Content Definition

    MVC View Examples

    Rendering the output casting to an int (without Models Builder)

    By casting the output as an int it's possible for you to do mathematical operations with the value.

    Rendering the output casting to a string (Without Models Builder)

    You can also render the output by casting it to a string, which means you will not be able to do mathematical operations

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Repeatable textstrings Data Type Definition

    Content Example

    Repeatable textstrings Content

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    To add multiple values to the repeatable text strings property editor you have to put each value on a new line. This can be achieved using either \r\n\ or Environment.NewLine.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Data Type Definition Example
    True/Checkbox List Definition

    You can use dictionary items to translate the options in a Checkbox List property editor in a multilingual setup. For more details, see the Creating a Multilingual Site article.

    Content Example

    Checkbox List Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Configure Collection

    Once Collections are configured, the parent content item displays its child items in a list view format within the content item itself. If Collections are not configured, the child items are displayed directly in the Content Tree, rather than being grouped within the parent content item.

    Enable Collection example

    Settings

    Collection settings example

    Columns Displayed

    It is possible to add more columns to the collection, via adding the properties through the picker modal. These properties are based on the Data Types which are used by the Document Type. The properties will listed for selection.

    Collection property picker example

    Once you have selected a column you want to display, define what its heading label should be and what kind of value it should display. You can also move the headers around, re-ordering how they should look. This is done by the move icon on the left side of the alias.

    The template section is where you define what kind of value you want to display. The value of the column is in the value variable.

    Layouts

    Collection comes with two layouts by default. A list and a grid view. These views can be disabled if you are not interested in any of them.

    A minimum of one layout needs to be enabled for Collection to work.

    You can also make your own layout and add it to the settings. For example, if you wanted to change the width or length of the grid, you will be able to do so.

    Order By

    Will sort your collection by the selection you choose in the dropdown. By default it selects "Last edited" and you get the following three columns:

    • Last edited - When the content node was last edited and saved.

    • Name - Name of the content node(s).

    • Created by - This is the user who the content node was created by.

    You can add more sorting to this collection by adding more datatypes to the columns in the "Columns Displayed" section.

    Order Direction

    You can select order of the content nodes displayed, "Ascending [a-z]" or "Descending [z-a]". The order is affected by the "Order By" selection.

    Page Size

    Defines how many child content nodes you want to see per page. This will limit how many content items you will see in your collection. If you set it to 5, then only 5 content items will be shown in the collection.

    Workspace View icon

    Support for changing the Workspace View icon has not been implemented yet.

    Changes the icon in the backoffice of the collection. By default it will look like the image below.

    Collection icon example

    Workspace View name

    Support for changing the Workspace View name has not been implemented yet.

    You can change the name of the collection itself. Default if empty: 'Child Items'.

    Show Content Workspace View First

    Support for setting the Content Workspace View First has not been implemented yet.

    Enable this to show the Content Workspace View by default instead of the collection's.

    Content Example

    Generic field value

    This example shows how to use a generic field from a child item and display its value in a collection.

    Collection content email label template

    You can use the Umbraco Flavored Markdown syntax to display the label value. Here, the {=value} placeholder retrieves the value of the Email property and displays it in the collection, as shown in the image below:

    Collection content email value displayed

    Content name

    First, a Content Picker property needs to be present on the content item. In this example, the child item has gotten a Content Picker Data Type with the alias of contentPicker.

    Collection content picker

    The child item has a document and the value that should be displayed is the name of the picked value. The next step is to reconfigure the template value in the collection setting.

    Collection content picker

    This will take the value picked up by the content picker.

    Collection content picker with picked value

    And display it in the collection. Shown in the example below:

    Collection view cards with content picker value
    Collection example
    Method 1 – Create a Document Blueprint from the Content Section

    Before using this method, make sure you have already created some content.

    1. Go to the Content section and select an existing content node.

    Content-Menu
    1. Click the ... menu next to the node and choose Create Document Blueprint.

    Action Button
    1. Enter a Name for the new blueprint.

    Document Blueprint Name Field
    1. Click Save.

    The new blueprint will appear under the Document Blueprints folder in the Settings section.

    New Document Blueprint

    If you don’t see the new blueprint, try refreshing your browser.

    Method 2 – Create a Document Blueprint from the Settings Section

    1. Go to the Settings section.

    2. Click the ... menu next to the Document Blueprints tree.

    3. Select Create....

    Create Document Blueprint
    1. Choose the Document Type you want to base the blueprint on.

    Select Content Type

    You can only create Document Blueprints from Document Types or Document Types with Templates.

    1. Enter a Name for the blueprint.

    2. Click Save.

    The new blueprint will appear under the Document Blueprints folder in the Settings section.

    Edit a Document Blueprint

    To edit an existing document blueprint, follow these steps:

    1. Go to the Settings section.

    2. Open the Document Blueprints folder.

    3. Select the blueprint you want to edit.

    4. Make your changes.

    5. Click Save.

    Edit Document Blueprint

    Use a Document Blueprint

    Once you have created a document blueprint, you can use it to create new content nodes.

    To use a document blueprint, follow these steps:

    1. Go to the Content section.

    2. Click the ... menu next to the root node and select Create.

    Create From Template
    1. Select the Document Type that has an associated blueprint.

    Select the Document Type
    1. Choose how to create the new content:

      • Use the Document Blueprint

      • Start with a blank node

    Select Template
    The renaming is purely a client-side UI change, meaning the property editor still uses the Umbraco.ContentPicker schema alias.

    The change was made as the word Content in the backoffice acts as an umbrella term covering the terms Document, Media, and Member.

    Data Type Definition Example

    Document Picker Data Type Definition

    Document Picker Example

    Document Picker Content

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    UDI
    Textbox Data Type Definition

    Content Example

    Without a character limit

    Textbox Content Example

    With a character limit

    Textbox Content Example Without a Character Limit

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Configuration

    You can configure this property editor in the same way as any standard property editor, using the Data Types admin interface.

    To set up a property using this editor, create a new Data Type and select Date Only from the list of available property editors.

    This editor has no configuration options.

    Editing experience

    Adding or editing a value

    You will be presented with a date input.

    Date Only property editor interface

    Rendering

    The value returned will have the type DateOnly?.

    Display the value

    With Models Builder:

    Without Models Builder:

    Add values programmatically

    This property editor stores values as a JSON object. The object contains the date as an ISO 8601 string with midnight time and UTC offset.

    Storage format

    The property editor stores values in this JSON format:

    The property editor handles date-only values. Time is set to 00:00:00 and offset to +00:00 for storage consistency. These time components are ignored in the Date Only context.

    1. Create a C# model that matches the JSON schema.

    2. Convert your existing date value to DateTimeOffset for storage.

      If you have a DateOnly:

      If you have a DateTime:

    3. Create an instance of the class with the DateTimeOffset value.

    4. Inject the IJsonSerializer and use it to serialize the object.

    5. Inject the IContentService to retrieve and update the value of a property of the desired content item.

    Configuration options

    Customize everything from toolbar options to editor size to where pasted images are saved.

    Style Menu

    Define a cascading text formatting and style menu for the Rich Text Editor toolbar.

    Blocks

    Use Blocks to define specific parts that can be added as part of the markup of the Rich Text Editor.

    Extensions

    Extend the functionality of the Rich Text Editor with extensions.

    Custom CSS properties

    Customize the appearance of the Rich Text Editor with custom CSS properties.

    Data Type Definition Example

    Rich Text Editor - Data Type

    Content Example

    Rich Text Editor - Content Example

    MVC View Example

    With Models Builder

    Without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string.

    the TinyMCE UI option for the Rich Text Editor is removed
    Tiptap
    Media Picker Data Type Definition

    Content Example

    Member Picker Content

    MVC View Example

    Getting the Value of the property will return the user ID - properties of the User can be accessed by referencing UserService.

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Document Type with Template

    A Document Type with a Template combines the content structure with a predefined visual presentation. This approach links your structured content with a specific page design, ensuring a consistent and cohesive look and feel across your site. It allows you to manage content and its appearance separately, which makes updates more efficient.

    Use a Document Type with a template for pages like blog posts, landing pages, or services that appear directly on the website.

    Element Type

    An Element Type is a Document Type without a template designed for reusable and repeatable set of properties. These are primarily used in editors like the Block List Editor or Block Grid Editor to create structured, nested content.

    Element Types are not part of the Content tree and cannot render directly on the front end. When created, the Is an Element Type flag in the Permissions tab is automatically set to True.

    Element type

    Use an Element Type when defining building blocks for complex page layouts, such as grid blocks or call-to-action sections. They are an essential part of modular content design.

    Folder

    The Folder in the Document Types section is used to organize and structure your Document Types within the Settings section. It serves purely as an organizational container, with no impact on the Content section or site functionality.

    Use a Folder to create logical groupings, like a folder named Compositions to hold all your Composition Document Types. This makes it easier to navigate and manage your Document Types, especially in larger projects.

    Folders are a powerful tool to keep your Document Types organized and your backoffice tidy.

    Create Document Type

    Date Time (with Time Zone)

    Full date, time, and time zone support

    International apps, timezone-aware scheduling

    DateTimeOffset

    Date Time (Unspecified)

    Date and time without a defined time zone

    Local events, compatibility with Date Time

    DateTime

    Date Only
    Time Only
    Date Only editor
    Time Only editor

    Migrate custom Property Editors to Umbraco version 14 and later

    This article helps you migrate custom Property Editors to Umbraco 14 and later

    This article applies only to implementers of custom Property Editors, that is:

    • Maintainers of Property Editor packages.

    • Site implementers who have built their own Property Editors.

    Umbraco 14 introduces a split between server-side and client-side Property Editor aliases. The reasoning behind this change is two-fold:

    1. It allows server-side implementations to be reused for multiple client-side Property Editor UIs.

    2. It helps to ensure a better division between client-side and server-side responsibility.

    Migration impact for Property Editors

    In the Umbraco source code, the change manifests as the EditorUiAlias property on IDataType.

    When upgrading from Umbraco 13 to Umbraco 14 and later, Umbraco automatically migrates all Data Types to include an EditorUiAlias value. For custom Property Editors, this migration is based on certain assumptions.

    Manifest based Property Editors

    If the Property Editor is built with a :

    1. Assign the package manifest alias to the Data Type EditorUiAlias, and

    2. Convert the Data Type EditorAlias to the alias of a core Data Editor, based on the valueType specified in the package manifest.

    The following table contains the applied conversion from valueType to EditorAlias:

    This might also impact Property Value Converters

    Property Value Converters for package manifest based Property Editors might be impacted by this migration.

    It is common practice to pair a Property Editor to a Property Value Converter using the package manifest alias:

    Since the migration moves the alias

    Code based editors

    If the Property Editor is built with a , we:

    1. Assign the Data Editor Alias to the Data Type EditorUiAlias, and

    2. Retain the Data Type EditorAlias as-is (which is the Data Editor Alias).

    The Data Editor Alias is found in the DataEditor attribute:

    Migration impact for porting Property Editor UIs

    The file is a central component for extensions in Umbraco 14+, including Property Editor UIs.

    To keep the Property Editor working with migrated properties, ensure that the propertyEditorUi extension is declared with:

    1. The migrated value of EditorUiAlias as its alias, and

    2. The migrated value of EditorAlias as its propertyEditorSchemaAlias (found in the extension meta collection).

    For example:

    See the article for guidance on building a Property Editor UI for Umbraco 14 and later.

    Alternatives

    If the Data Type migration yields an undesirable result, you have two options:

    1. Manually change the EditorAlias and/or EditorUiAlias directly in the umbracoDataType table, or

    2. Create a custom migration to update the properties. See the article for inspiration.

    Unattended Installs

    In some cases, you might need to install Umbraco instances automatically without having to run through the installation wizard to configure the instance.

    You can use the Unattended installs feature to allow for quick installation and set up of Umbraco instances on something like Azure Web Apps.

    This article will give you the details you need to install Umbraco unattended.

    Get clean install of Umbraco

    In order to get a clean instance of Umbraco, follow our installation guide for how to Install an Umbraco project template.

    Configure your database

    As you will not be running through the installation wizard when using this feature, you need to manually tell Umbraco which database to use.

    • Set up and configure a new database - see for details.

    • Add the connection string using configuration.

    Umbraco can create an SQL Server database for you during the unattended install process. The user specified by the credentials in your connection string needs to have the CREATE DATABASE permission granted and the global setting is set to true.

    If your connection string is for SQLite or SQL Server Express LocalDB it is assumed that a database should be created when missing. This is regardless of the value of the InstallMissingDatabase setting.

    SQL Server Example in appsettings.json

    The 'umbracoDbDSN_ProviderName' attribute sets the .NET Framework data provider name for the DataSource control's connection. For more information on the data providers included in the .Net Framework, see the .

    SQLite Example in appsettings.json

    A value is configured for the keyumbracoDbDSN_ProviderName to ensure usage of the Microsoft.Data.SQLite ADO.NET provider.

    It is recommended that you make use of the values shown below for the Cache, Foreign Keys and Pooling keywords on your connection string.

    Enable the unattended installs feature

    The unattended installs feature is disabled by default. In order to enable it, you need to add the following JSON object to a JSON configuration source.

    Remember to set the value of InstallUnattended to true.

    The UnattendedTelemetryLevel can be set to Minimal, Basic, or Detailed. If omitted, Detailed is the default.

    Alternatively you may set your configuration with Environment Variables or other means. Learn more about this in the .

    The keys for this would then be as follows:

    Initialize the unattended install

    After completing the steps above you can now initialize the installation by booting up the Umbraco instance.

    Once it has completed, you should see the following when visiting the frontend of the site.

    Configuration options

    Depending on your preferences, you can use any type of configuration to specify the connection string and login information, as well as enable unattended install. With the extending configuration functionality, it is possible to read from all kinds of sources. One example can be using a JSON file or environment variables.

    Program.cs has a condition, which if met, an appsettings.Local.json file will be added and configured as a configuration source.

    Having intellisense will help you to add your connection string and information needed for the unattended install.

    More support

    We have added support for unattended installs with Name, Email and Password, and Connection String as CLI params, which are also available in Visual Studio. There you can fill in your information as follows:

    CLI

    Visual Studio

    Running Umbraco in Docker

    Exactly how you choose to compose your Dockerfile will depend on your project specific needs. This section is not intended as a comprehensive guide, rather as an overview of topics to be aware of when hosting in Docker.

    What is Docker

    Docker is a platform for developing, shipping, and running applications in containers. Multiple services exist for hosting these containers. For more information, refer to the official Docker Documentation

    The Docker file system

    By default, files created inside a container are written to an ephemeral, writable container layer. This means that the files don't persist when the container is removed, and it's challenging to get files out of the container. Additionally, this writable layer is not suitable for performance-critical data processing.

    This has implications when running Umbraco in Docker.

    For more information, refer to the .

    General file system consideration

    In general, when working with files and Docker you work in a "push" fashion with read-only layers. When you build, you take all your files and "push" them into this read-only layer.

    This means that you should avoid making files on the fly, and instead rely on building your image.

    In an Umbraco context, this means you should not create or edit template, script or stylesheet files via the backoffice. These should be deployed as part of your web application and not managed via Umbraco.

    Similarly, you shouldn't use InMemory modelsbuilder, since that also relies on creating files on the disk. While this is not a hard requirement, it doesn't provide any value unless you are live editing your site.

    Instead, configure models builder to use "source code" mode in development, and "none" in production, as .

    Logs

    Umbraco writes logs to the /umbraco/Logs/ directory. Due to the performance implications of writing to a writable layer, and the limited size, it is recommended to mount a volume to this directory.

    You may prefer to avoid writing to disk for logs when hosting in containers. If so, you can disable this default behavior and register a custom Serilog sink to alternative storage, such as Azure Table storage.

    You can also provide an alternative implementation of a common abstraction for the log viewer. In this way you can read logs from the location where you have configured them to be written.

    For more details, read the article on Umbraco's .

    Data

    The /umbraco/Data/ directory is used to store temporary files, such as file uploads. Considering the limitations of the writable layer, you should also mount a volume to this directory.

    Media

    It's recommended to not store media in the writable layer. This is for similar performance reasons as logs, but also for practical hosting reasons. You likely want to persist media files between containers.

    One solution is to use bind mounts. The ideal setup, though, is to store the media and ImageSharp cache externally. For more information, refer to the .

    Required files

    Your solution may require some specific files to run, such as license files. You will need to pass these files into the container at build time, or mount them externally.

    HTTPS

    When running websites in Docker, it's common to do so behind a reverse proxy or load balancer. In these scenarios you will likely handle SSL termination at the reverse proxy. This means that Umbraco will not be aware of the SSL termination, and will complain about not using HTTPS.

    Umbraco checks for HTTPS in two locations:

    1. The HstsCheck health check - This will result in a failed healthcheck.

    2. The UseHttpsValidator - This will result in a build error, if Production runtime mode is used.

    To avoid these checks failing, you can remove them in your project.

    Health Check

    The health check must be removed via configuration, through the appsettings.json file, environment variables, or similar. For more information see the .

    The HstsCheck key is E2048C48-21C5-4BE1-A80B-8062162DF124 so the appsettings will look something like:

    Runtime mode validator

    The UseHttpsValidator must be removed through code For more information see the .

    The code to remove the validator can look something like:

    Standalone File System

    No file replication is configured, deployment handles updating files on the different servers.

    If the file system on your servers isn't performing any file replication then no Umbraco configuration file changes are necessary. However Media will need to be configured to use a shared location such as Blob storage or S3.

    Depending on the configuration and performance of the environment's local storage you might need to consider Examine Directory Factory Options and the Umbraco temporary storage location.

    Synchronised File System

    The servers are performing file replication, updates to a file on one server, updates the corresponding file on any other servers.

    If the file system on your servers is performing file replication then the Umbraco temporary folder (~/umbraco/Data/TEMP) must be excluded from replication.

    If the file system on your servers is located on shared storage you will need to configure Umbraco to locate the Umbraco temporary folder outside of the shared storage.

    Replication techniques

    A common way to replicate files on Windows Server is to use [DFS](https://msdn.microsoft.com/en-us/library/windows/desktop/bb540031(v=vs.85), which is included with Windows Server.

    Additional DFS resources:

    There are other alternatives for file replication out there, some free and some licensed. You'll need to decide which solution is best for your environment.

    Non-replicated files

    When deploying Umbraco in a load balanced scenario using file replication, it is important to ensure that not all files are replicated - otherwise you will experience file locking issues. Here are the folders and files that should not be replicated:

    • ~/umbraco/Data/TEMP/*

    Alternatively store the Umbraco temporary files in the local server's 'temp' folder and set Examine to use a .

    Achieve this by changing the value of the LuceneDirectoryFactory setting to 'TempFileSystemDirectoryFactory' in the appsettings.json. The downside is that if you need to view temporary files you'll have to find it in the temp files. Locating the file this way isn't always clear.

    Below is shown how to do this in a Json configuration source.

    • ~/umbraco/Logs/*

      • This is optional and depends on how you want your logs configured (see below)

    If for some reason your file replication solution doesn't allow you to not replicate specific files folders (which it should!!) then you can use an alternative approach by using virtual directories.

    The following is not the recommended setup but it is a viable alternative:

    • Copy the ~/umbraco/Data/TEMP directory to each server, outside of any replication areas or to a unique folder for each server.

    • Create a virtual directory (not a virtual application) in the ~/umbraco/Data/ folder, and name it TEMP. Point the virtual directory to the folder you created in step 2.

    • You may delete the ~/umbraco/Data/TEMP folder from the file system - not IIS as this may delete the virtual directory - if you wish.

    IIS Setup

    IIS configuration is pretty straightforward with file replication. IIS is only reading files from its own file system like a normal IIS website.

    Mixture of standalone & synchronised

    In some scenarios you have a mixture of standalone and synchronised file systems. An example of this is Azure Web Apps where the file system isn't replicated between backoffice and front end servers but is replicated between all front end servers, in this configuration you should follow the steps for synchronised file systems.

    There is a specific documentation for load balancing with

    Examine Directory Factory Options

    • The TempFileSystemDirectoryFactory allows Examine to store indexes directly in the environment temporary storage directory, and should be used instead of SyncTempEnvDirectoryFactory mentioned above.

    • The SyncedTempFileSystemDirectoryFactory enables Examine to sync indexes between the remote file system and the local environment temporary storage directory, the indexes will be accessed from the temporary storage directory. This setting is needed because Lucene has issues when working from a remote file share so the files need to be read/accessed locally. Any time the index is updated, this setting will ensure that both the locally created indexes and the normal indexes are written to. This will ensure that when the app is restarted or the local environment temp files are cleared out that the index files can be restored from the centrally stored index files.

    If you are load balancing with make sure to check out the article we have for that specific set-up.

    Advanced techniques

    Once you are familiar with how flexible load balancing works, you might be interested in some .

    Upgrade from Umbraco 8 to the latest version

    Learn how to upgrade your Umbraco 8 project to Umbraco 10.

    It is currently not possible to upgrade directly from Umbraco 8 to the latest version.

    The recommended approach for upgrading from version 8 to the latest version is to use this guide to upgrade from Umbraco 8 to Umbraco 10. Umbraco 10 contains the database migrations that must be upgraded from Umbraco 8. You can then use the Upgrading to Major steps to upgrade from Umbraco 10 to the latest version.

    Since the underlying framework going from Umbraco 8 to the latest version has changed, there is no direct upgrade path. That said, it is possible to re-use the database from your Umbraco 8 project on your new project in order to maintain the content.

    It is not possible to migrate the custom code as the underlying web framework has been updated from ASP.NET to ASP.NET Core. All templates and custom code will need to be reimplemented.

    You also need to make sure that the packages you are using are available on the latest version.

    Prerequisites

    • A Umbraco 8 project running the latest version of Umbraco 8.

    • A backup of your Umbraco 8 project database.

    • A clean installation of the latest version of Umbraco.

    If you use Umbraco Forms, then on the clean installation of Umbraco, you will need to install Umbraco.Forms package as well.

    Video Tutorial

    The video below shows how to complete the upgrade on an Umbraco Cloud project. Most of the process is the same, however, the video does contain some Cloud-specific elements.

    Step 1: Content Migration

    If you use Umbraco Forms, make sure to have to True before step 1.

    1. Create a backup of the database from your Umbraco 8 project (after you have upgraded to the latest version of v8). For this, you can use the .

    2. Import the database backup into SQL Server Management Studio.

    3. Update the connection string in the new projects appsettings.json file so that it connects to the Umbraco 8 database:

    You can also add the connection details if you spin up a clean installation.

    1. Run the new project and login to authorize the upgrade.

    2. Select "Upgrade" when the upgrade wizard appears.

    3. Once the upgrade has been completed, it's recommended to login to the backoffice to verify if your project is upgraded to new version.

    This is only content migration and the database will be migrated.

    You need to manually update the view files and custom code implementation. For more information, see Step 3 of this guide.

    Step 2: File Migration

    1. The following files/folders need to be copied from the Umbraco 8 project into the new project:

      • ~/Views - Do not overwrite the default Macro and Partial View Macro files unless changes have been made to these.

      • ~/Media - Media folder from v8 needs to be copied over into the wwwroot - media folder

    Step 3: Custom Code in the latest version

    The latest version of Umbraco is different from Umbraco 8 in many ways. With all the files and data migrated it is now time to rewrite and re-implement all custom code and templates.

    Examples of changes

    One of the changes is how published content is rendered through Template files. Due to this, it will be necessary to update all the Template files (.cshtml) to reflect these changes.

    Read more about these changes in the section of the Umbraco CMS documentation.

    • Template files need to inherit from Umbraco.Cms.Web.Common.Views.UmbracoViewPage<ContentModels.HomePage> instead of Umbraco.Web.Mvc.UmbracoViewPage<ContentModels.HomePage>

    • Template files need to use ContentModels = Umbraco.Cms.Web.Common.PublishedModels instead of ContentModels = Umbraco.Web.PublishedModels

    For more information on the correct namespaces or custom code, you can find the references in the article.

    Depending on the extent of the project and the amount of custom code and implementations, this step is going to require a lot of work.

    Once the new project runs without errors on a local setup it is time to deploy the website to production.

    This concludes this tutorial. Find related information and further reading in the section below.

    Related Information

    Install using Visual Studio Code

    Follow these steps to set up an Umbraco project with VS Code. The benefit of using VS Code is that it is super quick to get up and running.

    Installing and setting up VS Code

    1. Go to https://code.visualstudio.com/ and download VS Code for free.

    2. Once installed, launch VS Code.

    3. Click the extensions menu at the bottom on the left side. Then search for C# and install it.

    Creating your Umbraco project

    Follow the to create your project folder.

    Configure VS Code to run the Umbraco project

    Open your project folder in VS Code, your project will look something like this:

    Now we need to tell VS Code how to run your project.

    Open the command palette, you can use the shortcut Ctrl+Shift+P, and type in Tasks: Configure and select the Tasks: Configure Task option:

    Select "Create task.json from template"

    Now select ".NET Core" as your template.

    After this VS Code will have created a folder called .vscode that contains a file called tasks.json, it's this file that tells VS Code how to build your project.

    Now that we've told VS Code how to build your project, we need to tell it how to launch it. VS Code can do this for you. First, select the little play button in the left side menu, and then select the "create a launch.json file" link.

    This will prompt a menu to appear, select .NET 5+ and .NET Core:

    If .NET 5+ and .NET Core is missing in the drop-down menu:

    1. Press Ctrl + Shift + P (on Windows/Linux) or Cmd + Shift + P (on macOS) to open the Command Palette.

    2. Search for the command .NET: Generate Assets for Build and Debug. This command will generate the necessary assets for building and debugging your .NET application.

    Now you'll see a green play button appear with a dropdown where ".NET Core Launch (web)" is selected.

    If you navigate to the Files section, a new launch.json file is created in the .vscode folder. When you press F5, the launch.json file tells VS Code to build your project, run it, and then open a browser .

    With that, you're ready to run the project! Press F5, or click the little green play button in the Run and Debug section to run your brand new Umbraco site locally.

    Umbraco Web Installer

    This section continues from where we left off but covers the installation and configuration of Umbraco inside your web browser when you run Umbraco for the first time.

    You will see the install screen where you will need to fill in some data before Umbraco can be installed.

    When the installer is done, you will be logged into the backoffice.

    Congratulations, you have installed an Umbraco site!

    You can log into your Umbraco site by entering the following into your browser: http://yoursite.com/umbraco/.

    Load Balancing Azure Web Apps

    Ensure you read the Load Balancing overview and general Azure Web Apps documentation before you begin - you will need to ensure that your ASP.NET Core & logging configurations are correct.

    Azure Requirements

    • 2 x App service plans with 1 x web app in each:

      • One for the backoffice (Administrative) environment

      • One for your scalable public-facing environment (Public)

    • 1 x SQL server that is shared with these 2 web apps

    The setup above will allow for the proper scaling of the Administrative and Public web apps.

    The App Service plan with the Administrative web app should only be scaled up. The reason for this is that the web app needs to stay as a single instance.

    The App Service plan with the Public web app can be scaled both out and up.

    Lucene/Examine configuration

    The single instance Backoffice Administrative Web App should be set to use .

    The multi-instance Scalable Public Web App should be set to use .

    Umbraco TEMP files

    When an instance of Umbraco starts up it generates some 'temporary' files on disk. In a normal IIS environment, these would be created within the folders of the Web Application. In an Azure Web App, we want these to be created in the local storage of the actual server that Azure happens to be used for the Web App. So we set this configuration setting to 'true' and the temporary files will be located in the environment temporary folder. This is required for both the performance of the website as well as to prevent file locks from occurring due to the nature of Azure Web Apps shared files system.

    Host synchronization

    Umbraco runs within a .

    When a host restarts, the current host 'winds down' while another host is started. This means there can be more than one live host during a restart. Restarts can occur in many scenarios including when an Azure Web App auto-transitions between hosts, you scale the instances or you utilize slot swapping.

    Some file system based services in Umbraco such as the Published Cache and Lucene files can only be accessed by a single host at once. Umbraco manages this synchronization by an object called IMainDom.

    By default Umbraco v9.4 & 9.5 uses a system-wide semaphore locking mechanism. This mechanism only works on Windows systems and doesn't work with multi-instance Azure Web Apps. We need to swap it out for an alternative file system based locking mechanism by using the following appSetting. With Umbraco v10+ FileSystemMainDomLock is the default setting.

    Apply this setting to both the SCHEDULINGPUBLISHER Administrative server and the SUBSCRIBER scalable public-facing servers.

    You can also copy the following JSON directly into your Azure Web App configuration via the Advanced Edit feature.

    Steps to set up an environment

    1. Create an Azure SQL database

    2. Install Umbraco on your backoffice administrative environment and ensure to use your Azure SQL Database

    3. Install Umbraco on your scalable public-facing environment and ensure to use your Azure SQL Database

    4. Test: Perform some content updates on the administrative environment, ensure they work successfully in that environment, then verify that those changes appear on the scalable public-facing environment

    Ensure all Azure resources are in the same region to avoid connection lag.

    Scaling

    Do not scale your backoffice administrative environment this is not supported and can cause issues.

    The public-facing subscriber Azure Web Apps can be manually or automatically scaled up or down and is supported by Umbraco's load balancing.

    Deployment considerations

    Since you have 2 x web apps, when you deploy you will need to deploy to both places - There are various automation techniques you can use to simplify the process. That is outside the scope of this article.

    This also means that you should not be editing templates or views on a live server as SchedulingPublisher and Subscriber environments do not share the same file system. Changes should be made in a development environment and then pushed to each live environment.

    Date Time (with Time Zone)

    Schema Alias: Umbraco.DateTimeWithTimeZone

    UI Alias: Umb.PropertyEditorUi.DateTimeWithTimeZonePicker

    Returns: DateTimeOffset?

    The Date Time with Time Zone property editor provides a comprehensive interface for selecting dates, times, and time zones. It stores values as ISO 8601 date/time strings with time zone information. This makes it ideal for applications that need accurate date handling across different time zones.

    Configuration

    You can configure this property editor in the same way as any standard property editor, using the Data Types admin interface.

    To set up a property using this editor, create a new Data Type. Select Date Time (with time zone) from the list of available property editors.

    You will see the configuration options as shown below.

    • Time format - Specifies the level of precision for time values shown and stored by the editor.

    • Time zones - Controls how time zones are available in the property editor.

    Time format

    • HH:mm - Displays hours and minutes (e.g., 14:30). Suitable for most general use cases.

    • HH:mm:ss - Displays hours, minutes, and seconds (e.g., 14:30:45). Use this when you need more precise timing.

    Time zones

    • All - Displays the full list of time zones (for example, America/New_York, Europe/Stockholm).

    • Local - Displays only the local time zone of the user's browser/computer. Useful for simplifying the UI when time entries should always be based on the user’s local context.

    • Custom - Allows you to define a list of time zones. When you select this option, a dropdown appears. You can search and select from the full IANA time zone list. Add multiple zones to restrict user selection to only the zones you specify.

    The selected time zone affects how the date/time is displayed and stored. When you select a time zone, the value will be saved with the corresponding offset (e.g., 2025-01-01T14:30:00+01:00). Daylight saving time is also taken into account.

    Editing experience

    Adding or editing a value

    You will be presented with date, time, and time zone inputs. The time zone input allows typing, which filters the list of presented time zones.

    If your browser time zone appears in the list and no date is stored yet, it will be pre-selected by default.

    When you select a time zone different from your browser's local time zone, the editor displays a helpful conversion message. This shows what the selected date and time would be equivalent to in your local time zone, making it easier to understand the time difference.

    If only one time zone is available, you will see a label with the time zone name instead.

    Rendering

    The value returned will have the type DateTimeOffset?. This allows you to work with the date/time value while preserving time zone information.

    Display the value

    With Models Builder:

    Without Models Builder:

    Value conversions

    Convert to local time:

    Convert to UTC time:

    Convert to DateTime:

    Add values programmatically

    This property editor stores values as a JSON object. The object contains both the date (as an ISO 8601 string) and the selected time zone identifier.

    Storage format

    The property editor stores values in this JSON format:

    1. Create a C# model that matches the JSON schema.

    2. Create an instance of the created class with the desired values.

    3. Inject the IJsonSerializer and use it to serialize the object.

    4. Inject the IContentService

    Sections

    In this article you can learn more about the various sections you can find within the Umbraco Backoffice.

    A section in Umbraco is where you perform specific tasks related to a particular area of Umbraco. For example, Content, Settings, and Users are all sections. You can navigate between the different sections by clicking the corresponding icon in the section menu positioned at the top of the Backoffice.

    The Section menu is the horizontal menu located at the top of the Umbraco Backoffice.

    Below is a short overview of the default sections in Umbraco CMS:

    Content

    The Content section contains the content nodes that make up the website. Content is displayed as nodes in the Content tree.

    Nodes in Umbraco can display the following content states:

    • Grayed-out nodes are not published yet.

    • Nodes that are currently locked using the Public Access feature.

    • Content nodes that contain a collection of nodes.

    To create content, you must define it using Document Types.

    For more information, see the article.

    Media

    The Media section contains the media for the website. You can create folders and upload media files, such as images and PDFs. Additionally, you can customize the existing Media Types or define your own from the Settings section.

    For more information, see the article.

    Settings

    The Settings section allows you to manage website layout files, languages, media, and content types. It also gives you access to more advanced features such as the Log Viewer and extension insights.

    The Settings section consists of:

    Structure

    • Document Types

    • Media Types

    • Member Types

    • Data Types

    Templating

    • Templates (.cshtml files)

    • Partial views (.cshtml files)

    • Stylesheets (.css files)

    Advanced

    • Relations

    • Log Viewer

    • Extension Insights

    • Webhooks

    The Settings section in the Umbraco backoffice has its own set of default dashboards.

    For more information, see the article.

    Packages

    In this section, you can browse the different packages available for your Umbraco solution. You can also get an overview of all the packages you have installed or created.

    For more information, see the article.

    Users

    The Users section allows administrators to manage user accounts, assign permissions, set user roles, and monitor user activity within the backoffice. It provides control over who can access and modify content, media, and settings in the CMS.

    For more information, see the article.

    Members

    The Members section allows to create and manage member profiles, set up member groups, and control Member's access to restricted content on the website.

    For more information, see the article.

    Dictionary

    The Dictionary section is where you create and manage Dictionary Items. By managing these dictionary items, you can ensure consistent and efficient content translation and maintenance across different languages.

    For more information, see the article.

    Add-Ons

    To enhance Umbraco's functionality, you can integrate plugins and extensions tailored to specific needs. These add-ons expand Umbraco's capabilities, allowing for a more customized and powerful content management experience.

    For example, you can start with core Umbraco features and later decide to integrate additional products. Currently, Umbraco supports add-on products like:

    • Forms: Simplifies the creation and management of Forms.

    • Deploy: Facilitates smooth deployment processes.

    • Workflow: Enhances content workflows and approval processes.

    • Commerce: Adds e-commerce capabilities to your site.

    When you add an add-on product to Umbraco, it appears in the Backoffice as a new section, seamlessly extending your content management capabilities.

    If you wish to explore the unique features and use cases of Umbraco products, see the article.

    For more information about extending the Umbraco platform through packages and integrations, see the documentation.

    Help Section

    The Help section in Umbraco provides documentation and resources to assist in understanding and effectively using the Umbraco CMS. It typically includes the following in the Getting Started Dashboard:

    • Documentation: Comprehensive guides, tutorials, and references covering different aspects of Umbraco.

    • Community Forums: Access to forums where you can ask questions, share knowledge, and seek assistance from other Umbraco community members.

    • Resources: Stay updated with the latest news, access documentation, watch free video tutorials, and register for live demos.

    • Training

    The Help section serves as a valuable resource hub in navigating and leveraging the capabilities of the Umbraco CMS effectively.

    Custom Sections

    Along with the default sections that come with Umbraco, you can create your own .

    Access based on User Group

    A User can access a particular section based on the User Group permissions.

    Learn more about how to configure the permissions in the article about .

    Multi Url Picker

    Schema Alias: Umbraco.MultiUrlPicker

    UI Alias: Umb.PropertyEditorUi.MultiUrlPicker

    Returns: IEnumerable<Link> or Link

    Multi Url Picker allows an editor to pick and sort multiple URLs. It returns either a single item or a collection. This depends on the "Maximum number of items" Data Type setting. When that is set to 1, it returns a single item, otherwise a collection. Multi URL Picker allows editors to select and sort multiple URLs. The property returns either a single item or a collection, depending on the Maximum number of items setting in the Data Type configuration.

    • When the maximum is set to 1, it returns a single item.

    • When the maximum is greater than 1, it returns a collection.

    The URLs can point to internal, external, or media items.

    Data Type Definition Example

    Content Example

    MVC View Example

    Without Models Builder

    This example handles the case of Maximum number of items set to 1:

    With Models Builder

    And here is the case of Maximum number of items set to 1:

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Markdown Editor

    Schema Alias: Umbraco.MarkdownEditor

    UI Alias: Umb.PropertyEditorUi.MarkdownEditor

    Returns: System.Web.HtmlString

    This built-in editor allow the user to use the markdown formatting options, from within a rich text editor-like interface.

    Data Type Definition Example

    There are three settings available for manipulating the Markdown editor property.

    • Preview toggles if a preview of the markdown should be displayed beneath the editor in the content view.

    • Default value is inserted if no content has been saved to the Document Type using this property editor.

    • Overlay Size is used to select the width of the link picker overlay in the content view.

    Content Example

    Explanation of buttons from left to right

    Function
    Shortcut
    Further explanation

    Other functionality

    Function
    Shortcut

    MVC View Example

    With Models Builder

    Without Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    File Upload

    Schema Alias: Umbraco.UploadField

    UI Alias: Umb.PropertyEditorUi.UploadField

    Returns: string

    Adds an upload field, which allows documents or images to be uploaded to Umbraco.

    You can define which file types should be accepted through the upload field.

    For uploading and adding files and images to your Umbraco project, we recommend using the Media Picker.

    Find the full documentation for the property in the article.

    Data Type Definition Example

    Content Example

    In code, the property is a string, which references the location of the file.

    Example: "/media/o01axaqu/guidelines-on-remote-working.pdf"

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of this property editor you need the and the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Slider

    Schema Alias: Umbraco.Slider

    UI Alias: Umb.PropertyEditorUi.Slider

    Returns: decimal or Umbraco.Core.Models.Range<decimal>

    Pretty much like the name indicates this Data type enables editors to choose a value with a range using a slider.

    There are two flavors of the slider. One with a single value picker. One with a minimum and maximum value.

    Data Type Definition Example

    Content Example

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    With a range off

    With a range on

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Tags

    Schema Alias: Umbraco.Tags

    UI Alias: Umb.PropertyEditorUi.Tags

    Returns: IEnumerable<string>

    The Tags property editor allows you to add multiple tags to a node.

    Data Type Definition Example

    Tag group

    The Tag group setting provides a way to categorize your tags in groups. So for each category you will create a new instance of the Tags property editor and setup the unique category name for each instance. Whenever a tag is added to an instance of the tags property editor it's added to the tag group, which means it will appear in the Typeahead list when you start to add another tag. Only tags that belong to the specified group will be listed. If you have a "Frontend" group and a "Backend" group the tags from the "Frontend" group will only be listed if you're adding a tag to the Tags property editor configured with the "Frontend" group name and vice versa.

    Storage type

    Data can be saved in either Comma-Separated Values (CSV) format or in JSON format. By default data is saved in JSON format. The difference between using CSV and JSON is that with JSON you can save a tag, which includes comma separated values.

    There are built-in property value converters, which means you don't need to worry about writing them yourself or parse the JSON output when choosing "JSON" in the storage type field. Therefore on this page will work out of the box without further ado.

    Content Examples

    CSV tags

    JSON tags

    Tags typeahead

    Whenever a tag has been added it will be visible in the typeahead when you start typing on other pages.

    MVC View Example - displays a list of tags

    Multiple items - with Models Builder

    Multiple items - without Models Builder

    Setting Tags Programmatically

    You can use the ContentService to create and update Umbraco content from c# code, when setting tags there is an extension method (SetTagsValue) on IContentBase that helps you set the value for a Tags property. Remember to add the using statement for Umbraco.Core.Models to take advantage of it.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled, you can get the alias of the desired property without using a magic string:

    More on working with Tags

    More on working with Tags (query all of them) can be found at the

    Date Time (Unspecified)

    Schema Alias: Umbraco.DateTimeUnspecified

    UI Alias: Umb.PropertyEditorUi.DateTimePicker

    Returns: DateTime?

    The Date Time (Unspecified) property editor provides an interface for selecting dates and times without including time zone information.

    Configuration

    You can configure this property editor in the same way as any standard property editor, using the Data Types admin interface.

    To set up a property using this editor, create a new Data Type and select Date Time (Unspecified) from the list of available property editors.

    You will see the configuration options as shown below.

    • Time format - Specifies the level of precision for time values shown and stored by the editor.

    Time format

    • HH:mm - Displays hours and minutes (e.g., 14:30). Suitable for most general use cases.

    • HH:mm:ss - Displays hours, minutes, and seconds (e.g., 14:30:45). Use this when you need more precise timing.

    Editing experience

    Adding or editing a value

    You will be presented with a date and time input. This editor focuses only on the date and time components, unlike the time zone version.

    Rendering

    The value returned will have the type DateTime?.

    Display the value

    With Models Builder:

    Without Models Builder:

    Add values programmatically

    This property editor stores values as a JSON object. The object contains the date as an ISO 8601 string.

    Storage format

    The property editor stores values in this JSON format:

    The property editor handles unspecified date and time values without time zone information. The value is stored with offset +00:00 for consistency. The offset is ignored unless you replace this editor with the Date Time (with time zone) version.

    1. Create a C# model that matches the JSON schema.

    2. Convert your existing DateTime value to DateTimeOffset for storage.

    3. Create an instance of the class with the DateTimeOffset value.

    4. Inject the

    Settings Dashboards

    A guide displaying the options available in the Settings section in Umbraco CMS backoffice.

    The Settings section of the Umbraco backoffice has its own set of default dashboards. In this article, you can get an overview of each dashboard available in the Settings section:

    Welcome

    The Welcome dashboard is the first dashboard in the Settings section. Like all dashboards, it has a customizable view and links to different resources for developing your Umbraco website.

    For more information about creating custom dashboards, see the Dashboards article.

    Examine Management

    The Examine Management dashboard provides an overview of the Examine functionality available directly within the Umbraco backoffice. The Umbraco backoffice allows you to view details about your Examine indexes and searchers - all in one place. You can see which fields are being indexed and rebuild the indexes if there's a problem. You can also test keywords to see what results will be returned.

    For more information about Examine Management, see the article.

    Published Status

    The Published Status dashboard displays the status of your site in the Published Cache Status section alongside the Content and Media nodes value. The Caches section provides three options: Memory Cache, Database Cache, and Internals.

    • Memory Cache - Reloads the in-memory cache by entirely reloading it from the database cache. Use it when you think that the memory cache has not been properly refreshed.

    • Database Cache - Rebuilds the database cache that is the content of the cmsContentNu

    Models Builder

    Models builder is a tool that can generate a complete set of strongly-typed published content models for Umbraco. Models are available in both controllers and views. When using the Models Builder, the content cache does not return IPublishedContent objects anymore but returns strongly typed models implementing IPublishedContent.

    The Models Builder dashboard displays the following information:

    • Details on how Models Builder is configured, that is: InMemoryAuto

    Health Check

    Health Checks are used to determine the status of your Umbraco project. It is a handy list of checks to see if your Umbraco installation is configured according to best practices. It's possible to add your custom-built health checks.

    For more information about Health Checks, see the articles.

    Profiling

    You can use the built-in performance profiler to assess the performance when rendering pages. To activate the profiler for a specific page rendering, add umbDebug=true to the querystring when requesting the page.

    The Profiling dashboard provides a toggle option - Activate the profiler by default to keep the profiler active by default for all page renderings. You can use this option without having to set umbDebug=true on each page request. The toggle button sets a cookie named UMB-DEBUG in your browser, which then activates the profiler automatically.

    For more information about MiniProfiler, see the section in the article.

    Telemetry Data

    The Telemetry Data dashboard is a consent screen that is used for collecting system and usage information from your installation. Here, you can see what type of data is being collected and even adjust the level of reporting. Currently, there are three levels available: Minimal, Basic, and Detailed.

    Detailed is the default option where the data sent contains:

    • Anonymized site ID, Umbraco version, and packages installed.

    Language Variants

    Learn how to use language variants to output your content in multiple languages.

    Language Variants allows you to vary content by culture, so you can allow a content node to exist in multiple languages.

    This article will cover the different aspects of enabling and working with language variants on your Umbraco website.

    Contents

    • Video tutorial

    Video tutorial

    How to enable Language Variants

    To work with Language Variants you need to have more than one language enabled. This can be done from the Settings section:

    You will always have one default language but each language can be set to mandatory.

    Enabling Language Variants on Document Types

    Now that there are two languages to vary the content with, it needs to be enabled on the Document Types. To do so:

    1. Go to the Document Type in the structure section.

    2. Open the settings page.

    3. Toggle Allow vary by culture.

    To allow a property on the Document Type to be varied it will have to be enabled for the property:

    Working with Language Variants on content

    When you return to your content node you will notice two things:

    1. At the top of the Content tree there will now be a dropdown so you can show the Content tree in the language of your choice.

    2. To the right of the content name there is now a dropdown where you can select a language. You can also open a split view so you can see two languages at once.

    To read about how you render variant content in Templates, check out the .

    Test your language variants

    Culture and hostnames must be added to your language sites before the content can be tested for variants:

    1. Click ... next to the Home node and select Culture and Hostnames.

    2. Add a specific URL per language and save. For eg: An English language variant with English (United States) as the language can be given a specific URL https://yourwebsite.com/en-us and a Danish language variant can be given a specific URL https://yourwebsite.com/dk.

    The Info content app should now show specific URLs for your language variants.

    Control User Group permissions on language variants

    This feature is available from Umbraco version 10.2.

    When you are working with a multilingual site you might want to control who can edit the different variations of the content on the website.

    This can be controlled on a User Group level. All default User Groups, except the Sensitive data group, have access to all languages out of the box.

    When "Allow access to all languages" is not checked, languages can be added and/or removed. This is to determine which variants the users in the user group have access to.

    Even though the language permissions have been set, a user will still be able to view and browse all the language variations. The permission setting will ensure that only the added languages are editable by users of the User Group.

    Related Links

    Default Data/Media Types

    On this page you will find the media types and Data Types in Umbraco. These types are not created automatically after an upgrade. If you want to use the new types, you can create them yourself.

    After upgrading, the default media types are not created automatically. If you create them manually, make sure to:

    • Set the permission for each of the media types to Allow at root.

    • Ensure that the Folder media type allows the new media types as children.

    Data Types

    UploadArticle

    The UploadArticle Data Type has the following configuration:

    • Property editor: FileUpload

    • Accepted file extensions: pdf, docx, doc

    UploadAudio

    The UploadAudio Data Type has the following configuration:

    • Property editor: FileUpload

    • Accepted file extensions: mp3, weba, oga, opus

    UploadVectorGraphics

    The UploadVectorGraphics Data Type has the following configuration:

    • Property editor: FileUpload

    • Accepted file extensions: svg

    UploadVideo

    The UploadVideo Data Type has the following configuration:

    • Property editor: FileUpload

    • Accepted file extensions: mp4, webm, ogv

    Media Types

    UmbracoMediaArticle

    The UmbracoMediaArticle media type has the following properties:

    • umbracoFile - Upload File

    • umbracoExtension - Label (string)

    • umbracoBytes - Label (bigint)

    UmbracoMediaAudio

    The UmbracoMediaAudio media type has the following properties:

    • umbracoFile Upload Audio

    • umbracoExtension Label (string)

    • umbracoBytes Label (bigint)

    UmbracoMediaVectorGraphics

    The UmbracoMediaVectorGraphics media type has the following properties:

    • umbracoFile - Upload Vector Graphics

    • umbracoExtension Label (string)

    • umbracoBytes Label (bigint)

    UmbracoMediaVideo

    The UmbracoMediaVideo media type has the following properties:

    • umbracoFile - Upload Video

    • umbracoExtension - Label (string)

    • umbracoBytes - Label (bigint)

    You can also create localization files for Media Types. You can read more about this in the article.

    Minor upgrades for Umbraco 7

    This article provides details on how to upgrade to the next minor version when using Umbraco 7.

    Sometimes there are exceptions to these guidelines, which are listed in the .

    Note

    It is necessary to run the upgrade installer on each environment of your Umbraco site. If you want to update your staging and live site then you need to repeat the steps below and make sure that you click through the install screens to complete the upgrade.

    Installing Nightly Builds

    Instructions on installing nightly builds of Umbraco.

    In this article, we'll explain how you can get the latest builds of Umbraco. You can do this in three steps:

    Dropdown

    Schema Alias: Umbraco.DropDown.Flexible

    UI Alias: Umb.PropertyEditorUi.Dropdown

    Returns: String or IEnumerable<string>

    Displays a list of preset values. Either a single value or multiple values (formatted as a collection of strings) can be returned.

    Extensions

    Information on how to work with Tiptap extensions in the rich text editor.

    The Rich Text Editor (RTE) in Umbraco is based on the open-source editor .

    Out of the box, Tiptap has limited capabilities and everything is an extension by design. Basic text formatting features such as bold, italic, and underline are their own extensions. This offers great flexibility, making the rich text editor highly configurable. The implementation in Umbraco offers a wide range of built-in extensions to enhance the Tiptap editor capabilities.

    Using the same extension points, this article will show you how to add a custom extension to the rich text editor.

    Native Tiptap extensions

    Tiptap has a library of supported native extensions. You can find a list of these extensions on the . While many of these are open source, there are also

    Document Type Localization

    Setup localization for Document Types in the Umbraco backoffice.

    The Umbraco backoffice is localized to match the .

    When defining a Document Type, you can apply localization to:

    • Document Type names and descriptions.

    • Property names and descriptions.

    • Custom property validation messages.

    {
      "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iisExpress": {
          "applicationUrl": "http://localhost:40264",
          "sslPort": 44360
        }
      },
      "profiles": {
        "IIS Express": {
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "Umbraco.Web.UI.NetCore": {
          "commandName": "Project",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          },
          "applicationUrl": "https://localhost:44360;http://localhost:40264"
        }
      }
    }
    {
      "iisSettings": {
        "windowsAuthentication": false,
        "anonymousAuthentication": true,
        "iis": {
          "applicationUrl": "https://testsite.local",
          "sslPort": 0
        },
        "iisExpress": {
          "applicationUrl": "http://localhost:40264",
          "sslPort": 44360
        }
      },
      "profiles": {
        "IIS Express": {
          "commandName": "IISExpress",
          "launchBrowser": true,
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "IIS": {
          "commandName": "IIS",
          "launchBrowser": true,
          "launchUrl": "https://testsite.local",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          }
        },
        "Umbraco.Web.UI.NetCore": {
          "commandName": "Project",
          "environmentVariables": {
            "ASPNETCORE_ENVIRONMENT": "Development"
          },
          "applicationUrl": "https://localhost:44360;http://localhost:40264"
        }
      }
    }
    {
        "Umbraco": {
            "CMS": {
                "Global": {
                    "MainDomLock" : "FileSystemMainDomLock"
                },
                "Hosting": {
                    "LocalTempStorageLocation": "EnvironmentTemp"
                },
                "Examine": {
                    "LuceneDirectoryFactory": "SyncedTempFileSystemDirectoryFactory"
                }
            }
        }
    }
    {
      "name": "UMBRACO__CMS__Global__MainDomLock",
      "value": "FileSystemMainDomLock",
      "slotSetting": false
    },
    {
      "name": "UMBRACO__CMS__Hosting__LocalTempStorageLocation",
      "value": "EnvironmentTemp",
      "slotSetting": false
    },
    {
      "name": "UMBRACO__CMS__Examine__LuceneDirectoryFactory",
      "value": "SyncedTempFileSystemDirectoryFactory",
      "slotSetting": false
    }
    using System.Text.Json.Serialization;
    
    namespace UmbracoProject;
    
    public class TimeOnlyValue
    {
        /// <summary>
        /// The time value, represented as a <see cref="DateTimeOffset"/> for storage compatibility.
        /// </summary>
        [JsonPropertyName("date")]
        public DateTimeOffset Date { get; init; }
    }
    TimeOnly timeOnly = TimeOnly.FromDateTime(DateTime.Now); // Your existing TimeOnly value
    DateTimeOffset dateTimeOffset = new DateTimeOffset(DateOnly.MinValue, timeOnly, TimeSpan.Zero);
    DateTime dateTime = DateTime.Now; // Your existing DateTime value
    TimeOnly timeOnly = TimeOnly.FromDateTime(dateTime);
    DateTimeOffset dateTimeOffset = new DateTimeOffset(DateOnly.MinValue, timeOnly, TimeSpan.Zero);
    @Model.StartHours
    @Model.Value<TimeOnly?>("startHours")
    {
        "date": "0001-01-01T14:30:00+00:00"
    }
    @{
        int students = Model.HasValue("students") ? Model.Value<int>("students") : 0;
        int teachers = Model.HasValue("teachers") ? Model.Value<int>("teachers") : 0;
        int totalTravellers = students + teachers;
    
        <p>@totalTravellers</p>
    }
    @{
        if(Model.HasValue("students")){
            <p>@(Model.Value<string>("students"))</p>
        }
    }
    @{
        int students = Model.Students;
        int teachers = Model.Teachers;
        int totalTravellers = students + teachers;
    
        <p>@totalTravellers</p>
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'students'
        content.SetValue("students", 20);
        
        // Save the change
        ContentService.Save(content);
    
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'students'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Students).Alias, 20);
    }
    @{
        if (Model.Value<string[]>("keyFeatureList").Length > 0)
        {
            <ul>
                @foreach (var item in Model.Value<string[]>("keyFeatureList"))
                {
                    <li>@item</li>
                }
            </ul>
        }
    }
    @{
        if (Model.KeyFeatureList.Any())
        {
            <ul>
                @foreach (var item in Model.KeyFeatureList)
                {
                    <li>@item</li>
                }
            </ul>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'keyFeatureList'
        content.SetValue("keyFeatureList", "Awesome" + Environment.NewLine + "Super");
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'keyFeatureList'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.KeyFeatureList).Alias, "Awesome" + Environment.NewLine + "Super");
    }
    @{
        if (Model.HasValue("superHeros"))
        {
            <ul>
                @foreach (var item in Model.Value<IEnumerable<string>>("superHeros"))
                {
                    <li>@item</li>
                }
            </ul>
        }
    }
    @{
        if (Model.SuperHeros.Any())
        {
            <ul>
                @foreach (var item in Model.SuperHeros)
                {
                    <li>@item</li>
                }
            </ul>
        }
    }
    @using Umbraco.Cms.Core.Serialization
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @inject IJsonSerializer Serializer
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'superHeroes'.
        content.SetValue("superHeroes", Serializer.Serialize(new[] { "Umbraco", "CodeGarden"}));
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'superHeroes'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.SuperHeroes).Alias, Serializer.Serialize(new[] { "Umbraco", "CodeGarden"}));
    }
    @{
        IPublishedContent typedContentPicker = Model.Value<IPublishedContent>("featurePicker");
        if (typedContentPicker != null)
        {
            <p>@typedContentPicker.Name</p>
        }
    }
    @{
        IPublishedContent typedContentPicker = Model.FeaturePicker;
        if (typedContentPicker != null)
        {
            <p>@typedContentPicker.Name</p>
        }
    }
    @using Umbraco.Cms.Core
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Get the page you want to assign to the document picker
        var page = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
    
        // Create an Udi of the page
        var udi = Udi.Create(Constants.UdiEntityType.Document, page.Key);
    
        // Set the value of the property with alias 'featurePicker'.
        content.SetValue("featurePicker", udi.ToString());
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'featurePicker'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.FeaturePicker).Alias, udi.ToString());
    }
    @{
        // Perform an null-check on the field with alias 'pageTitle'
        if (Model.HasValue("pageTitle")){
            // Print the value of the field with alias 'pageTitle'
            <p>@(Model.Value("pageTitle"))</p>
        }
    }
    @{
        // Perform an null-check on the field with alias 'pageTitle'
        @if (!Model.HasValue(Model.PageTitle))
        {
            // Print the value of the field with alias 'pageTitle'
            <p>@Model.PageTitle</p>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'pageTitle'
        content.SetValue("pageTitle", "Umbraco Demo");
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'pageTitle'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.PageTitle).Alias, "Umbraco Demo");
    }
    using System.Text.Json.Serialization;
    
    namespace UmbracoProject;
    
    public class DateOnlyValue
    {
        /// <summary>
        /// The date value, represented as a <see cref="DateTimeOffset"/> for storage compatibility.
        /// </summary>
        [JsonPropertyName("date")]
        public DateTimeOffset Date { get; init; }
    }
    DateOnly dateOnly = DateOnly.FromDateTime(DateTime.Today); // Your existing DateOnly value
    DateTimeOffset dateTimeOffset = dateOnly.ToDateTime(TimeOnly.MinValue);
    DateTime dateTime = DateTime.Today; // Your existing DateTime value
    DateOnly dateOnly = DateOnly.FromDateTime(dateTime);
    DateTimeOffset dateTimeOffset = dateOnly.ToDateTime(TimeOnly.MinValue);
    @Model.EventDate
    @Model.Value<DateOnly?>("eventDate")
    {
        "date": "2025-01-01T00:00:00+00:00"
    }
    @{
        if (!string.IsNullOrEmpty(Model.RichText.ToString()))
        {
            <p>@Model.RichText</p>
        }
    }
    @{
        if (Model.HasValue("richText")){
            <p>@(Model.Value("richText"))</p>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Create a variable for the desired value
        var htmlValue = new HtmlString("Add some text <strong>here</strong>");
    
        // Set the value of the property with alias 'richText'.
        content.SetValue("richText", htmlValue);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'richText'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.RichText).Alias, htmlValue);
    }
    @using Umbraco.Cms.Core.Services;
    @inject IUserService UserService;
    @{
        
        if (Model.Value("userPicker") != null)
        {
            var us = UserService;
            var username = us.GetUserById(Model.Value<int>("userPicker")).Name;
    
            <p>This is the chosen person: @username</p>
            <p>This returns the id value of chosen person: @Model.Value("userPicker")</p>
        }
    }
    @using Umbraco.Cms.Core.Services;
    @inject IUserService UserService;
    @{
        if (Model.UserPicker != null)
        {
    
            var us = UserService;
            var user = us.GetUserById((int)Model.UserPicker);
    
            <p>This is the chosen person: @user.Name</p>
            <p>This returns the id value of chosen person: @user.Id)</p>
        }
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = new Guid("796a8d5c-b7bb-46d9-bc57-ab834d0d1248");
        
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'userPicker'. The value is the specific ID of the user
        content.SetValue("userPicker", -1);
                
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'userPicker'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.UserPicker).Alias, -1);
    }
    table. Use it when reloading the Memory Cache is not enough and you think that the database cache has not been properly generated.
  • Internals - Lets you trigger a NuCache snapshots collection.

  • As of Umbraco 15 IPublishedSnapshot, IPublishedSnapshotAccessor, and SnapshotCache are all obsolete.

    ,
    Nothing
    ,
    SourceCodeAuto
    , and
    SourceCodeManual
    .
  • Provides a button to generate models (if the models mode is SourceCodeManual mode only).

  • Reports the last error (if any) that would have prevented models from being properly generated.

  • For more information about Models Builder, see the Models Builder article.

    Number of: Root nodes, Content nodes, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, and Property Editors in use.

  • System information: Webserver, server OS, server framework, server OS language, and database provider.

  • Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, and if you are in debug mode.

  • Basic contains:

    • Anonymized site ID, Umbraco version, and packages installed.

    Minimal contains:

    • Anonymized site ID only

    You can see the specific data being sent on each of the levels directly in the Telemetry Data Dashboard.

    Additionally, Telemetry Data also sends anonymized, analytical data on package usage in Umbraco. Having solid data on package usage is important for both package developers and the Umbraco ecosystem.

    For more information about Package Telemetry, see the Package Telemetry section in the Umbraco 9.2 Release Blog Post.

    Examine Management
    Health Check
    MiniProfiler
    Debugging
    Templates Guide
    VS Code install extension
    Fresh Umbraco installation
    Configure task option
    Create task from template
    Create .NET Core Template
    Creating launch.json file
    Prompt Menu
    Green play button options
    launch.json file
    Web Installer - Lets Get Started
    Document Type Localization
    MediaArticle
    MediaAudio
    MediaVectorGraphics
    MediaVideo
    Date Time with Time Zone editor
    Date Time Unspecified editor
    Languages
  • Document Blueprints

  • Scripts (.js files)

    UI Builder: Helps in designing and customizing the user interface.

    : Learn how to effectively use Umbraco through structured courses, webinars, and hands-on tutorials designed to enhance your proficiency with the CMS.
    Defining Content
    Creating Media
    Settings Dashboards
    Packages
    Users
    Members
    Dictionary Items
    Exploring the Umbraco Products
    Umbraco DXP
    Custom Sections
    backoffice users
    Add-Ons Section
    Time Only property editor showing time format in HH:mm format (hours and minutes only)
    Time Only property editor showing time format in HH:mm:ss format (hours, minutes, and seconds)
    Requirements
    InstallMissingDatabase
    Microsoft Documentation
    Microsoft .Net Core config documentation
    Docker documentation on storage
    described when using runtime modes
    log viewer
    Azure Blob Storage documentation
    Health Check documentation
    Runtime mode documentation
    Overview of DFS Replication in Windows Server 2008 R2
    Watch an intro to installing and working with DFS
    Directory Factory
    Azure Web Apps
    Azure Web Apps
    advanced techniques

    Fix the backoffice environment to be the SCHEDULINGPUBLISHER scheduling server and the scalable public-facing environment to be SUBSCRIBERs - see Setting Explicit Server Roles

    SyncedTempFileSystemDirectoryFactory
    TempFileSystemDirectoryFactory
    .NET Host
    Loadbalancing infrastructure on Azure web apps
    Content Service
    Multi Url Picker Data Type Definition
    Multi Url Picker Content

    toggle code block

    Ctrl + K

    insert image

    Ctrl + G

    This opens the Select Media interface.

    toggle ordered list

    Ctrl + O

    toggle unordered list

    Ctrl + U

    toggle heading

    Ctrl + H

    This toggles between h1, h2 and off.

    toggle a hr

    undo

    Ctrl + Z

    redo

    Ctrl + Y

    toggle bold text

    Ctrl + B

    toggle italic text

    Ctrl + I

    insert link

    Ctrl + L

    This opens the Select Link interface.

    toggle quote

    Ctrl + Q

    select all

    Ctrl + A

    copy

    Ctrl + C

    paste

    Ctrl + V

    Content Service
    Markdown Editor definition example
    Content Example

    Media Picker
    Content Service
    Media Service
    File Upload Definition
    Content Example Empty
    Content Example
    Content Service
    Slider Data Type Definition
    the last code example
    UmbracoHelper reference page
    Tags Data Type Definition Example
    CSV tags example
    JSON tags example
    Tags typeahead example

    Umbraco.Plain.String

    TEXT

    Umbraco.Plain.String

    TIME

    Umbraco.Plain.Time

    XML

    Umbraco.Plain.String

    to
    EditorUiAlias
    , the Umbraco 14 and later equivalent code looks like this:

    Property Editor valueType

    Resulting EditorAlias

    BIGINT

    Umbraco.Plain.Integer

    DATE

    Umbraco.Plain.DateTime

    DATETIME

    Umbraco.Plain.DateTime

    DECIMAL

    Umbraco.Plain.Decimal

    JSON

    Umbraco.Plain.Json

    INT

    Umbraco.Plain.Integer

    package manifest
    Data Editor
    umbraco-package.json
    Creating a Property Editor
    Creating a Custom Database Table

    STRING

    IJsonSerializer
    and use it to serialize the object.
  • Inject the IContentService to retrieve and update the value of a property of the desired content item.

  • Date Time Unspecified property editor configuration
    Date Time Unspecified property editor interface
    Date Time Unspecified property editor showing time format in HH:mm format (hours and minutes only)
    Date Time Unspecified property editor showing time format in HH:mm:ss format (hours, minutes, and seconds)
    available for commercial subscriptions.

    Tiptap extension types

    There are two types of extension: tiptapExtension and tiptapToolbarExtension.

    The tiptapExtension extension is used to register a native Tiptap Extension. These will enhance the capabilities of the rich text editor itself. For example, to enable text formatting, drag-and-drop functionality and spell-checking.

    The tiptapToolbarExtension extension adds a toolbar action that interacts with the Tiptap editor (and native Tiptap extensions).

    Adding a native extension

    This example assumes that you will be creating an Umbraco package using the Vite/Lit/TypeScript setup. You can learn how to do this Vite Package Setup article.

    In this example, you will take the native Tiptap open-source extension Highlight. Then register it with the rich text editor and add a toolbar button to invoke the Task List action.

    1. Install the Highlight extension from the npm registry.

    1. Create the code to register the native Tiptap extensions in the rich text editor.

    1. Create the toolbar action to invoke the Highlight extension.

    Once you have the above code in place, they can be referenced using a bundle extension type.

    Upon restarting Umbraco, the new extension and toolbar action will be available in the Tiptap Data Type configuration settings.

    Tiptap
    Tiptap website
    pro extensions
    TimeOnlyValue value = new TimeOnlyValue
    {
        Date = dateTimeOffset
    };
    string jsonValue = _jsonSerializer.Serialize(value);
    IContent content = _contentService.GetById(contentKey) ?? throw new Exception("Content not found");
    
    // Set the value of the property with alias 'startHours'. 
    content.SetValue("startHours", jsonValue);
    
    // Save the change
    _contentService.Save(content);
    DateOnlyValue value = new DateOnlyValue
    {
        Date = dateTimeOffset
    };
    string jsonValue = _jsonSerializer.Serialize(value);
    IContent content = _contentService.GetById(contentKey) ?? throw new Exception("Content not found");
    
    // Set the value of the property with alias 'eventDate'. 
    content.SetValue("eventDate", jsonValue);
    
    // Save the change
    _contentService.Save(content);
    {
      "ConnectionStrings": {
        "umbracoDbDSN": "server=localhost;database=UmbracoUnicore;user id=sa;password='P@ssw0rd'",
        "umbracoDbDSN_ProviderName": "System.Data.SqlClient"
      }
    }
    {
      "ConnectionStrings": {
        "umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
        "umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
      }
    }
    {
      "Umbraco": {
        "CMS": {
          "Unattended": {
            "InstallUnattended": true,
            "UnattendedUserName": "FRIENDLY_NAME",
            "UnattendedUserEmail": "EMAIL",
            "UnattendedUserPassword": "PASSWORD",
            "UnattendedTelemetryLevel": "Detailed"
          }
        }
      }
    }
    Umbraco__CMS__Unattended__InstallUnattended
    Umbraco__CMS__Unattended__UnattendedUserName
    Umbraco__CMS__Unattended__UnattendedUserEmail
    Umbraco__CMS__Unattended__UnattendedUserPassword
    Umbraco__CMS__Unattended__UnattendedTelemetryLevel
    #if DEBUG
      .ConfigureAppConfiguration(config
        => config.AddJsonFile(
          "appsettings.Local.json",
          optional: true,
          reloadOnChange: true))
    #endif
    {
        "ConnectionStrings": {
            "umbracoDbDSN": "server=localhost;database=UmbracoUnicore;user id=sa;password='P@ssw0rd'"
        },
        "Umbraco": {
            "CMS": {
                "Unattended": {
                    "InstallUnattended": true,
                    "UnattendedUserName": "FRIENDLY_NAME",
                    "UnattendedUserEmail": "EMAIL",
                    "UnattendedUserPassword": "PASSWORD",
                    "UnattendedTelemetryLevel": "Detailed"
                }
            }
        }
    }
    dotnet new umbraco -n MyNewProject --friendly-name "Friendly User" --email [email protected] --password password1234 --telemetry-level Detailed --connection-string "Server=(localdb)\Umbraco;Database=MyDatabase;Integrated Security=true" --version 10.0.0
      "Umbraco": {
        "CMS": {
          "HealthChecks" : {
            "DisabledChecks": [
              {
                "Id": "E2048C48-21C5-4BE1-A80B-8062162DF124"
              }
            ]
          },
          {...}
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Infrastructure.Runtime.RuntimeModeValidators;
    
    namespace MySite;
    
    public class DockerChecksRemover : IComposer
    {
        public void Compose(IUmbracoBuilder builder)
            => builder.RuntimeModeValidators().Remove<UseHttpsValidator>();
    }
    
    {
        "Umbraco": {
            "CMS": {
                "Examine": {
                    "LuceneDirectoryFactory" : "TempFileSystemDirectoryFactory"
                }
            }
        }
    }
    {
        "Umbraco": {
            "CMS": {
                "Examine": {
                    "LuceneDirectoryFactory" : "TempFileSystemDirectoryFactory"
                }
            }
        }
    }
    {
        "Umbraco": {
            "CMS": {
                "Examine": {
                    "LuceneDirectoryFactory" : "SyncedTempFileSystemDirectoryFactory"
                }
            }
        }
    }
    {
        "Umbraco": {
            "CMS": {
                "Examine": {
                    "LuceneDirectoryFactory" : "TempFileSystemDirectoryFactory"
                }
            }
        }
    }
    {
        "Umbraco": {
            "CMS": {
                "Hosting": {
                    "LocalTempStorageLocation" : "EnvironmentTemp"
                }
            }
        }
    }
    {
        "Umbraco": {
            "CMS": {
                "Global": {
                    "MainDomLock" : "FileSystemMainDomLock"
                }
            }
        }
    }
    {
      "name": "UMBRACO__CMS__Global__MainDomLock",
      "value": "FileSystemMainDomLock",
      "slotSetting": false
    },
    {
      "name": "UMBRACO__CMS__Hosting__LocalTempStorageLocation",
      "value": "EnvironmentTemp",
      "slotSetting": false
    },
    {
      "name": "UMBRACO__CMS__Examine__LuceneDirectoryFactory",
      "value": "TempFileSystemDirectoryFactory",
      "slotSetting": false
    }
    @using Umbraco.Cms.Core.Models
    @{
        var links = Model.Value<IEnumerable<Link>>("footerLinks");
        if (links.Any())
        {
            <ul>
                @foreach (var link in links)
                {
                    <li><a href="@link.Url" target="@link.Target">@link.Name</a></li>
                }
            </ul>
        }
    }
    @using Umbraco.Cms.Core.Models
    @{
        var link = Model.Value<Link>("link");
        if (link != null)
        {
            <a href="@link.Url" target="@link.Target">@link.Name</a>
        }
    }
    @{
        var links = Model.FooterLinks;
        if (links.Any())
        {
            <ul>
                @foreach (var link in links)
                {
                    <li><a href="@link.Url" target="@link.Target">@link.Name</a></li>
                }
            </ul>
        }
    }
    @{
        var link = Model.Link;
        if (link != null)
        {
            <a href="@link.Url" target="@link.Target">@link.Name</a>
        }
    }
    @using Umbraco.Cms.Core
    @using Umbraco.Cms.Core.Serialization
    @using Umbraco.Cms.Core.Services
    @using Umbraco.Cms.Core.Models
    @inject IContentService ContentService
    @inject IJsonSerializer Serializer
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Get the media you want to assign to the footer links property 
        var media = Umbraco.Media("bca8d5fa-de0a-4f2b-9520-02118d8329a8");
    
        // Create an Udi of the media
        var mediaUdi = Udi.Create(Constants.UdiEntityType.Media, media.Key);
    
        // Get the content you want to assign to the footer links property 
        var contentPage = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
    
        // Create an Udi of the Content
        var contentPageUdi = Udi.Create(Constants.UdiEntityType.Document, contentPage.Key);
    
        // Create a list with different link types
        var externalLinks = new List<Link>
        {
            // External Link
            new Link
            {
                Target = "_blank",
                Name = "Our Umbraco",
                Url = "https://our.umbraco.com/",
                Type = LinkType.External
            },
            // Media 
            new Link
            {
                Target = "_self",
                Name = media.Name,
                Url = media.MediaUrl(),
                Type = LinkType.Media,
                Udi = mediaUdi
            }, 
            // Content 
            new Link
            {
                Target = "_self",
                Name = contentPage.Name,
                Url = contentPage.Url(),
                Type = LinkType.Content,
                Udi = contentPageUdi
            }
        };
    
        // Serialize the list with links to JSON
        var links = Serializer.Serialize(externalLinks);
    
    
        // Set the value of the property with alias 'footerLinks'. 
        content.SetValue("footerLinks", links);
    
        // Save the change
        ContentService.Save(content);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'footerLinks'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.FooterLinks).Alias, links);
    }
    @Model.MyMarkdownEditor
    @Model.Value("MyMarkdownEditor")
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Create markdown value
        var markdownValue = new HtmlString("#heading  \n**strong text**");
        
        // Set the value of the property with alias 'myMarkdownEditor'. 
        content.SetValue("myMarkdownEditor", markdownValue);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'myMarkdownEditor'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MyMarkdownEditor).Alias, markdownValue);
    }
    @if (Model.HasValue("myFile"))
    {
        var myFile = Model.Value<string>("myFile");
    
        <a href="@myFile">@System.IO.Path.GetFileName(myFile)</a>
    }
    @if (Model.HasValue("myFile"))
    {
       <a href="@Model.MyFile">@System.IO.Path.GetFileName(Model.MyFile)</a>
    }
    @using System.Net
    @using Umbraco.Cms.Core
    @using Umbraco.Cms.Core.Services
    @using Umbraco.Cms.Core.PropertyEditors
    @using Umbraco.Cms.Core.IO
    @using Umbraco.Cms.Core.Serialization
    @using Umbraco.Cms.Core.Strings
    @inject MediaFileManager MediaFileManager
    @inject IShortStringHelper ShortStringHelper
    @inject IContentTypeBaseServiceProvider ContentTypeBaseServiceProvider
    @inject IContentService ContentService
    @inject IMediaService MediaService
    @inject IJsonSerializer Serializer
    @inject MediaUrlGeneratorCollection MediaUrlGeneratorCollection
    @{
        // Create a variable for the GUID of the parent where you want to add a child item
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Create a variable for the file you want to upload, in this case the Our Umbraco logo
        var imageUrl = "https://our.umbraco.com/assets/images/logo.svg";
    
        // Create a request to get the file
        var request = WebRequest.Create(imageUrl);
        var webResponse = request.GetResponse();
        var responseStream = webResponse.GetResponseStream();
    
        // Get the file name 
        var lastIndex = imageUrl.LastIndexOf("/", StringComparison.Ordinal) + 1;
        var filename = imageUrl.Substring(lastIndex, imageUrl.Length - lastIndex);
    
        // Create a media file
        var media = MediaService.CreateMediaWithIdentity("myImage", -1, "File");
        media.SetValue(MediaFileManager, MediaUrlGeneratorCollection, ShortStringHelper, ContentTypeBaseServiceProvider, Constants.Conventions.Media.File, filename, responseStream);
        // Save the created media 
        MediaService.Save(media);
    
        // Get the published version of the media (IPublishedContent)
        var publishedMedia = Umbraco.Media(media.Id);
    
        // Set the value of the property with alias 'myFile' 
        content.SetValue("myFile", publishedMedia.Url());
    
        // Save the child item
        ContentService.Save(content);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'myFile'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MyFile).Alias, publishedMedia.Url();
    }
    @if (Model.HasValue("singleValueSlider"))
    {
        var value = Model.Value<decimal>("singleValueSlider");
        <p>@value</p>
    }
    
    @if (Model.HasValue("multiValueSlider"))
    {
        var value = Model.Value<Umbraco.Cms.Core.Models.Range<decimal>>("multiValueSlider");
        <p>@(value.Minimum) and @(value.Maximum)</p>
    }
    // with a range off
    @if (Model.SingleValueSlider != null)
    {
        var value = Model.SingleValueSlider;
        <p>@value</p>
    }
    
    // with a range on
    @if (Model.MultiValueSlider != null)
    {
        var minValue = Model.MultiValueSlider.Minimum;
        var maxValue = Model.MultiValueSlider.Maximum;
        <p>@minValue and @maxValue</p>
    }
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'singleValueSlider'. 
        content.SetValue("singleValueSlider", 10);
    
        // Save the change
        ContentService.Save(content);
    }
    @using Umbraco.Cms.Core.Models
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Create a variable for the desired value of the 'multiValueSlider' property
        var range = new Range<decimal> {Minimum = 10, Maximum = 12};
    
        // Set the value of the property with alias 'multiValueSlider'. 
        content.SetValue("multiValueSlider", range);
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'singleValueSlider'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.SingleValueSlider).Alias, 10);
    
        // Set the value of the property with alias 'multiValueSlider'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.MultiValueSlider).Alias, new Range<decimal> {Minimum = 10, Maximum = 12});
    }
    @if(Model.Tags.Any()){
        <ul>
            @foreach(var tag in Model.Tags){
                <li>@tag</li>
            }
        </ul>
    }
    @if(Model.HasValue("tags"))
    {
     var tags = Model.Value<IEnumerable<string>>("tags");
        <ul>
            @foreach(var tag in tags)
            {
                <li>@tag</li>
            }
        </ul>
    }
    @using Umbraco.Cms.Core.Serialization
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @inject IJsonSerializer Serializer
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("9daf8585-6ab6-4ac2-98f0-28bf83aeea6e");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'tags'. 
        content.SetValue("tags", Serializer.Serialize(new[] { "News", "Umbraco", "Example", "Setting Tags", "Helper" }));
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'tags'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Tags).Alias, Serializer.Serialize(new[] {  "News", "Umbraco", "Example", "Setting Tags" }));
    }
    public bool IsConverter(IPublishedPropertyType propertyType)
      => propertyType.EditorAlias.Equals("My.Editor.Alias");
    [DataEditor("My.Editor.Alias")]
    public class MySuggestionsDataEditor : DataEditor
    {
    }
    umbraco-package.json
    {
        "name": "My.Editors",
        "version": "1.0.0",
        "extensions": [
            {
                "type": "propertyEditorUi",
                "alias": "My.Editor.Alias",
                (...)
                "meta": {
                    "propertyEditorSchemaAlias": "Umbraco.Plain.String",
                    (...)
                }
            }
        ]
    }
    public bool IsConverter(IPublishedPropertyType propertyType)
      => propertyType.EditorUiAlias.Equals("My.Editor.Alias");
    IContent content = _contentService.GetById(contentKey) ?? throw new Exception("Content not found");
    
    // Set the value of the property with alias 'eventDateTime'. 
    content.SetValue("eventDateTime", jsonValue);
    
    // Save the change
    _contentService.Save(content);
    @Model.EventDateTime.Value
    @Model.Value<DateTime?>("eventDateTime")
    {
        "date": "2025-01-01T00:00:00+00:00"
    }
    using System.Text.Json.Serialization;
    
    namespace UmbracoProject;
    
    public class DateTimeUnspecified
    {
        /// <summary>
        /// The date and time value, represented as a <see cref="DateTimeOffset"/> for storage compatibility.
        /// </summary>
        [JsonPropertyName("date")]
        public DateTimeOffset Date { get; init; }
    }
    DateTime dateTime = DateTime.Now; // Your existing DateTime value
    DateTimeOffset dateTimeOffset = dateTime; // Explicit conversion
    var value = new DateTimeUnspecified
    {
        Date = dateTimeOffset
    };
    string jsonValue = _jsonSerializer.Serialize(value);
    npm install @tiptap/extension-highlight
    import { UmbTiptapExtensionApiBase } from '@umbraco-cms/backoffice/tiptap';
    import { Highlight } from '@tiptap/extension-highlight';
    
    export default class UmbTiptapHighlightExtensionApi extends UmbTiptapExtensionApiBase {
        getTiptapExtensions = () => [Highlight];
    }
    import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';
    import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
    
    export default class UmbTiptapToolbarHighlightExtensionApi extends UmbTiptapToolbarElementApiBase {
        override execute(editor?: Editor) {
            editor?.chain().focus().toggleHighlight().run();
        }
    }
    manifests.ts
    export const manifests: Array<UmbExtensionManifest> = [
        {
            type: 'tiptapExtension',
            kind: 'button',
            alias: 'My Highlight Tiptap Extension',
            name: 'My.Tiptap.Highlight',
            api: () => import('./highlight.tiptap-api.js'),
            meta:{
                icon: "icon-thumbnail-list",
                label: "Highlight",
                group: "#tiptap_extGroup_formatting"
            }
        },
        {
            type: 'tiptapToolbarExtension',
            kind: 'button',
            alias: 'My.Tiptap.Toolbar.Highlight',
            name: 'My Highlight Tiptap Toolbar Extension',
            js: () => import('./highlight.tiptap-toolbar-api.js'),
            forExtensions: ["My.Tiptap.Highlight"],
            meta:{
                alias: "highlight",
                icon: "icon-brush",
                label: "Highlight"
            }
        }
    ]

    Any files/folders related to Stylesheets and JavaScript.

  • Migrate custom configuration from the Umbraco 8 configuration files (.config) into the appsettings.json file on the new project.

    • As of Umbraco version 9, the configuration no longer lives in the Web.Config file and has been replaced by the appsettings.json file. Learn more about this in the Configuration article.

  • Migrate Umbraco Forms data to the database, if relevant.

    • As of Umbraco Forms version 9, it is only possible to store Forms data in the database. If Umbraco Forms was used on the Umbraco 8 project, the files need to be migrated to the database.

  • Run the new project.

    • It will give you an error screen on the frontend as none of the Template files have been updated. Follow Step 3 to resolve the errors.

  • StoreUmbracoFormsInDbset
    database backup guide
    IPublishedContent
    API Documentation
    Issue tracker for known issues with Content Migration
    Configuration in modern Umbraco
    Configuration in legacy Umbraco
  • Example: Selecting the following time zones:

    • Coordinated Universal Time (UTC)

    • Europe/Copenhagen Will result in the following editing experience:

  • to retrieve and update the value of a property of the desired content item.
    Internet Assigned Numbers Authority (IANA)
    IANA
    Date Time with Time Zone property editor configuration
    Date Time with Time Zone property editor showing time zone dropdown with filtering functionality as user types
    Date Time with Time Zone property editor displaying a single time zone as a static label instead of dropdown
    Date Time with Time Zone property editor showing time format in HH:mm format (hours and minutes only)
    Date Time with Time Zone property editor showing time format in HH:mm:ss format (hours, minutes, and seconds)
    Contents

    In this article you will find instructions for 2 different ways of upgrading:

    • Upgrade using NuGet

    • Upgrade manually from a Zip file

    Upgrade using NuGet

    1. Open up the Package Console and type: Update-Package UmbracoCms

    2. Choose "No to All" by pressing the "L" when prompted.

      • If there are any specific configuration changes required for the version you are upgrading to then they will be noted in the version-specific guide.

    Alternatively, you can use the Visual Studio NuGet Package Manager to upgrade:

    1. Open the NuGet Package Manager and select the Updates pane to get a list of available updates.

    2. Choose the package called UmbracoCms and select update.

    The upgrade will run through all the files and make sure you have the latest changes while leaving the files you have updated.

    Upgrades to versions lower than 7.2.0

    If you're not upgrading to 7.2.0 or higher then you should follow these extra instructions. If you are upgrading to 7.2.0+ then you can skip this and go to Merge UI.xml and language.

    You will be asked to overwrite your web.config file and the files in /config, make sure to answer No to those questions.

    For some inexplicable reason, the installation will fail if you click "No to All" (in the GUI) or answer "L" (in the package manager console) to the question: "File 'Web.config' already exists in project 'MySite'. Do you want to overwrite it?" So make sure to only answer "No" (in the GUI) or "N" (in the package manager console).

    File conflict dialog with a web.config file in conflict
    File conflict console message with multiple files in conflict

    We will overwrite the web.config file. We'll back it up so don't worry. You can find the backup in App_Data\NuGetBackup\20140320-165450\. The 20140320-165450 bit is the date and time when the backup occurred, which varies. You can then merge your config files and make sure they're up to date.

    Upgrade manually from a zip file

    Download the .zip file for the new version you are upgrading to from https://our.umbraco.com/download

    Copy the following folders from inside the .zip file over the existing folders in your site:

    • /bin

    • /Umbraco

    • /Umbraco_Client

    There are hosting providers (we know of one: RackSpace Cloud) that require proper casing of file and folder names. Generally, on Windows, this is not a problem. Is your hosting provider forcing proper casing? You'll then need to verify that folders and files are named in the same casing as the version you're upgrading to.

    Merge configuration files

    You can expect some changes to the following configuration files:

    • Any file in the /Config folder

    • The /Global.asax file

    • The web.config file in the root of your site (Important: make sure to copy back the version number, and the connection string as they were.)

    • In rare cases, the web.config file in the Views folder

    Use a tool like WinMerge to check changes between all of the config files. Depending on when you last did this there may have been updates to a few of them.

    There's also the possibility that files in the /Config folder are new or have been removed(we note this in the release notes). WinMerge (and other diff tools) is able to compare folders as well so you can spot these differences.

    Up until version 6.0.0 it was necessary to change the version number in ClientDependency.config. This was to clear the cached HTML/CSS/JS files in the backoffice. Change the current version number to one that's higher than that. Make sure not to skip this step as you might get strange behavior in the backoffice otherwise.

    Merge UI.xml and language

    Some packages (like Contour and Umbraco Forms) add dialogs to the UI.xml. Make sure to merge those changes back in from your backup during the upgrade so that the packages continue to work. This file can be found in: /Umbraco/Config/Create/UI.xml.

    Packages like Contour, Umbraco Forms, and Courier also make changes to the language files located in: /Umbraco/Config/Lang/*.xml (typically en.xml).

    Finalize

    After copying the files and making the config changes, you can open your site. You should see the installer which will guide you through the upgrade.

    The installer will do two things:

    • Update the version number in the web.config

    • Upgrade your database in case there are any changes

    We are aware that, currently, the installer is asking you for the database details of a blank database while upgrading. In the near future this will be pre-filled with your existing details and the wording will be updated. So no need to be scared. Enter the details of your existing database and Umbraco will upgrade it to the latest version when necessary.

    Post installation

    One important recommendation is to always remove the install folder immediately after upgrading Umbraco and never to upload it to a live server.

    Potential issues and gotchas

    Browser cache

    Google Chrome has notoriously aggressive caching. If something doesn't seem to work well in the backoffice, make sure to clear cache and cookies thoroughly (for other browsers as well). Normally the browser cache problem is automatically handled in an Umbraco upgrade by modifying the config/ClientDependency.config version number. If you wish to re-force this update you can increment this version number. This will ensure that any server-side cache of JavaScript and stylesheets gets cleared as well.

    One way to nudge the cache in Chrome is to open the developer tools (F12) and go to the settings (the cog icon). There will be a checkbox that says "Disable cache (while DevTools is open)". Once this checkbox is on you can refresh the page and the cache should be invalidated. To force it even more, the "reload" button next to your address bar now has extra options when you right-click it. It should have "Normal reload", "Hard reload" and "Empty cache and hard reload" now. The last option is the most thorough and you might want to try that.

    version-specific guide
    Adding the nightly feed as a NuGet source

    The NuGet feed containing the nightly builds is https://www.myget.org/F/umbraconightly/api/v3/index.json.

    You can either add this feed through the command line or use an IDE of your choice. In this article, we'll provide steps for:

    • Using the command line

    • Using Visual Studio

    • Using Rider

    Option 1: Using the command line

    To add the nightly feed using the command line:

    1. Open a command prompt of your choice.

    2. Run the following command:

    Now the feed is added as a source named Umbraco Nightly.

    Option 2: Using Visual Studio

    To add the nightly feed using Visual Studio:

    1. Open Visual Studio.

    2. Go to Tools > NuGet Package Manager > Package Manager Settings.

    Package Manager Settings
    1. The Options window open.

    2. Select the Package Sources option in the NuGet Package Manager section.

    3. Click the + icon.

    4. A new Package source will be added automatically and highlighted.

    5. Enter the desired name for the feed in the Name field.

    6. Enter the link https://www.myget.org/F/umbraconightly/api/v3/index.json into the Source field.

    7. Click OK.

    Register the nightly feed

    Now the feed is added as a source named Umbraco Nightly.

    Option 3: Using Rider

    To add the nightly feed using Rider:

    1. Open Rider.

    2. Go to View > Tool Windows > NuGet.

    3. Go to Sources tab.

    4. Choose the C:\Users\Úmbraco\AppData\Roaming\NuGet\NuGet.Config to add the feed globally.

    5. Click the green + button in the New Feed field.

    Open the new feed menu
    1. The New feed dialog opens.

    2. Enter the desired name in the Name field.

    3. Enter https://www.myget.org/F/umbraconightly/api/v3/index.json in the URL field.

    Leave the User, Password fields empty, and the Enabled checkbox ticked.

    Adding the feed
    1. Click OK.

    Now the feed is added as a source named Umbraco Nightly.

    Finding the latest nightly version

    In the previous steps, we've added the feed and are now ready to install the nightly build.

    However, which version should we install? This is, in particular, an issue if we want to create a new site using the dotnet template. The dotnet command does not allow us to use wildcard characters to install the newest version.

    Using IDE, we can see a list of available versions in both Visual Studio and Rider. We can then use that version to install the template.

    Here we're going to assume that you want to create a brand new site with the dotnet template. The approach is the same if you're updating an existing site. You'll click the Update button for the Umbraco.Cms package instead of installing the template through the terminal.

    Let's look at how we can find the latest version of the nightly build:

    • Using Visual Studio

    • Using Rider

    Option 1: Using Visual Studio

    You can use the package manager in Visual Studio to browse the available template versions.

    1. Open Visual Studio.

    2. Go to Tools > NuGet Package Manager > Manage NuGet Packages For Solution...

    Opening the Nuget Package Manager
    1. Select Umbraco Nightly from the Package source dropdown in the NuGet - Solution window.

    Select the nightly NuGet feed
    1. Check the Include prerelease checkbox.

    2. Search for Umbraco.Templates in the Browse field.

    3. Choose that package.

    4. Click on the Version dropdown and see the available nightly builds.

    5. Choose the applicable version and note down the version number.

    Find the version

    Option 2: Using Rider

    You can use the NuGet window in Rider to browse the available template versions.

    1. Open Rider.

    2. Go to the Packages tab in the NuGet window..

    3. Select Umbraco Nightly from the All Feeds dropdown.

    Choose the feed
    1. Check the Prerelase checkbox.

    2. Search for Umbraco.Templates in the Search field.

    3. Choose that package.

    4. Click on the Version drop down and see the available nightly builds.

    5. Choose the applicable version and note down the version number

    Find the version

    Installing the latest nightly version template

    Now that our feed is added and we know the exact version we're ready to install our template.

    To install the latest nightly version template:

    1. Open your command prompt.

    2. Run the following command using the latest version:

    With that, we've successfully installed the latest nightly build of Umbraco.

    All we have to do now is to create a site using the dotnet new umbraco -n MyAwesomeNightlySite command.

    For more information about installing Umbraco, see the Installation article.

    Adding the nightly feed as a NuGet source
    Finding the latest nightly version
    Installing the latest nightly version template
    Settings

    Enable multiple choice

    If enabled, editors will be able to select multiple values from the dropdown otherwise only a single value can be selected.

    Add options

    Options are the values which are shown in the dropdown list. You can add, edit, or remove values here.

    You can use dictionary items to translate the options in a Dropdown property editor in a multilingual setup. For more details, see the Creating a Multilingual Site article.

    Data Type Definition Example

    Dropdown-data-type

    Content Example

    Single Value

    Single dropdown content example

    Multiple Values

    Multiple dropdown content example

    MVC View Example

    Single item - without Models Builder

    Multiple items - without Models Builder

    Single item - with Models Builder

    Multiple items - with Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the Content Service.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Tab and group names.

    Setting up localization for Document Types is a three-step process:

    • Register the Document Type localization files via a new manifest 'umbraco-package.json' file.

    • Create the localizations in user defined Document Type localization files.

    • Apply the localizations to the Document Type.

    Everything in this article also applies to defining Media Types and Member Types.

    Registering Document Type localization Files

    To register Document Type localizations, you must create a new manifest using an umbraco-package.json file.

    The umbraco-package.json file is only registered when placed directly in the /App_Plugins/ or /App_Plugins/{SubFolderName} folder. It will not be recognized in nested subfolders.

    Creating localizations

    Once you have registered the Document Type localization, you can add your localization texts for use in Document Types. The following localizations are used for the samples in this article:

    Umbraco must be restarted to register the localization manifest. Any subsequent localization text changes will need to be reloaded within the browser.

    Applying localizations

    The localizations are applied by using the syntax #{area alias}_{key alias}.

    1. Create a Document Type with Template called #contentTypes_article with the alias: articlePage.

    2. Under the newly created Document Type, follow these steps:

      • Set the description to #contentTypes_article-desc.

      • Create a new tab called #tabs_content.

      • Add a new group called #groups_titles.

      • Add a property called #properties_title with alias title.

        • Set the description to {#properties_title-desc}.

        • Use a TextString editor.

    Property descriptions support Umbraco Flavored Markdown, which uses a different syntax (wrapped in brackets) to avoid conflicts with Markdown headers.

    Applying localization to a property
    1. Add a property called #properties_subTitle with alias subTitle.

      • Set the description to {#properties_subTitle-desc}.

      • Use a TextString editor.

    2. Enable Allow at root in the Structure tab.

    Applying localization to a Document Type

    When creating and editing the content, you will see that the backoffice now uses the configured localizations.

    Localized document creation dialog
    1. Create a new "Article" node:

    Localized document editing
    1. When trying to save the node without adding the mandatory content, you will see a warning as expected:

    Localized property validation
    user's configured UI Culture
    How to enable Language Variants
    Enabling Language Variants on Document Types
    Working with Language Variants on content
    Test your language variants
    Control User Group permissions on language variants
    Related Links
    rendering content section
    Umbraco 8: Language Variants (official blog post from Umbraco HQ)
    Language variations
    Render varied content in Templates
    Adding a language
    Allowing Variance on properties
    Allowing Variance on properties
    Assign access to all or individual languages on the User Group

    Umbraco in Load Balanced Environments

    Information on how to deploy Umbraco in a Load Balanced scenario and other details to consider when setting up Umbraco for load balancing

    Overview

    Configuring and setting up a load balanced server environment requires planning, design and testing. This document should assist you in setting up your servers, load balanced environment and Umbraco configuration.

    This document assumes that you have a fair amount of knowledge about:

    • Umbraco

    • IIS 10+

    • Networking & DNS

    • Windows Server

    • .NET5+

    It is highly recommended that you setup your staging environment to also be load balanced so that you can run all of your testing on a similar environment to your live environment.

    Design

    These instructions make the following assumptions:

    • All web servers can communicate with the database where Umbraco data is stored

    • You are running Umbraco 9.0.0 or above

    • You will designate a single server to be the backoffice server for which your editors will log into for editing content. Umbraco will not work correctly if the backoffice is behind the load balancer.

    There are three design alternatives you can use to effectively load balance servers:

    1. You use cloud based auto-scaling appliances like

    2. Each server hosts copies of the load balanced website files and a file replication service is running to ensure that all files on all servers are up to date

    3. The load balanced website files are located on a centralized file share (SAN/NAS/Clustered File Server/Network Share)

    You will need a load balancer to do your load balancing.

    How Umbraco load balancing works

    In order to understand how to host your site it is best to understand how Umbraco's flexible load balancing works.

    The following diagram shows the data flow/communication between each item in the environment:

    The process is as follows:

    • Administrators and editors create, update, delete data/content on the backoffice server

    • These events are converted into data structures called "instructions" and are stored in the database in a queue

    • Each front-end server checks to see if there are any outstanding instructions it hasn't processed yet

    • When a front-end server detects that there are pending instructions, it downloads them and processes them and in turn updates it's cache, cache files and indexes on its own file system

    Scheduling and server role election

    Although there is a backoffice server designated for administration, by default this is not explicitly set as the "Scheduling server". In Umbraco there can only be a single scheduling server which performs the following tasks:

    • Scheduled tasks - to initiate any configured scheduled tasks

    • Scheduled publishing - to initiate any scheduled publishing for documents

    Automatic Server Role Election

    Umbraco will automatically elect a "Scheduling server" to perform the above services. This means that all of the servers will need to be able to resolve the URL of either: itself, the Backoffice server, the internal load balancer, or the public address.

    There are two server roles:

    • SchedulingPublisher - Usually this is the backoffice instance.

    • Subscriber - These are the scalable front-end instances - not recommended to be used for backoffice access.

    These new terms replace 'Master and Replica', in Umbraco versions 7 and 8.

    Each instance will be allocated a role by the automatic server role election process, but they can also be set explicitly (recommended)

    For example, In the following diagram the node f02.mysite.local is the elected "Scheduling server". In order for scheduling to work it needs to be able to send requests to itself, the Backoffice server, the internal load balancer or the public address. The address used by the "Scheduling server" is called the "umbracoApplicationUrl".

    By default, Umbraco will set the "umbracoApplicationUrl" to the address made by the first accepted request when the AppDomain starts. It is assumed that this address will be a DNS address that the server can resolve.

    For example, if a public request reached the load balancer on www.mysite.com, the load balancer may send the request on to the servers with the original address: www.mysite.com. By default the "umbracoApplicationUrl" will be www.mysite.com. However, load balancers may route the request internally under a different DNS name such as "f02.mysite.local" which by default would mean the "umbracoApplicationUrl" is "f02.mysite.local". In any case the elected "Scheduling server" must be able to resolve this address.

    In many scenarios this is fine, but in case this is not adequate there's a few of options you can use:

    • Recommended: by creating a custom IServerRegistrar, this means the front-end servers will never be used as the SchedulingPublisher server role.

    • Set the UmbracoApplicationUrl property in the

    Common load balancing setup information

    The below section applies to all ASP.NET load balancing configurations.

    Server Configuration

    This section describes the configuration options depending on your hosting setup:

    1. - You use cloud based auto-scaling appliances like

    2. - Each server hosts copies of the load balanced website files and a file replication service is running to ensure that all files on all servers are up to date

    3. - The load balanced website files are located on a centralized file share (SAN/NAS/Clustered File Server/Network Share)

    Data Protection

    The replacement for Machine Keys in ASP.NET Core are called Data Protection. You will need to setup data protection to the same keys on all servers, without this you will end up with view state errors, validation errors and encryption/decryption errors since each server will have its own generated key.

    ASP.NET Core supports multiple ways to share keys. Use the to find a description that fits your setup the best.

    Session State and Distributed Cache

    It is required to setup a distributed cache, like DistributedSqlServerCache or an alternative provider (see for more details). The distributed cache is used by the session in your application, which is used by the default TempDataProvider in MVC.

    Because Umbraco in some cases uses TempData, your setup needs to be configured with a distributed cache.

    Logging

    There are some logging configurations to take into account no matter what type of load balancing environment you are using.

    Testing

    Your staging environment should also be load balanced so that you can see any issues relating to load balancing in that environment before going to production.

    You'll need to test this solution a lot before going to production. You need to ensure there are no windows security issues, etc... The best way to determine issues is have a lot of people testing this setup and ensuring all errors and warnings in your application/system logs in Windows are fixed.

    Ensure to analyze logs from all servers and check for any warnings and errors.

    Unattended upgrades

    When upgrading it is possible to run the upgrades unattended.

    Find steps on how to enable the feature for a load balanced setup in the article.

    FAQs

    Here's some common questions that are asked regarding Load Balancing with Umbraco:

    Question> Why do I need to have a single web instance for Umbraco admin?

    TL:DR You must not load balance the Umbraco backoffice, you will end up with data integrity or corruption issues.

    The reason you need a single server is because there is no way to guarantee transactional safety between servers. This is because we don't currently use database level locking, we only use application (c#) level locks to guarantee transactional data integrity which is only possible to work on one server. If you have multiple admins saving and publishing at once between servers then the order in which this data is read and written to the database absolutely must be consistent otherwise you will end up with data corruption.

    Additionally, the order in which cache instructions are written to the cache instructions table is important for LB, this order is guaranteed by having a single admin server.

    Question> Can my SchedulingPublisher backoffice admin server also serve front-end requests?

    Yes. There are no problems with having your SchedulingPublisher backoffice admin server also serve front-end request.

    However, if you wish to have different security policies for your front-end servers and your back office servers, you may choose to not do this.


    Umbraco Training

    Media Picker

    Schema Alias: Umbraco.MediaPicker3

    UI Alias: Umb.PropertyEditorUi.MediaPicker

    Returns: IEnumerable<MediaWithCrops> or MediaWithCrops

    This property editors returns one of the following:

    • A collection (IEnumerable<MediaWithCrops>) if the Pick multiple items setting is enabled.

    • A single MediaWithCrops item if the Pick multiple items setting is disabled.

    Data Type Definition Example

    Accepted types

    Use setting to limit the picker to only select Media Items of these types.

    Pick multiple items

    Use this setting to enable the property to contain multiple items. When this is enabled the property editor returns an IEnumerable<MediaWithCrops>.

    You can still set the maximum amount to 1. Do so when you want to retrieve a collection but only allow the Content Editors to select one Media Item.

    Amount

    Use this setting to enforce a minimum and/or maximum amount of selected Media Items.

    It is not possible to set a maximum amount when the "Pick multiple items" feature is disabled.

    Start node

    This setting is used to limit the Media Picker to certain parts of the Media Tree.

    Ignore user start nodes

    Use this setting to overrule user permissions, to enable any user of this property to pick any Media Item of the chosen Start node.

    When this setting is enabled, a user can access the media available under the selected "Start Node" (/Design in this case). This applies even if they normally lack access. The access is granted specifically when using this particular Media Picker.

    Enable Focal Point

    Enable the focal point setter, do only enable this if the focal point is used or if you have Image crops defined.

    Image Crops

    Define local image crops. Local image crop data is stored on the document in this property. This means it can differentiate between documents.

    This is different from Global crops as they are defined on the Media Item, making the crops shared between all usage of that Media Item.

    Global crops are configured on the Image Cropper property of the Image Media Type

    Content Example

    MVC View Example

    Multiple enabled without Models Builder

    Multiple enabled without Models Builder to retrieve IEnumerable data

    While MediaWithCrops is the default return type, IPublishedContent may be used in backward-compatible implementations or when working directly with core APIs.

    Multiple enabled with Models Builder

    Multiple disabled without Models Builder

    Multiple disabled with Models Builder

    Using crops

    Both local and global crops are retrieved using the method GetCropUrl. If crops with identical aliases are defined both locally and globally, the locally defined crops are always prioritized by GetCropUrl.

    The following is an example of how to retrieve a crop from a MediaWithCrops entry:

    Explicitly retrieving global crops

    You can retrieve globally defined crops explicitly by using GetCropUrl on the UrlHelper:

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update a value of a property editor you need the .

    The following sample will update a single image in a Media Picker.

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    Style Menu

    A Style Select Menu is a configurable extension that adds a cascading menu to the toolbar for applying text styles and formatting.

    Rich Text Editor cascading style menu

    Any custom stylesheets associated with the Rich Text Editor will not auto-generate a style select menu in the toolbar. See the Creating a Style Select Menu section below.

    Adding Style Select to Rich Text Editor

    To add Style Select to the Rich Text Editor:

    1. Go to Settings.

    2. Navigate to Data Types.

    3. Select the relevant Data Type.

    4. Drag Style Select from Available Actions into the Toolbar section.

    Alternatively, while configuring an editor on a Document Type, you can drag Style Select from Available Actions into the Toolbar section.

    Creating a Style Select Menu

    In this article, you can find an example of how to set up a Style Select Menu using an file.

    The items property defines the structure of the style select menu. Each menu item has the following options:

    • label: (required) The label of the menu item. This supports localization keys.

    • appearance: This defines the appearance of the menu item. The value has 2 optional properties:

      • icon: To prefix an icon to the menu item.

    Once configured, all custom style select menus will appear in the Rich Text Editor toolbar options, as described in the article.

    Supported HTML tags

    Due to Tiptap’s strict rich-text schema, only supported HTML tags are allowed in the style select menu, (arbitrary markup will be excluded). The following HTML tag names are supported:

    • h1

    • h2

    • h3

    • h4

    Minor upgrades for Umbraco 8

    This article provides details on how to upgrade to the next minor version when using Umbraco 8.

    Sometimes there are exceptions to these guidelines, which are listed in the .

    Note

    It is necessary to run the upgrade installer on each environment of your Umbraco site. If you want to update your staging and live site you need to repeat the steps below. Make sure you click through the install screens so that your upgrade is complete.

    Backoffice

    Learn more about the Umbraco backoffice which is the admin side of your Umbraco website

    In this article you can learn more about the common terms and concepts that are used throughout the Umbraco backoffice.

    When you go to the backoffice for the first time, you're presented with the login screen.

    .

    Upgrade Details

    Describes how to upgrade existing installations to new versions.

    In this article, you will find everything you need to upgrade your Umbraco CMS project.

    If you are new to upgrades, be sure to read the first.

    Runtime Modes

    This section describes how to use the runtime mode setting to optimize Umbraco for the best development experience or optimal production environment.

    Configuring the runtime mode

    You can configure the runtime mode to optimize Umbraco for different development experiences and environments by setting Umbraco:CMS:Runtime:Mode to one of the available modes:

    • BackofficeDevelopment

    Install using .NET CLI

    We have made custom Umbraco templates that are available for use with dotnet new. The steps below will demonstrate the minimum amount of actions required to get you going and set up an Umbraco project from the command line using .NET templates.

    Video Tutorial

    Upgrade to Umbraco 7

    This document should be used as a reference, not a step by step guide. Upgrading will largely depend on what version of Umbraco you are currently running, what packages you have installed and the many

    The still apply to this process as well.

    Backup

    It is critical that you back up your website and database before upgrading. There are database changes made during installation and you cannot revert an Umbraco 7 database to an Umbraco 6 database.

    Hosting Umbraco in IIS

    Information on hosting Umbraco on IIS

    Install .NET Core Runtime

    • Download the .NET Core Runtime from the .

    • Ensure you download the version that matches your project’s requirements, which can be found in the

    "ConnectionStrings": {
        "umbracoDbDSN": "Server=YourLocalSQLServerHere;Database=NameOfYourDatabaseHere;User Id=NameOfYourUserHere;Password=YourPasswordHere;TrustServerCertificate=True"
    }
    @Model.EventDateTime.Value
    @Model.Value<DateTimeOffset?>("eventDateTime")
    DateTimeOffset? localTime = Model.EventDateTime?.ToLocalTime();
    DateTimeOffset? utcTime = Model.EventDateTime?.ToUniversalTime();
    DateTime? dateTime = Model.EventDateTime?.DateTime;
    DateTime? utcDateTime = Model.EventDateTime?.UtcDateTime;
    {
        "date": "2025-01-01T00:01:00+01:00",
        "timeZone": "Europe/Copenhagen"
    }
    using System.Text.Json.Serialization;
    
    namespace UmbracoProject;
    
    public class DateTimeWithTimeZone
    {
        /// <summary>
        /// The date and time value, represented as a <see cref="DateTimeOffset"/>.
        /// </summary>
        [JsonPropertyName("date")]
        public DateTimeOffset Date { get; init; }
    
        /// <summary>
        /// The identifier of the time zone to pre-select in the editor. E.g., "Europe/Copenhagen".
        /// </summary>
        [JsonPropertyName("timeZone")]
        public string TimeZone { get; init; }
    }
    var value = new DateTimeWithTimeZone
    {
        Date = DateTimeOffset.Now, // The date and time value to store.
        TimeZone = "Europe/Copenhagen" // The time zone to pre-select in the editor.
    };
    var jsonValue = _jsonSerializer.Serialize(value);
    IContent content = _contentService.GetById(contentKey) ?? throw new Exception("Content not found");
    
    // Set the value of the property with alias 'eventDateTime'. 
    content.SetValue("eventDateTime", jsonValue);
    
    // Save the change
    _contentService.Save(content);
    dotnet nuget add source "https://www.myget.org/F/umbraconightly/api/v3/index.json" -n "Umbraco Nightly"
    dotnet new install Umbraco.Templates
    @if (Model.HasValue("category"))
    {
        <p>@(Model.Value<string>("category"))</p>
    }
    @if (Model.HasValue("categories"))
    {
        var categories = Model.Value<IEnumerable<string>>("categories");
        <ul>
            @foreach (var category in categories)
            {
                <li>@category</li>
            }
        </ul>
    }
    @if (!Model.HasValue(Model.Category))
    {
       <p>@Model.Category</p>
    }
    @if (Model.Categories.Any())
    {
        <ul>
            @foreach (var category in Model.Categories)
            {
                <li>@category</li>
            }
        </ul>
    }
    @using Umbraco.Cms.Core.Serialization
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @inject IJsonSerializer Serializer
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Set the value of the property with alias 'categories'. 
        content.SetValue("categories", Serializer.Serialize(new[] { "News" }));
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'categories'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.Categories).Alias, Serializer.Serialize(new[] { "News" }));
    }
    umbraco-package.json
    {
      "name": "Document Type Localization",
      "extensions": [
        {
          "type": "localization",
          "alias": "DocumentType.Localize.En",
          "name": "English",
          "meta": {
            "culture": "en"
          },
          "js": "/App_Plugins/DocumentTypeLocalization/doctype-en.js"
        }
      ]
    }
    doctype-en.js
    export default {
        contentTypes: {
            article: 'Article page',
            'article-desc': 'A textual, article-like page on the site. Use this as the main type of content.',
            landing: 'Landing page',
            'landing-desc': 'An inviting, very graphical page. Use this as an entry point for a campaign, and supplement with Article pages.'
        },
        tabs: {
            content: 'Page content',
            seo: 'SEO configuration',
        },
        groups: {
            titles: 'Page titles'
        },
        properties: {
            title: 'Main title',
            'title-desc': 'This is the main title of the page.',
            'title-message': 'The main title is required for this page.',
            subTitle: 'Sub title',
            'subTitle-desc': 'This is the sub title of the page.',
        }
    };
    Date Time with Time Zone property editor showing custom time zone selection with UTC and Europe/Copenhagen options

    Set the field validation to mandatory.

  • Under validation add #properties_title-message.

  • How to install Umbraco using NuGet and Visual Studio
    How to use Language Variants in Umbraco
    A video tutorial guiding you through the steps of upgrading from version 8 to the latest version on Umbraco Cloud.
    Read about the Image Cropper here
    Content Service
    Media Picker Data Type Definition
    Media Picker Content

    Click Save.

    style: To apply CSS rules to the menu item.

  • data: To configure the function of the style select menu item. The value has 3 optional properties:

    • tag: A supported HTML tag name. This will be applied to the selected text.

    • class: Applies a class attribute with the defined class name to the containing tag of the selected text.

    • id: Applies an ID attribute with the defined ID value to the containing tag of the selected text.

  • separatorAfter: When true, it will add a line separator after the menu item.

  • items: To enable a cascading menu, an array of nested menu items may be added.

  • h5

  • h6

  • p

  • blockquote

  • code

  • codeBlock

  • div

  • em (italic)

  • ol

  • strong (bold)

  • s (strike-through)

  • span

  • u (underline)

  • ul

  • Umbraco Package Manifest
    Rich Text Editor Configuration
    Adding Style Select to the Rich Text Editor
    Contents

    In this article you will find instructions for 3 different ways of upgrading:

    • Upgrade using NuGet

    • Upgrade manually from a Zip file

    • Run an unattended upgrade (v8.12+)

    Upgrade using NuGet

    1. Open up the Package Console and type: Update-Package UmbracoCms

    2. Choose "No to All" by pressing the "L" when prompted.

      • If there are any specific configuration changes required for the version you are upgrading to then they will be noted in the version-specific guide.

    Alternatively, you can use the Visual Studio NuGet Package Manager to upgrade:

    1. Open the NuGet Package Manager and select the Updates pane to get a list of available updates.

    2. Choose the package called UmbracoCms and select update.

    The upgrade will run through all the files and make sure you have the latest changes while leaving files you have updated.

    Upgrade manually from a zip file

    Download the .zip file for the new version you are upgrading to from https://our.umbraco.com/download

    Copy the following folders from inside the .zip file over the existing folders in your site:

    • /bin

    • /Umbraco

    There are hosting providers (we know of one: RackSpace Cloud) that require proper casing of file and folder names. Normally on Windows this is not a problem. If your hosting provider however forces proper casing, you will need to verify that the folder and file names are in the same casing as in the newest version you're upgrading to.

    Merge configuration files

    You can expect some changes to the following configuration files:

    • Any file in the /Config folder

    • The /Global.asax file

    • The web.config file in the root of your site (Important: make sure to copy back the version number, and the connection string as they were.)

    • In rare cases, the web.config file in the /Views folder

    Use a tool like WinMerge to check changes between all of the config files. Depending on when you last did this there may have been updates to few of them.

    There's also the possibility that some files in the /Config folder are new or some have been removed (we do make a note of this in the release notes). WinMerge (and other diff tools) can compare folders as well so you can spot these differences.

    Merge UI.xml and language files

    Some packages like Umbraco Forms add dialogs to the UI.xml. Make sure to merge those changes back in from your backup during the upgrade so that the packages continue to work. This file can be found in: /Umbraco/Config/Create/UI.xml.

    Packages like Umbraco Forms and Courier also make changes to the language files located in: /Umbraco/Config/Lang/*.xml (typically en.xml).

    Finalize

    After copying the files and making the config changes, you can open your site. You should see the installer which will guide you through the upgrade.

    The installer will do two things:

    • Update the version number in the web.config

    • Upgrade your database in case there are any changes

    We are aware that, currently, the installer is asking you for the database details of a blank database while upgrading. In the near future this will be pre-filled with your existing details and the wording will be updated. So no need to be scared. Enter the details of your existing database and Umbraco will upgrade it to the latest version when necessary.

    Run an unattended upgrade

    When upgrading your Umbraco project to Umbraco v8.12+ it is possible to enable the upgrade to run unattended. This means that you will not need to run through the installation wizard when upgrading.

    Below you will find the steps you need to take in order to upgrade your project unattended.

    Are you running a load balanced setup with multiple servers and environments?

    Check out the section about Unattended upgrades in a load balanced setup.

    Enable the feature

    1. Add the Umbraco.Core.RuntimeState.UpgradeUnattended key to appSettings in your web.config file.

    2. Set the value of the key to true.

    Check the ConfigurationStatus

    In order to trigger the actual upgrade, the correct version number needs to be set.

    It is important to use the version number of the version that you are upgrading to. If this is not set, the upgrade will not run even if the UpgradeUnattended key has been set to true.

    1. Locate the ConfigurationStatus key in the appSettings section in your web.config file.

    2. Update the value to match the Umbraco version that you are upgrading to.

    Run the upgrade

    With the correct configuration applied, the project will be upgraded on the next boot.

    While the upgrade processes are running, any requests made to the site will be "put on hold", meaning that no content will be returned before the upgrade is complete.

    Boot order

    The Runtime level will use Run instead of Upgrade in order to allow the website to continue to boot up directly after the migration is run, instead of initiating the otherwise required restart.

    The upgrade is run after Composers but before Components. This is because the migration requires services that are registered in Composers and Components requires that Umbraco and the database is ready.

    Unattended upgrades in a load balanced setup

    Follow the steps outlined below to use run unattended upgrades in a load balanced setup.

    1. Upgrade Umbraco via NuGet in Visual Studio. Make sure the Umbraco.Core.ConfigurationStatus key in appSetting in the web.config file is updated to match the target version.

    2. Deploy to all environments, including the updated appSetting for Umbraco.Core.ConfigurationStatus.

    3. Set the Umbraco.Core.RuntimeState.UpgradeUnattended key in appSetting in the web.config to true for the Main server only.

    4. Request a page on the Main server and the upgrade will run automatically.

    5. Wait for the upgrade to complete.

    6. Browse the Read-Only servers and make sure they do not show the “upgrade required” screen.

    Post installation

    One important recommendation is to always remove the install folder immediately after upgrading Umbraco and never to upload it to a live server.

    Potential issues and gotchas

    Browser cache

    Google Chrome has notoriously aggressive caching, so if something doesn't seem to work well in the backoffice, make sure to clear cache and cookies thoroughly (for other browsers as well). Normally the browser cache problem is automatically handled in an Umbraco upgrade by modifying the config/ClientDependency.config version number. If you however wish to re-force this update you can increment this version number which will ensure that any server-side cache of JavaScript and stylesheets gets cleared as well.

    One way to nudge the cache in Chrome is to open the developer tools (F12) and go to the settings (the cog icon). There will be a checkbox that says "Disable cache (while DevTools is open)". Once this checkbox is on you can refresh the page and the cache should be invalidated. To force it even more, the "reload" button next to your address bar now has extra options when you right-click it. It should have "Normal reload", "Hard reload" and "Empty cache and hard reload" now. The last option is the most thorough and you might want to try that.

    version-specific guide
    @using Umbraco.Cms.Core.Models
    @{
        var typedMultiMediaPicker = Model.Value<IEnumerable<MediaWithCrops>>("medias");
        foreach (var entry in typedMultiMediaPicker)
        {
            <img src="@entry.MediaUrl()" style="width:200px" />
        }
    }
    @using Umbraco.Cms.Core.Models
    @{
        var listOfImages = Model.Value<IEnumerable<IPublishedContent>>("medias");
        foreach (var image in listOfImages)
        {
            <img src="@image.Url()" alt="@image.Name" />
        }
    }
    @{
        var typedMultiMediaPicker = Model.Medias;
        foreach (var entry in typedMultiMediaPicker)
        {
            <img src="@entry.MediaUrl()" style="width:200px" />
        }
    }
    @using Umbraco.Cms.Core.Models
    @{
        var typedMediaPickerSingle = Model.Value<MediaWithCrops>("media");
        if (typedMediaPickerSingle != null)
        {
            <img src="@typedMediaPickerSingle.MediaUrl()" style="width:200px" alt="@typedMediaPickerSingle.Value("alt")" />
        }
    }
    @using Umbraco.Cms.Core.Models
    @{
        var typedMediaPickerSingle = Model.Media;
        if (typedMediaPickerSingle is MediaWithCrops mediaEntry)
        {
            <img src="@mediaEntry.MediaUrl()" style="width:200px"/>
        }
    }
    @{
        foreach (var entry in Model.Medias)
        {
            <img src="@entry.GetCropUrl("cropAlias")"/>
        }
    }
    @{
        foreach (var entry in Model.Medias)
        {
            <img src="@Url.GetCropUrl(entry, "cropAlias")"/>
        }
    }
    @using Umbraco.Cms.Core
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Get the media you want to assign to the media picker 
        var media = Umbraco.Media("bca8d5fa-de0a-4f2b-9520-02118d8329a8");
    
        // Create an Udi of the media
        var udi = Udi.Create(Constants.UdiEntityType.Media, media.Key);
    
        // Set the value of the property with alias 'featuredBanner'. 
        content.SetValue("featuredBanner", udi.ToString());
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234); 
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'featuredBanner'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.FeaturedBanner).Alias, udi.ToString());
    }
    umbraco-package.json
    {
        "name": "Name of your package",
        "alias": "My.Package",
        "extensions": [
            {
                "type": "tiptapToolbarExtension",
                "kind": "styleMenu",
                "alias": "MyCustom.Tiptap.StyleMenu",
                "name": "My Custom Tiptap Style Menu",
                "meta": {
                    "alias": "myCustomStyleMenu",
                    "icon": "icon-palette",
                    "label": "My custom styles"
                },
                "items": [
                    {
                        "label": "Headings",
                        "items": [
                            {
                                "label": "Heading 2",
                                "data": { "tag": "h2" },
                                "appearance": { "icon": "icon-heading-2" }
                            },
                            {
                                "label": "Heading 3",
                                "data": { "tag": "h3" },
                                "appearance": { "style": "font-size: large;" }
                            },
                            {
                                "label": "Heading 4",
                                "data": { "tag": "h4" }
                            }
                        ]
                    },
                    {
                        "label": "Attributes",
                        "items": [
                            {
                                "label": "Classes",
                                "data": { "class": "foo" }
                            },
                            { 
                                "label": "IDs",
                                "data": { "id": "bar" }
                            },
                            {
                                "label": "Mixed",
                                "data": { "tag": "span", "class": "foo", "id": "bar" }
                            }
                        ]
                    }
                ]
            }
        ]
    }
        <add key="Umbraco.Core.RuntimeState.UpgradeUnattended" value="true" />
    <add key="Umbraco.Core.ConfigurationStatus" value="x.x.x"/>

    There can be a delay between content updates and a front-end server's refreshing, this is expected and normal behaviour.

    Microsoft's Azure Web Apps
    set your front-end(s) (non-admin server) to be explicit subscriber servers
    WebRouting section of the CMS config
    Azure Web Apps
    Microsoft's Azure Web Apps
    File Replication
    Centralized file share
    Full documentation is available here
    official docs
    https://docs.microsoft.com/en-us/aspnet/core/performance/caching/distributed
    Full documentation is available here
    General Upgrades
    Umbraco flexible load balancing diagram
    Umbraco flexible load balancing diagram
    Section

    A section in Umbraco is where you do specific tasks related to that section. For example Content, Settings and Users. You can navigate between the different sections of the backoffice by clicking the corresponding icon in the section menu.

    The Section menu is the horizontal menu located on the top of the backoffice.

    Section

    Read more about the section menu.

    Tree

    A tree is a hierarchical list of items related (and usually restricted) to a specific concept, like for example content or media.

    You can expand trees by clicking the side arrow to the left of the node.

    Tree

    Read more about the Tree

    Node

    A node is an item in a tree. Media section items appear as nodes in the Media tree, while pages and content are displayed in the Content tree, and so on.

    Node

    Dashboards

    A dashboard is the main view you are presented with when entering a section within the backoffice. It can be used to show valuable information to the users of the system.

    Default dashboard in the Content section

    Read more about Dashboards

    Editor

    An editor is what you use to edit different items within the backoffice. There are editors specific to editing stylesheets, there are editors for editing Partial Views, and so forth.

    Content

    Content is what you find in the Content section. Each item in the tree is called a content node. Each content node in the content tree consists of different fields, and each of them is defined by a Document Type.

    Content

    Read more about Content

    Document Type

    Document Types define the types of content nodes that backoffice users can create in the content tree. Each Document Type contains different properties. Each property has a specific Data Type for example text or number.

    Document Types

    Properties

    Every Document Type has properties. These are the fields that the content editor is allowed to edit for the content node.

    Document Type Properties

    Data Type

    Each Document Type property has a Data Type that defines the type of input of that property. Data Types reference a Property Editor and are configured in the Umbraco backoffice in the Settings section. A Data Type can be something basic (text string, number, true/false) or more complex (multi-node tree picker, image cropper, etc).

    Data Types

    Read more about Data Types

    Property Editors

    A property editor is a view used by Data Types to insert content into Umbraco. An example of a property editor is the Textarea. It's possible to have many Textarea Data Types with different settings that all use the Textarea property editor.

    Property Editor

    Read more about Property Editors

    Media

    Media items are used to store assets like images and video within the Media section and can be referenced from your content.

    Media

    Read more about Media

    Media Types

    Media Types are similar to Document Types in Umbraco, except they are specifically for media items in the Media section.

    Umbraco includes the following default Media Types - Article, Audio, File, Folder, Image, Vector Graphics (SVG), and Video.

    Media Types

    Members

    A member is someone who has access to signup, register, and login into your public website and is not to be confused with Users.

    Members

    Read more about Members

    Member Types

    Similar to a Document Type and a Media Type. You are able to define custom properties to store on a member such as Twitter username or website URL.

    Member Types

    Templates

    A Template is where you define the HTML markup of your website and also where you output the data from your content nodes.

    Templates

    Read more about Templates

    Packages

    A package is the Umbraco term for an add-on or plugin used to extend the core functionalities in Umbraco. The packages can be found on the Umbraco Marketplace, and the can also be browsed directly in the backoffice of the Umbraco CMS.

    Packages

    Users

    A user is someone who has access to the Umbraco backoffice and is not to be confused with Members. When Umbraco has been installed a user will automatically be generated with the login (email) and password entered during installation. Users can be created, edited, and managed in the User section.

    Users

    Document Blueprints

    Document Blueprint provide a blueprint for content nodes based on an existing node.

    Document Blueprint
    Login screen
    Read more about the login screen
    Login screen
    Upgrade to a new Major

    You can upgrade to a new major version of Umbraco CMS directly by using NuGet.

    You must upgrade to the closest Long-term Support (LTS) major version before upgrading to the latest version. For Umbraco 10, the closest long-term support version is Umbraco 13. Once the project is on Umbraco 13, you can move on to Umbraco 14.

    Switching to a new major version of Umbraco CMS also means switching to a new .NET version. Ensure that any packages used on your site are compatible with this version before upgrading.

    The package compatibility can be checked on the package's download page. Locate the Project compatibility area and select View details to check version-specific compatibility.

    Choose the correct .NET version

    Use the table below to determine which .NET version to upgrade to when going through the steps below.

    CMS version
    .NET version

    17

    10.0

    16

    9.0

    15

    9.0

    14

    8.0

    13

    8.0

    12

    7.0

    Upgrade your project using Visual Studio

    If you are upgrading a Cloud project locally from version 14 to 15, remove the Umbraco.Cloud.Cms.PublicAccess and Umbraco.Cloud.Identity.Cms packages. For more details, see Step 3: Upgrade the project locally using Visual Studio in the Umbraco Cloud Documentation.

    It's recommended that you upgrade the site offline and test the upgrade fully before deploying it to the production environment.

    1. Stop your site in IIS to prevent any changes from being made while you are upgrading.

    2. Open your Umbraco project in Visual Studio.

    3. Right-click on the project name in the Solution Explorer and select Properties.

    4. Select the .NET version from the Target Framework drop-down.

    5. Go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution...

    6. Go to the Installed tab in the NuGet Package Manager.

    7. Upgrade Umbraco.Cms.

      a. Select the correct version from the Version drop-down.

      b. Click Install to upgrade your project.

    If you have other packages like Umbraco Forms installed, upgrade them before upgrading Umbraco.CMS. Consult the version-specific upgrade notes for Umbraco Forms if relevant.

    1. Make sure that your connection string has TrustServerCertificate=True to complete the upgrade successfully:

    1. Restart your site in IIS, then build and run your project to finish the installation.

    Umbraco 13 and later versions use the Minimal Hosting Model.

    If you have added custom code to the startup.cs file, it is recommended to move that code into a Composer after upgrading.

    If your database experiences timeout issues after an upgrade, it might be due to the ASP.NET Core Module's startupTimeLimit configuration.

    To fix the issue, try increasing the startupTimeLimit in the web.config file. Additionally, you can set the Connection Timeout value in the ConnectionString in the appsettings.json file.

    It is necessary to run the upgrade installer on each environment of your Umbraco site. This wil occur on first boot of an upgraded project as it is deployed into a new environment.

    Potential issues and gotchas

    If you receive an error that a deploy license is missing even though you have a valid license, follow the guide below.

    Google Chrome has aggressive caching, so when experiencing startup issues, clear the cache and cookies thoroughly. Ideally, this should be done for other browsers as well.

    Nudge the cache in Chrome following these steps:

    1. Open the developer tools (F12).

    2. Go to the settings (Cog icon).

    3. Ensure that "Disable cache (while DevTools is open)" is checked.

    4. Refresh the page, and the cache will be invalidated.

    5. Right-click the "reload" button next to your address bar and choose "Empty cache and hard reload".

    All caches and cookies have now been cleared from your Google Chrome browser. Generally, it is a good thing to do occasionally.

    Upgrade to a new Minor

    NuGet installs the latest version of the package when you use the dotnet add package command unless you specify a package version:

    dotnet add package Umbraco.Cms --version <VERSION>

    Add a package reference to your project by executing the dotnet add package Umbraco.Cms command in the directory that contains your project file.

    Run dotnet restore to install the package.

    For Umbraco 9 If you are using SQL CE in your project, you need to run dotnet add package Umbraco.Cms.SqlCe --version <VERSION> before the dotnet restore command. From Umbraco 10, SQL CE has been replaced with SQLite, so a dotnet restore should be sufficient. If this is not working, then you need to run dotnet add package Umbraco.Cms.Persistence.Sqlite --version <VERSION> , and then dotnet restore.

    When the command completes, open the .csproj file to make sure the package reference was updated:

    Legacy Umbraco

    The steps outlined in this article apply to Umbraco version 10 and later versions.

    Are you upgrading to a minor version for Umbraco 6, 7, or 8? You can find the appropriate guide below:

    upgrade introduction article
    Upgrade to a new Major
    Upgrade to a new Minor
    Legacy Umbraco
    Minor upgrades for Umbraco 8
    Minor upgrades for Umbraco 7
    (default)
  • Development

  • Production

  • This can be done via the appsettings.json file, environment variables, or any other .NET configuration provider (like Azure Key Vault/App Configuration). Although this setting affects how Umbraco behaves at runtime, some modes have prerequisites on how the project is built/published. Make sure to read the descriptions of each mode before changing this setting from the default BackofficeDevelopment mode, as incorrect configuration can result in your application not starting (by throwing a BootFailedException).

    BackofficeDevelopment mode

    The BackofficeDevelopment mode is the default behavior for Umbraco: it does not optimize Umbraco for any specific environment and does not have any prerequisites. This mode allows for rapid development (without having to recompile/rebuild your project), including all development from within the backoffice.

    Development mode

    The Development mode can be used when you're developing from an IDE (like Visual Studio, VS Code, or Rider) or the dotnet CLI (e.g. using dotnet watch). It is a recommended prerequisite if you want to use the Production mode in your production environment.

    This mode disables in-memory ModelsBuilder generation and validates the following setting:

    • Umbraco:CMS:ModelsBuilder:ModelsMode is not set to InMemoryAuto.

    If you want to use the generated models, use SourceCodeAuto or SourceCodeManual. These require manually recompiling the project after the models have changed (for example after updating Document Types, Media Types, Member Types, or Data Types). Razor views (cshtml files) will still be automatically compiled at runtime. They allow you to quickly iterate on the rendered output from templates, partial views, and view components.

    The recommended approach to enable Development mode is to update the appsettings.json file with the following settings:

    Ensure your models are generated by running Umbraco and navigating to Settings > Models Builder > Generate models. You can remove the following properties from your csproj project file to enable the compilation of Razor views (which also ensures your views do not contain compilation errors and is a prerequisite for enabling Production mode):

    Fix any compilation errors you might get after this, e.g. if you accidentally referenced deleted models or properties. Running the application will still show the rendered content and you're now ready to optionally enable Production mode on your production environment.

    Ensure you have the <CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory> property set in your csproj project file, so Razor views are always copied to the publish directory. This is required by the CMS to display the contents in the backoffice, for Forms to lookup custom theme views and for Deploy to be able to compare schemas (otherwise you'll get schema mismatches).

    Production mode

    Use Production mode to ensure your production environment is running optimally by disabling development features and validating whether specific settings are configured to their recommended production values.

    This mode disables both in-memory ModelsBuilder generation (see Development mode) and Razor (cshtml) runtime compilation. Production mode requires you to compile your views at build/publish time and enforces the following settings for optimal performance/security:

    • The application is built/published in Release mode (with JIT optimization enabled), e.g. using dotnet publish --configuration Release;

    • Umbraco:CMS:WebRouting:UmbracoApplicationUrl is set to a valid URL;

    • Umbraco:CMS:Global:UseHttps is enabled;

    • Umbraco:CMS:ModelsBuilder:ModelsMode is set to Nothing.

    To compile your views at build/publish time, remove the <RazorCompileOnBuild> and <RazorCompileOnPublish> properties from your project file (see the Development mode section). If you don't, Umbraco can't find the templates and will return 404 (Page Not Found) errors.

    The recommended approach to enable Production mode is to update the appsettings.Production.json file (or create one) with the following settings:

    Although you can still edit document types and views (if not running from the published output), changes won't be picked up until you've rebuilt your project or republished the application.

    Models won't be generated by ModelsBuilder (because the mode is set to Nothing), requiring you to do all your changes while in Development mode. As Models Builder is set to Nothing, the Models Builder dashboard is disabled in the backoffice of live environment.

    Also, templates cannot be edited on live environment as runtime compilation is not enabled and is set to Production.

    Also ensure the UmbracoApplicationUrl is updated to the primary URL of your production environment, as this is used when sending emails (password reset, notifications, health check results, etc.).

    Static web assets are disabled when using Production mode, following Microsoft guidance. If you are running a non-Development environment using the Production runtime mode from source (non-published output), you will need to explicitly enable this. You can add the following line of code to your Program.cs file:

    This should not be used in a more typical production environment where you are hosting your application from published output.

    Customize/extend runtime mode validation

    Validation of the above-mentioned settings is done when determining the runtime level during startup using the new IRuntimeModeValidationService and when it fails, causes a BootFailedException to be thrown. The default implementation gets all registered IRuntimeModeValidators to do the validation, making it possible to remove default checks and/or add your own (inherit from RuntimeModeProductionValidatorBase, if you only want to validate against the production runtime mode). The following validators are added by default:

    • JITOptimizerValidator - Ensure the application is built/published in Release mode (with JIT optimization enabled) when in production runtime mode, e.g. using dotnet publish --configuration Release;

    • UmbracoApplicationUrlValidator - ensure Umbraco:CMS:WebRouting:UmbracoApplicationUrl is configured when in production runtime mode;

    • UseHttpsValidator - ensure Umbraco:CMS:Global:UseHttps is enabled when in production runtime mode;

    • ModelsBuilderModeValidator - ensure Umbraco:CMS:ModelsBuilder:ModelsMode is not set to InMemoryAuto when in development runtime mode and set to Nothing when in production runtime mode.

    The following example removes the default UmbracoApplicationUrlValidator and adds a new custom DisableElectionForSingleServerValidator:

    Install the template
    1. Install the latest .NET SDK.

    2. Run dotnet new install Umbraco.Templates to install the project templates. The solution is packaged up into the NuGet package Umbraco.Templates and can be installed into the dotnet CLI.

    Once that is complete, you can see that Umbraco was added to the list of available projects types by running dotnet new --list:

    In some cases the templates may silently fail to install (usually this is an issue with NuGet sources). If this occurs you can try specifying the NuGet source in the command by running dotnet new install Umbraco.Templates --nuget-source "https://api.nuget.org/v3/index.json".

    To get help on a project template with dotnet new run the following command:

    dotnet new umbraco -h

    From that command's output, you will get a better understanding of what are the default template options, as well as those command-line flags specific to Umbraco that you can use (as seen below):

    Create an Umbraco project

    1. Create a new empty Umbraco solution: dotnet new umbraco -n MyCustomUmbracoProject

    You will now have a new project with the name MyCustomUmbracoProject, or the name you chose to use. The new project can be opened and run using your favorite IDE or you can continue using the CLI commands.

    If you want to create a solution file as well you can run the commands below. dotnet new sln dotnet sln add MyCustomUmbracoProject

    Run Umbraco

    1. Navigate to the newly created project folder: cd MyCustomUmbracoProject

    2. Build and run the new Umbraco .Net Core project: dotnet build dotnet run

    The project is now running on the Kestrel server and has assigned a free available port to run it on. Look in the terminal window after the dotnet run command to see the URLs.

    The next step is to run through the Umbraco CMS installation. If you chose to use MS SQL Server/Azure you will need to add your connection string during this setup process to get access to the Umbraco backoffice.

    .Net 4.5

    Umbraco 7 is built on .Net 4.5 and your development environment will require this version installed in order to operate. Visual Studio users may require 2012 or higher.

    HTML 5 browser support

    Umbraco 7 requires browsers with proper HTML 5 support, these include Chrome, Firefox, IE10+

    Breaking changes

    Before you upgrade be sure to read the list of breaking changes. This is especially recommended if you have removed or modified code in the core or if one of these breaking changes directly affects your installation.

    See the list of breaking changes for more details.

    Examine

    It is recommended to rebuild all Examine indexes after completing the upgrade.

    Xml Cache rebuild

    You should re-generate the XML cache. This can be done by following the prompts when visiting the following URL:

    your-domain.com/umbraco/dialogs/republish.aspx?xml=true

    Configuration changes

    It is recommended that you use a Diff tool to compare the configuration file changes with your own current configuration files.

    • /web.config updates

      • Details are listed here: https://issues.umbraco.org/issue/U4-2900

      • You will need to compare the new Umbraco 7 web.config with your current web.config. Here is a quick reference of what needs to change:

        • Remove the section name="BaseRestExtensions" section

        • Remove the section name="FileSystemProviders" section

        • Remove the sectionGroup name="system.web.webPages.razor" section

        • Remove the <FileSystemProviders> element

        • Remove the BaseRestExtensions element

        • Remove the add key="umbracoUseMediumTrust" element

        • Remove the system.web.extensions element

        • Removes the xhtmlConformance element

        • Remove the system.codedom element

        • Remove the compilation assemblies, /compilation

        • Remove the system.web.webPages.razor element

        • New: sectionGroup name="umbracoConfiguration" section

        • New: umbracoConfiguration element

        • Ensure that the targetFramework="4.5" is added to the httpRuntime element

        • Add add key="ValidationSettings:UnobtrusiveValidationMode" value="None" to the appSettings element

    • /config/clientdependency.config changes

      • remove add name="CanvasProvider" element

    • /views/web.config updates

    • New macroscripts/web.config

    • config/umbracoSettings.config

      • Umbraco is now shipped with minimal settings but the are still available

      • umbracoSettings is now a true ASP.NET configuration section

    • Removed xsltExtensions.config

    • /config/applications.config and /config/trees.config have some icon paths and names updated. You need to merge the new changes into your existing config files.

    • /config/tinyMceConfig.config

      • The inlinepopups is compatible and supported in Umbraco 7. You need to remove these elements: plugin loadOnFrontend="true", inlinepopups/plugin;

      • The plugins element that is shipped with Umbraco 7 looks like this:

    • /config/dashboard.config

      • You need to merge the changes from the new dashboard.config into yours. Some of the original dashboard entries that were shipped with Umbraco 6 have been replaced or removed.

    Medium Trust

    Umbraco 7+ will no longer support medium trust environments. There are now some assemblies used in the core that do not support medium trust but are used extensively. Plugin scanning now also allows for scanning Umbraco's internal types which requires full trust.

    Events

    Tree events

    Content, Media, Members, and Data Type trees will no longer raise the legacy tree events (based on BaseTree). It is recommended to change all tree event handlers to use the new tree events that fire for every tree in Umbraco including legacy trees. The new tree events are static events and are found in the class Umbraco.Web.Trees.TreeControllerBase:

    • MenuRendering

    • RootNodeRendering

    • TreeNodesRendering

    Legacy business logic events

    The Content, Media, Member, and Data Type editors have been re-created and are solely using the new Umbraco Services data layer. This means that operations performed in the backoffice will no longer raise the legacy business logic events (for example, events based on umbraco.cms.businesslogic.web.Document). It is recommended to change your event handlers to subscribe to the new Services data layer events. These are static events and are found in the services. For example: Umbraco.Core.Services.ContentService.Saved.

    Property Editors

    Legacy property editors (pre-Umbraco 7) will not work with Umbraco 7. During the upgrade installation process, Umbraco will generate a report showing you which legacy property editors are installed. These will all be converted to a readonly Label property editor. No data loss will occur but you'll need to re-assign your existing data types to use a new compatible Umbraco 7 property editor.

    Most Umbraco core property editors shipped will be mapped to their equivalent Umbraco 7 editors. The Image cropper editor has not been completed for v7.0.

    The Related Links property editor and XSLT

    Since the Related Links property is an advanced property editor, the data format has changed from XML to JSON. This should not have any effect when retrieving the data from razor. If you are outputting Related Links data with XSLT you will need to update your XSLT snippet. Making use of the new library method umbraco.library:JsonToXml and taking into account that the xml structure has also slightly changed.

    GUID -> Alias mapping

    One of the database changes made in Umbraco 7 is the change of referencing a property editor from a GUID to a string alias. In order to map a legacy property editor to a new Umbraco 7 version you can add your custom "GUID -> Alias" map during application startup. To do this you would add your map using this method: Umbraco.Core.PropertyEditors.LegacyPropertyEditorIdToAliasConverter.CreateMap

    Parameter Editors

    Legacy parameter editors (pre-Umbraco 7) will not work with Umbraco 7. If Umbraco detects legacy parameter editor aliases that do not map to a Umbraco 7 parameter editor it will render a textbox in its place. You will need to update your macros to use a compatible Umbraco 7 parameter editor as those that aren't supported.

    Previously, parameter editors were registered in an Umbraco database table: cmsMacroPropertyType which no longer exists. Parameter editors in Umbraco 7 are plugins like property editors. During the Umbraco 7 upgrade installation process it will update the new cmsMacroProperty.editorAlias column with the previous parameter editor alias. During this process it will look into the Umbraco.Core.PropertyEditors.LegacyParameterEditorAliasConverter for a map between a legacy alias to a new Umbraco 7 alias.

    Custom legacy parameters can be mapped to new Umbraco 7 parameter editor aliases during installation. This can be done by modifying the mapping during application startup using this method: Umbraco.Core.PropertyEditors.LegacyParameterEditorAliasConverter.CreateMap.

    Database changes

    All database changes will be taken care of during the upgrade installation process.

    For database change details see (including all child tasks):

    • Issue U4-2886

    • Issue U4-3015

    Tags

    See above for the database updates made for better tag support.

    • Tags can now be assigned to a nodes property and not only a node

    • Multiple tag controls can exist on one page with different data

      • The legacy API does not support this, the legacy API will effectively, add/update/remove tags for the first property found for the document that is assigned a tag property editor.

    • There is a new ITagService that can be used to query tags

      • Querying for tags in a view (front-end) can be done via the new TagQuery class which is exposed from the UmbracoHelper. For example: @Umbraco.TagQuery.GetTagsForProperty

    Packages

    You should check with the package creator for all installed packages to ensure they are compatible with Umbraco 7.

    For package developers

    We see common errors that we cannot fix for you, but we do have recommendations you can follow to fix them:

    TypeFinder

    The TypeFinder has been deprecated since 4.10 and is now found under Umbraco.Core.TypeFinder.

    JavaScript in menu actions

    While you need to have JavaScript inside menu actions to trigger a response, it is highly recommended that you use the recommended UmbClientMgr methods. You should not try to override parent.right.document and similar tricks to get to the right-hand frame.

    Use the recommended Umbraco uicontrols

    If you have a webforms page, it is recommended to use the built-in ASP.NET controls to render panels, properties and so on. If you use the raw HTML or try to style it to match the backoffice, you will get out of sync. Follow the guidelines set by Umbraco's internal editors and use the ASP.NET custom controls for UI.

    standard upgrade instructions
    article.

    Install the Hosting Bundle

    Download the ASP.NET Core Runtime Hosting Bundle to enable IIS to run ASP.NET Core applications.

    Restart IIS

    After installing .NET Core Runtime, restart IIS to ensure the changes are applied.

    1. Open Command Prompt as Administrator.

    2. Run the following commands:

    Create the Site in IIS

    Next, create a new site in IIS for hosting Umbraco.

    Set Application Pool

    1. Open IIS Manager.

    2. Right-click on Application Pools in the Connections panel.

    3. Select Add Application Pool.

    4. Enter the Name.

    5. Ensure the .NET Common Language Runtime (CLR) version is set to No Managed Code.

    6. Click Ok.

    IIS Application Pool

    Create a Site

    1. Open IIS Manager.

    2. Right-click on Sites in the Connections panel.

    3. Select Add Website.

    4. Fill in the Site Name, Physical Path (to your Umbraco installation), and the Port.

    5. Click Ok.

    IIS Creating Site

    Publish the Website

    You can either use the dotnet CLI or Visual Studio to publish your Umbraco website.

    Option 1: Use dotnet CLI for Manual Deployment

    1. Open the Command Prompt in the directory of your Umbraco project.

    2. Run the following command:

    Make sure to replace net9.0 with the version of .NET you are using.

    Using dotnet CLI for Manual Deployment

    Option 2: Use Visual Studio to Deploy

    1. Open your project in Visual Studio.

    2. Right-click on the Umbraco project in Solution Explorer.

    3. Select Publish....

    Using Visual Studio to Deploy

    To deploy Umbraco to IIS via Azure DevOps, you can use the IIS Release task in Azure DevOps. This task is a wrapper for MSDeploy.exe and can be configured as preferred.

    Configure Environment Variables

    In IIS, you can configure environment variables for Umbraco to store sensitive data such as your connection string.

    Configure Environment Variables in IIS

    1. Open IIS Manager and select your Umbraco site.

    2. Double-click Configuration Editor in the Management section.

    IIS Website Configuration
    1. Select system.webServer/aspNetCore in the Section dropdown.

    2. Select ApplicationHost.config <location path='[YOUR-SITENAME]'> in the From dropdown.

    This ensures your settings will be stored in a machine specific file. The configuration files might end in a public repository and should not contain sensitive data like Connection Strings or Simple Mail Transfer Protocol (SMTP) credentials. Additionally, by default the configuration file will be overwritten during each publish processes.

    1. Locate the environmentVariables line and open the dialog to add environment variables.

    2. Enter the values for ASPNETCORE_ENVIRONMENT and ConnectionStrings__umbracoDbDSN.

    • Variable names need to change the object structure form JSON by combining the segments with double underscore __ For example: ConnectionStrings__umbracoDbDSN

    • Escaped backslashes \\ For example: serverName\\databaseInstanceName are replaced by single backslash \ (DATABASESERVER123\SQL2017)

    1. Click Add.

    2. Click Apply.

    IIS Configuration Editor
    1. Restart IIS to apply the changes after updating the environment variables.

    IIS Hosting Models

    IIS can host .NET applications using two different hosting models: In-process (default) and Out-of-process.

    In-process Hosting (Default)

    • In-process hosting runs the .NET application within the same process as the IIS worker process.

    • This is the default hosting model and is more efficient, as there is no inter-process communication between IIS and the application.

    Default Configuration

    No changes are required to your application configuration for in-process hosting. It works automatically with the default IIS settings.

    Out-of-process Hosting

    • Out-of-process hosting allows the .NET application to run separately from the IIS worker process. IIS acts as a reverse proxy to the Kestrel server, which hosts the .NET application.

    • This model is useful when you need to run a .NET application in a separate process, for example, when the application requires more isolated resources or needs to scale independently from IIS.

    Configuration

    To enable out-of-process hosting:

    1. Open your Umbraco project.

    2. Locate the .csproj file.

    3. Add the following line:

    1. Save the .csproj file.

    2. Rebuild your application.

    Troubleshooting: Handling WebDAV Module Interference

    Issue: A 405 error may occur when attempting to save content items in Umbraco, due to the WebDAV module blocking PUT requests.

    Solution: If you encounter this issue, it may be because the WebDAV module in IIS is blocking the necessary PUT requests. This issue is not present on all IIS setups, but if you do have WebDAV installed, try disabling the WebDAV module.

    Workaround:

    1. Open the web.config file.

    2. Add the following code to remove the WebDAV module:

    1. Restart IIS.

    Download .NET page
    requirements

    Image Cropper

    Schema Alias: Umbraco.ImageCropper

    UI Alias: Umb.PropertyEditorUi.ImageCropper

    Returns: MediaWithCrops

    Returns a path to an image, along with information about focal point and available crops.

    When the Image Cropper is used on a Media Type the crops are shared between all usages of a Media Item. This is called global crops.

    If the Image Cropper is used on a Document Type, the file and crops will be local to the Document.

    Notice that it is possible make local crops on shared Media Items via the Media Picker Property Editor.

    Settings

    Define Crops

    You can add, edit & delete crop presets the cropper UI can use.

    Data Type Definition Example

    Content Example

    The Image Cropper provides a UI to upload an image, set a focal point on the image, and use predefined crops.

    By default, images in the Image Cropper will be shown based on a set focal point and only use specific crops if they are available.

    The Image Cropper comes with 3 modes:

    • Uploading an image

    • Setting a focal point

    • Cropping the image to predefined crops

    Uploading images

    The editor exposes a drop area for files. Select it to upload an image.

    Set focal point

    By default, the Image Cropper allows the editor to set a focal point on the uploaded image.

    All the preset crops are shown to give the editor a preview of what the image will look like on the frontend.

    Crop and resize

    The editor can fit the crop to the image to ensure that the image is presented as intended.

    Powered by ImageSharp.Web

    is image processing middleware for ASP.NET.

    We bundle this package with Umbraco and you can therefore take full advantage of all its features for resizing and format changing. Learn more about the built in processing commands in .

    Sample code

    The Image Cropper comes with an API to generate crop URLs. You can also access the raw data directly as a dynamic object.

    For rendering a cropped media item, the .GetCropUrl is used:

    The third parameter is HtmlEncode and is by default set to true. This means you only need to define the parameter if you want to disable HTML encoding.

    Example to output a "banner" crop from a cropper property with the property alias "customCropper"

    Or, alternatively using the MediaWithCrops extension method:

    Example to dynamically create a crop using the focal point - in this case 300 x 400px image

    CSS background example to output a "banner" crop

    Set the htmlEncode to false so that the URL is not HTML encoded

    Add values programmatically

    To update a content property value you need the .

    The following sample demonstrates how to add or change the value of an Image Cropper property programmatically. The sample creates an API controller with an action, which must be invoked via a POST request to the URL written above the action.

    If you use Models Builder to generate source code (modes SourceCodeAuto or SourceCodeManual), you can use nameof([generated property name]) to access the desired property without using a magic string:

    Get all the crop urls for a specific image

    Crop URLs are not limited to usage within a view. IPublishedContent has a GetCropUrl extension method, which can be used to access crop URLs anywhere.

    The following sample demonstrates how to use GetCropUrl to retrieve URLs for all crops defined on a specific image:

    Sample on how to change the format of the image

    Below the example to output a PNG using ImageSharp.Web command.

    Block List

    Schema Alias: Umbraco.BlockList

    UI Alias: Umb.PropertyEditorUi.BlockList

    Returns: IEnumerable<BlockListItem>

    This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.

    Block List is a list editing property editor, using Element Types to define the list item schema.

    The Block List replaces the obsolete Nested Content editor.

    Configure Block List

    The Block List property editor is configured in the same way as any standard property editor, via the Data Types admin interface.

    To set up your Block List Editor property, create a new Data Type and select Block List from the list of available property editors.

    Then you will see the configuration options for a Block List as shown below.

    The Data Type editor allows you to configure the following properties:

    • Available Blocks - Here you will define the Block Types to be available for use in the property. Read more on how to set up Block Types below.

    • Amount - Sets the minimum and/or maximum number of blocks that should be allowed in the list.

    • Single block mode - When in Single block mode, the output will be BlockListItem<> instead of BlockListModel

    Setup Block Types

    Block Types are Element Types which need to be created before you can start configuring them as Block Types. This can be done either directly from the property editor setup process, or you can set them up beforehand and add them to the block list after.

    Once you have added an element type as a Block Type on your Block List Data Type you will have the option to configure it further.

    Each Block has a set of properties that are optional to configure. They are described below.

    Editor Appearance

    By configuring the properties in the group you can customize the user experience for your content editors when they work with the blocks in the Content section.

    • Label - Define a label for the appearance of the Block in the editor. The label uses to display values of properties. The label is also used for search in the Add Block dialog during content editing. If no label is defined, the block will not be searchable. The search does not fall back to the block’s name.

    • Overlay editor size - Set the size for the Content editor overlay for editing this block.

    Data Models

    It is possible to use two separate Element Types for your Block Types. Its required to have one for Content and optional to add one for Settings.

    • Content model - This presents the Element Type used as model for the content section of this Block. This cannot be changed, but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.

    • Settings model - Add a Settings section to your Block based on a given Element Type. When picked you can open the Element Type or choose to remove the settings section again.

    Catalogue appearance

    These properties refer to how the Block is presented in the Block catalogue, when editors choose which Blocks to use for their content.

    • Background color - Define a background color to be displayed beneath the icon or thumbnail. Eg. #424242.

    • Icon color - Change the color of the Element Type icon. Eg. #242424.

    • Thumbnail - Pick an image or SVG file to replace the icon of this Block in the catalogue.

    The thumbnails for the catalogue are presented in the format of 16:10, and we recommend a resolution of 400px width and 250px height.

    Advanced

    These properties are relevant when you work with custom views.

    • Force hide content editor - If you made a custom view that enables you to edit the content part of a block and you are using default editing mode (not inline) you might want to hide the content-editor from the block editor overlay.

    Editing Blocks

    When viewing a Block List editor in the Content section for the first time, you will be presented with the option to Add content.

    Clicking the Add content button brings up the Block Catalogue.

    The Block Catalogue looks different depending on the amount of available Blocks and their catalogue appearance.

    Click the Block Type you wish to create and a new Block will appear in the list.

    Depending on whether your Block List Editor is setup to use default or inline editing mode you will see one of the following things happening:

    In default mode you will enter the editing overlay of that Block:

    In inline editing mode the new Blocks will expand to show its inline editor:

    More Blocks can be added to the list by clicking the Add content button or using the inline Add content button that appears on hover between or above existing Blocks.

    To reorder the Blocks, click and drag a Block up or down to place in the desired order.

    To delete a Block click the trash-bin icon appearing on hover.

    Rendering Block List Content

    Rendering the stored value of your Block List property can be done in two ways.

    1. Default rendering

    You can choose to use the built-in rendering mechanism for rendering blocks via a Partial View for each block.

    The default rendering method is named GetBlockListHtml() and comes with a few options to go with it. The typical use could be:

    "MyBlocks" above is the alias for the Block List editor.

    If using ModelsBuilder the example can be simplified:

    Example:

    To make this work you will need to create a Partial View for each block, named by the alias of the Element Type that is being used as Content Model.

    These partial views must be placed in this folder: Views/Partials/BlockList/Components/. Example: Views/Partials/BlockList/Components/MyElementTypeAliasOfContent.cshtml.

    A Partial View will receive the model of Umbraco.Core.Models.Blocks.BlockListItem. This gives you the option to access properties of the Content and Settings section of your Block.

    In the following example of a Partial view for a Block Type, the MyElementTypeAliasOfContentand MyElementTypeAliasOfSettings should correspond with the selected Element Type Alias for the given model in your case.

    Example:

    With ModelsBuilder:

    2. Build your own rendering

    A built-in value converter is available to use the data as you like. Call the Value<T> method with a generic type of IEnumerable<BlockListItem> and the stored value will be returned as a list of BlockListItem entities.

    Example:

    Each item is a BlockListItem entity that contains two main properties Content and Settings. Each of these is a IPublishedElement which means you can use all the value converters you are used to using.

    Example:

    Extract Block List Content data

    In some cases, you might want to use the Block List Editor to hold some data and not necessarily render a view since the data should be presented in different areas on a page. An example could be a product page with variants stored in a Block List Editor.

    In this case, you can extract the variant's data using the following, which returns IEnumerable<IPublishedElement>.

    Example:

    If using ModelsBuilder the example can be simplified:

    Example:

    If you know the Block List Editor only uses a single block, you can cast the collection to a specific type T using .OfType<T>() otherwise the return value will be IEnumerable<IPublishedElement>.

    Build a Custom Backoffice View

    Building Custom Views for Block representations in Backoffice is the same for all Block Editors.

    Blocks

    Blocks enable editors to insert structured content elements directly into the Rich Text Editor (RTE). Blocks are Element Types and can be configured with custom properties, styling, and behavior.

    Blocks can be added to the Rich Text Editor when:

    • Available Blocks are specified as part of the Rich Text Editor Data Type configuration.

    • The Insert Block toolbar option is enabled in the Rich Text Editor.

    RTE Insert Block Toolbar Button

    Configure Blocks

    Blocks are Element Types that must be created before configuring them as blocks in the Rich Text Editor. You can create Element Types in the Settings > Document Types section

    Blocks functionality can then be configured through the Rich Text Editor Data Type configuration as follows.

    1. Navigate to Settings > Data Types.

    2. Select your Rich Text Editor Data Type or create a new one.

    3. Locate the Available Blocks section.

    4. Add the Element Types you want to make available as blocks.

    Editor Appearance

    Configure how blocks appear and behave in the Content section:

    • Label - Define how the block appears in the editor. Umbraco 16 uses (UFM) syntax for dynamic labels. Use {=propertyAlias} to display property values (e.g., {=author} for a text property containing the name of an author, or Written by: {=author} for a label with static text and dynamic content).

    • Display Inline - When enabled, blocks remain inline with surrounding text. When disabled, blocks appear on separate lines.

    • Overlay size

    Data Models

    Configure the content structure for your blocks:

    • Content model - The Element Type that defines the main content properties for the block (required).

    • Settings model - Optional Element Type that defines additional settings or configuration options for the block.

    Catalogue Appearance

    Control how blocks appear in the block picker:

    • Background color - Background color displayed behind the block icon or thumbnail.

    • Icon Color - Color of the Element Type icon.

    • Thumbnail - Custom image to replace the default Element Type icon.

    Working with Blocks

    Adding Blocks to Content

    Editors can add blocks to rich text content using the Insert Block toolbar button:

    1. Position the cursor where you want to insert the block

    2. Click the Insert Block button in the Rich Text Editor toolbar

    3. Select the desired Block from the available options

    The block appears in the editor as a structured element.

    Rendering Blocks

    To display blocks on the frontend, create Partial Views for each Block.

    Rich Text Editor blocks use a different view location than Block List blocks. RTE blocks are placed in Views/Partials/RichText/Components/, while Block List blocks use Views/Partials/BlockList/Components/.

    File Structure

    • Location: Views/Partials/RichText/Components/.

    • Naming: Use the exact Element Type alias as the filename (e.g., quoteBlock.cshtml for alias quoteBlock).

    • Model: Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem.

    The different folder structure ensures that RTE blocks and Block List blocks can have separate rendering implementations, even when using the same Element Types.

    The view filename must match the Element Type alias exactly. If you see the error ArgumentException: ~/Views/Partials/richtext/Components/[filename].cshtml does not match any available view, verify that your view filename matches your Element Type alias precisely.

    Example Partial View

    For a Block Type with Element Type alias quoteBlock:

    Example with Settings Model

    For a Call To Action block with Element Type alias callToActionBlock and settings model callToActionBlockSettings:

    Type-Safe Rendering with Models Builder

    When using Models Builder, specify the Content and Settings models for type-safe access:

    Build a Custom Backoffice View

    Building Custom Views for Block representations in Backoffice is the same for all Block Editors. .

    Best Practices

    Content Design

    • Design blocks for reusable content patterns.

    • Keep block content focused on a single purpose.

    • Use descriptive labels that help editors understand the block's function.

    Performance

    • Avoid creating too many Blocks - this can overwhelm content editors.

    • Use appropriate caching strategies for block rendering.

    • Consider the impact of complex blocks on editor performance.

    Accessibility

    • Ensure block markup follows accessibility guidelines.

    • Provide meaningful labels and descriptions.

    • Test block rendering with screen readers.

    Related Articles

    Log Viewer

    Information on using the Umbraco log viewer

    Umbraco ships with a built-in Log Viewer feature. This allows you to filter, view log entries, perform complex search queries, and analyze logs for debugging. You can find the Log viewer in the Settings section of the Umbraco backoffice.

    Benefits

    Ever needed to find all log entries containing the same request ID? Or locate all logs where a property called Duration exceeds 1000ms?

    With structured logging and a query language, you can efficiently search and identify log items for specific scenarios. This helps in debugging and finding patterns in your logs, making it easier to resolve issues.

    Example Queries

    Here are some example queries to help you get started. For more details on the syntax, see the https://github.com/serilog/serilog-filters-expressions project.

    Find all logs that are from the namespace 'Umbraco.Core'StartsWith(SourceContext, 'Umbraco.Core')

    Find all logs that have the property 'Duration' and the duration is greater than 1000msHas(Duration) and Duration > 1000

    Find all logs where the message has localhost in it with SQL like@Message like '%localhost%'

    Saved Searches

    If you frequently use a custom query, you can save it for quick access. Type your query in the search box and click the heart icon to save it with a friendly name. Saved queries are stored in the umbracoLogViewerQuery table in the database.

    Implementing Your Own Log Viewer Source

    Umbraco allows you to implement a custom ILogViewerRepository and ILogViewerService to fetch logs from alternative sources, such as Azure Table Storage.

    Creating a Custom Log Viewer Repository

    To fetch logs from Azure Table Storage, extend the LogViewerRepositoryBase class from Umbraco.Cms.Infrastructure.Services.Implement.

    This implementation requires the Azure.Data.Tables NuGet package.

    Azure Table Storage requires entities to implement the ITableEntity interface. Since Umbraco's default log entity does not implement this, a custom entity (AzureTableLogEntity) must be created to ensure logs are correctly fetched.

    Creating a custom log viewer service

    The next thing to do is create a new implementation of ILogViewerService. Amongst other things, this is responsible for figuring out whether a provided log query is allowed. Again a base class is available.

    Register implementations

    Umbraco needs to be made aware that there is a new implementation of an ILogViewerRepository and an ILogViewerService. These need to replace the default ones that are shipped with Umbraco.

    Configuring Logging to Azure Table Storage

    With the above three classes, the setup is in place to view logs from an Azure Table. However, logs are not yet persisted into the Azure Table Storage account. To enable persistence, configure the Serilog logging pipeline to store logs in Azure Table Storage.

    • Install Serilog.Sinks.AzureTableStorage from NuGet.

    • Add a new sink to appsettings.json with credentials to persist logs to Azure.

    The following sink needs to be added to the array.

    For more in-depth information about logging and how to configure it, see the article.

    Compact Log Viewer - Desktop App

    . A desktop tool is available for viewing and querying JSON log files in the same way as the built-in Log Viewer in Umbraco.

    Migrate content to Umbraco 8

    This guide will show you how to migrate the content from your Umbraco 7 site to a site running Umbraco 8.

    Umbraco 8 contains a lot of breaking changes and a lot of code has been cleaned up compared to Umbraco 7. Due to this, it will not be possible to do a direct upgrade from Umbraco 7 to Umbraco 8. You need to migrate your content from your Umbraco 7 site into your Umbraco 8 site and then recreate the rest in the new version.

    A content migration tool has been implemented in Umbraco 8.1.0, to help you with the transition.

    In this guide you can read more about the tool, its limitations, and how to use it in practice.

    Migrating Umbraco Cloud sites

    Follow the to upgrade your Umbraco 7 site on Cloud.

    Creating Media

    Learn how to work with different types of Media content on your Umbraco website.

    Media in Umbraco CMS is handled the same way as content. You define Media Types that act as a base for media items. The following default Media Types are available:

    • Article - used for uploading and storing documents.

    • Audio - used for uploading and storing digital audio files.

    • File - used for uploading and storing different types of files in the Media section.

    appsettings.json
    "ConnectionStrings": {
        "umbracoDbDSN": "Server=YourLocalSQLServerHere;Database=NameOfYourDatabaseHere;User Id=NameOfYourUserHere;Password=YourPasswordHere;TrustServerCertificate=True"
    }
    YourProjectName.csproj
    <ItemGroup>
      <PackageReference Include="Umbraco.Cms" Version="x.x.x" />
    </ItemGroup>
    builder.WebHost.UseStaticWebAssets();
    {
        "Umbraco": {
            "CMS": {
                "Runtime": {
                    "Mode" : "Development"
                },
                "ModelsBuilder":{
                    "ModelsMode": "SourceCodeAuto"
                }
            }
        }
    }
    <RazorCompileOnBuild>false</RazorCompileOnBuild>
    <RazorCompileOnPublish>false</RazorCompileOnPublish>
    {
      "Umbraco": {
        "CMS": {
          "Runtime": {
            "Mode": "Production"
          },
          "Hosting": {
            "Debug": false
          },
          "Global": {
            "UseHttps": true
          },
          "ModelsBuilder": {
            "ModelsMode": "Nothing"
          },
          "WebRouting": {
            "UmbracoApplicationUrl": "https://<REPLACE_WITH_YOUR_PRIMARY_DOMAIN>/"
          }
        }
      }
    }
    using System.Diagnostics.CodeAnalysis;
    using Microsoft.Extensions.Options;
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Core.Configuration.Models;
    using Umbraco.Cms.Infrastructure.Runtime;
    using Umbraco.Cms.Infrastructure.Runtime.RuntimeModeValidators;
    
    public class RuntimeModeValidatorComposer : IComposer
    {
        public void Compose(IUmbracoBuilder builder)
            => builder.RuntimeModeValidators()
                .Remove<UmbracoApplicationUrlValidator>()
                .Add<DisableElectionForSingleServerValidator>();
    }
    
    public class DisableElectionForSingleServerValidator : IRuntimeModeValidator
    {
        private readonly IOptionsMonitor<GlobalSettings> _globalSettings;
    
        public DisableElectionForSingleServerValidator(IOptionsMonitor<GlobalSettings> globalSettings) => _globalSettings = globalSettings;
    
        public bool Validate(RuntimeMode runtimeMode, [NotNullWhen(false)] out string? validationErrorMessage)
        {
            if (runtimeMode == RuntimeMode.Production && _globalSettings.CurrentValue.DisableElectionForSingleServer == false)
            {
                validationErrorMessage = "Disable primary server election (and support for load balancing) to improve startup performance.";
                return false;
            }
    
            validationErrorMessage = null;
            return true;
        }
    }
    Templates                    Short Name               Language          Tags
    ------------------------------------------------------------------------------------------------------
    Umbraco Project              umbraco                  [C#]              Web/CMS/Umbraco
    Umbraco Extension            umbraco-extension        [C#]              Web/CMS/Umbraco/Extension/Plugin/Razor Class Library
    Umbraco Docker Compose       umbraco-compose                            Web/CMS/Umbraco
    Umbraco Project (C#)
    Author: Umbraco HQ
    Description: An empty Umbraco project ready to get started.
    
    Usage:
      dotnet new umbraco [options] [template options]
    
    Options:
      -n, --name <name>       The name for the output being created. If no name is specified, the name of the output directory is used.
      -o, --output <output>   Location to place the generated output.
      --dry-run               Displays a summary of what would happen if the given command line were run if it would result in a template
                              creation.
      --force                 Forces content to be generated even if it would change existing files.
      --no-update-check       Disables checking for the template package updates when instantiating a template.
      --project <project>     The project that should be used for context evaluation.
      -lang, --language <C#>  Specifies the template language to instantiate.
      --type <project>        Specifies the template type to instantiate.
    
    Template options:
      -r, --release <Latest|LTS>                 The Umbraco release to use, either latest or latest long term supported
                                                 Type: choice
                                                   Latest  The latest umbraco release
                                                   LTS     The most recent long term supported version
                                                 Default: Latest
      --use-https-redirect                       Adds code to Startup.cs to redirect HTTP to HTTPS and enables the UseHttps setting.
                                                 Type: bool
                                                 Default: false
      -da, --use-delivery-api                    Enables the Delivery API
                                                 Type: bool
                                                 Default: false
      --add-docker                               Adds a docker file to the project.
                                                 Type: bool
                                                 Default: false
      --no-restore                               If specified, skips the automatic restore of the project on create.
                                                 Type: bool
                                                 Default: false
      --exclude-gitignore                        Whether to exclude .gitignore from the generated template.
                                                 Type: bool
                                                 Default: false
      --minimal-gitignore                        Whether to only include minimal (Umbraco specific) rules in the .gitignore.
                                                 Type: bool
                                                 Default: false
      --connection-string <connection-string>    Database connection string used by Umbraco.
                                                 Type: string
      --connection-string-provider-name          Database connection string provider name used by Umbraco.
      <connection-string-provider-name>          Type: string
                                                 Default: Microsoft.Data.SqlClient
      --development-database-type <choice>       Database type used by Umbraco for development.
                                                 Type: choice
                                                   None     Do not configure a database for development.
                                                   SQLite   Use embedded SQLite database.
                                                   LocalDB  Use embedded LocalDB database (requires SQL Server Express with Advanced
                                                 Services).
                                                 Default: None
      --friendly-name <friendly-name>            Used to specify the name of the default admin user when using unattended install on
                                                 development (stored as plain text).
                                                 Type: string
      --email <email>                            Used to specify the email of the default admin user when using unattended install on
                                                 development (stored as plain text).
                                                 Type: string
      --password <password>                      Used to specify the password of the default admin user when using unattended install on
                                                 development (stored as plain text).
                                                 Type: string
      --telemetry-level <telemetry-level>        Used to specify the level of telemetry the installation will report (Minimal, Basic or Detailed).
                                                 Type: string
      --no-nodes-view-path <no-nodes-view-path>  Path to a custom view presented with the Umbraco installation contains no published
                                                 content.
                                                 Type: string
      -dm, --development-mode <choice>           Choose the development mode to use for the project.
                                                 Type: choice
                                                   BackofficeDevelopment  Enables backoffice development, allowing you to develop from
                                                 within the backoffice, this is the default behaviour.
                                                   IDEDevelopment         Configures appsettings.Development.json to Development runtime
                                                 mode and SourceCodeAuto models builder mode, and configures appsettings.json to
                                                 Production runtime mode, Nothing models builder mode, and enables UseHttps
                                                 Default: BackofficeDevelopment
      -mm, --models-mode <choice>                Choose the models builder mode to use for the project. When development mode is set to
                                                 IDEDevelopment this only changes the models builder mode appsetttings.development.json
                                                 Type: choice
                                                   Default           Let DevelopmentMode determine the models builder mode.
                                                   InMemoryAuto      Generate models in memory, automatically updating when a content
                                                 type change, this means no need for app rebuild, however models are only available in
                                                 views.
                                                   SourceCodeManual  Generate models as source code, only updating when requested
                                                 manually, this means a interaction and rebuild is required when content type(s) change,
                                                 however models are available in code.
                                                   SourceCodeAuto    Generate models as source code, automatically updating when a
                                                 content type change, this means a rebuild is required when content type(s) change,
                                                 however models are available in code.
                                                   Nothing           No models are generated, this is recommended for production assuming
                                                 generated models are used for development.
                                                 Default: Default
      -sk, --starter-kit <choice>                Choose a starter kit to install.
                                                 Type: choice
                                                   None                   No starter kit.
                                                   Umbraco.TheStarterKit  The Umbraco starter kit.
                                                 Default: None
    Could not load type umbraco.BusinessLogic.Utils.TypeFinder from assembly businesslogic, Version=1.0.5031.21336, Culture=neutral, PublicKeyToken=null.
    net stop was /y
    net start w3svc
    dotnet publish -o ../deployment-artefacts -f net9.0
    <PropertyGroup>
      <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
    </PropertyGroup>
    <modules runAllManagedModulesForAllRequests="false">
        <remove name="WebDAVModule" />
    </modules>

    11

    7.0

    10

    6.0.5

    Expand Node
    Remove the EnableCanvasEditing element
  • Remove the webservices element

  • You need to merge the changes from the new tinyMceConfig file into yours. The command elements that have changed are: JustifyCenter, JustifyLeft, JustifyRight, JustifyFull, umbracomacro, umbracoembed, mceImage, subscript, superscript, styleselect

  • Remove the command: mceSpellCheck

  • full settings
    https://issues.umbraco.org/issue/U4-58
    https://issues.umbraco.org/issue/U4-2742
    ImageSharp.Web
    the official ImageSharp documentation
    Content Service
    format
    Image Cropper Data Type Definition
    Image Cropper Upload
    Image Cropper Focal Point
    Image Cropper crop

    Live editing mode - Enabling this will make editing of a block happening directly to the document model, making changes appear as you type.

  • Inline editing mode - Enabling this will change editing experience to inline, meaning that editing the data of blocks happens at sight as accordions.

  • Property editor width - Overwrite the width of the property editor. This field takes any valid css value for "max-width".

  • Umbraco Flavoured Markdown
    Read about building a Custom View for Blocks here
    Block List - Data Type Definition
    Block List - Data Type Block Configuration
    Block List - Add Content
    Block List - Setup
    Block List - example setup from Umbraco.com
    Block List - Overlay editing
    Block List - Inline editing
    Block List - Add Content
    <plugins>
        <plugin loadOnFrontend="true">code</plugin>
        <plugin loadOnFrontend="true">paste</plugin>
        <plugin loadOnFrontend="true">umbracolink</plugin>
        <plugin loadOnFrontend="true">anchor</plugin>
        <plugin loadOnFrontend="true">charmap</plugin>
        <plugin loadOnFrontend="true">table</plugin>
        <plugin loadOnFrontend="true">lists</plugin>
    </plugins>
    <img src="@Url.GetCropUrl(Model.Photo,"square", true)" />
    <img src="@Url.GetCropUrl(Model.SecondaryPhoto, "customCropper", "banner")" />
    <img src="@Model.SecondaryPhoto.GetCropUrl("customCropper", "banner")" />
    @if (Model.Photo is not null)
    {
        <img src="@Url.GetCropUrl(Model.Photo, height: 300, width: 400)" alt="@Model.Photo.Name" />
    }
    @if (Model.Photo is not null)
    {
        var cropUrl = Url.GetCropUrl(Model.Photo, "square", false);
        <style>
            .myCssClass {
                background-image: url("@cropUrl");
                height: 400px;
                width: 400px;
            }
        </style>
        <div class="product-image-container myCssClass"></div>
    }
    using Microsoft.AspNetCore.Mvc;
    using Umbraco.Cms.Core.Models;
    using Umbraco.Cms.Core.PropertyEditors;
    using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
    using Umbraco.Cms.Core.Serialization;
    using Umbraco.Cms.Core.Services;
    
    namespace Umbraco.Docs.Samples.Web.Property_Editors_Add_Values;
    
    [ApiController]
    [Route("/umbraco/api/createimagecroppervalues")]
    public class CreateImageCropperValuesController : Controller
    {
        private readonly IContentService _contentService;
        private readonly IMediaService _mediaService;
        private readonly MediaUrlGeneratorCollection _mediaUrlGeneratorCollection;
        private readonly IJsonSerializer serializer;
    
        public CreateImageCropperValuesController(
            IContentService contentService,
            IMediaService mediaService,
            MediaUrlGeneratorCollection mediaUrlGeneratorCollection, IJsonSerializer serializer)
        {
            _contentService = contentService;
            _mediaService = mediaService;
            _mediaUrlGeneratorCollection = mediaUrlGeneratorCollection;
            this.serializer = serializer;
        }
    
        // /Umbraco/Api/CreateImageCropperValues/CreateImageCropperValues
        [HttpPost("createimagecroppervalues")]
        public ActionResult<bool> CreateImageCropperValues()
        {
            // Create a variable for the GUID of the page you want to update
            var contentKey = Guid.Parse("89974f8b-e213-4c32-9f7a-40522d87aa2f");
    
            // Get the page using the GUID you've defined
            IContent? content = _contentService.GetById(contentKey);
            if (content == null)
            {
                return false;
            }
    
            // Create a variable for the GUID of the media item you want to use
            var mediaKey = Guid.Parse("b6d4e98a-07c0-45f9-bfcc-52994f2806b6");
    
            // Get the desired media file
            IMedia? media = _mediaService.GetById(mediaKey);
            if (media == null)
            {
                return false;
            }
    
            // Create a variable for the image cropper and set the source
            var imageCropperValue = new ImageCropperValue
            {
                Src = media.GetUrl("umbracoFile", _mediaUrlGeneratorCollection)
            };
    
            // Serialize the image cropper value
            var propertyValue = serializer.Serialize(imageCropperValue);
    
            // Set the value of the property with alias "cropper"
            // - remember to add the "culture" parameter if "cropper" is set to vary by culture
            content.SetValue("cropper", propertyValue);
    
            return _contentService.Save(content).Success;
        }
    }
    // Set the value of the "Cropper" property on content of type MyContentType
    // - remember to add the "culture" parameter if "cropper" is set to vary by culture
    content.SetValue(nameof(MyContentType.Cropper).ToFirstLowerInvariant(), propertyValue);
    public Dictionary<string, string> GetCropUrls(IPublishedContent image)
    {
        // Get the Image Cropper property value for property with alias "umbracoFile"
        ImageCropperValue? imageCropperValue = image.Value<ImageCropperValue>("umbracoFile");
        if (imageCropperValue?.Crops == null)
        {
            return new Dictionary<string, string>();
        }
    
        // Return all crop aliases and their corresponding crop URLs as a dictionary
        var cropUrls = new Dictionary<string, string>();
        foreach (ImageCropperValue.ImageCropperCrop crop in imageCropperValue.Crops)
        {
            // Get the cropped URL and add it to the dictionary that I will return
            var cropUrl = crop.Alias != null
                ? image.GetCropUrl(crop.Alias)
                : null;
            if (cropUrl != null)
            {
                cropUrls.Add(crop.Alias!, cropUrl);
            }
        }
    
        return cropUrls;
    }
    <img src="@Url.GetCropUrl(Model.Photo, 500, 300, furtherOptions: "&format=png")" />
    @Html.GetBlockListHtml(Model, "MyBlocks")
    @Html.GetBlockListHtml(Model.MyBlocks)
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockListItem>;
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    @{
        var content = (ContentModels.MyElementTypeAliasOfContent)Model.Content;
        var settings = Model.Settings as ContentModels.MyElementTypeAliasOfContent; // Cast Model.Settings safely using 'as' to avoid null reference exceptions
    }
    
    @* Output the value of field with alias 'heading' from the Element Type selected as Content section *@
    <h1>@content.Value("heading")</h1>
    @* Output the value of field with alias 'heading' from the Element Type selected as Content section *@
    <h1>@content.Heading</h1>
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
    @using Umbraco.Cms.Core.Models.Blocks;
    @{
        var blocks = Model.Value<IEnumerable<BlockListItem>>("myBlocksProperty");
        foreach (var block in blocks)
        {
            var content = block.Content;
    
            @Html.Partial("MyFolderOfBlocks/" + content.ContentType.Alias, block)
        }
    }
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    @using Umbraco.Cms.Core.Models.Blocks;
    @{
        var blocks = Model.Value<IEnumerable<BlockListItem>>("myBlocksProperty");
        foreach (var block in blocks)
        {
            var content = (ContentModels.MyAliasOfContentElementType)block.Content;
            var settings = (ContentModels.MyAliasOfSettingsElementType)block.Settings;
    
            <h1>@content.MyExampleHeadlinePropertyAlias</h1>
        }
    }
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage;
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    @using Umbraco.Cms.Core.Models.Blocks;
    @{
        var variants = Model.Value<IEnumerable<BlockListItem>>("variants").Select(x => x.Content);
        foreach (var variant in variants)
        {
            <h4>@variant.Value("variantName")</h4>
            <p>@variant.Value("description")</p>
        }
    }
    @inherits Umbraco.Web.Mvc.UmbracoViewPage
    @using ContentModels = Umbraco.Web.PublishedModels;
    @{
        var variants = Model.Variants.Select(x => x.Content).OfType<ProductVariant>();
        foreach (var variant in variants)
        {
            <h4>@variant.VariantName</h4>
            <p>@variant.Description</h4>
        }
    }

    Configure each Block Type with the options described below.

    - Set the size of the editing overlay when editors work with the block content.
    Configure the block content (and settings, if provided)
    Adding Blocks to Content - Step 3
    Umbraco Flavoured Markdown
    Read about building a Custom View for Blocks here
    Element Types
    Rich Text Editor Configuration
    Rich Text Editor Extensions
    RTE Blocks Data Type Configuration
    RTE Blocks Editor Appearance Settings
    RTE Blocks Data Models Settings
    Adding Blocks to Content - Step 1
    Adding Blocks to Content - Step 2
    What are the limitations?

    In the following section, you can learn more about the limitations of migrating content from Umbraco 7 to Umbraco 8.

    Versions supported

    The content migration tool is a database migration, which is made for the database schema of Umbraco 7.14+. This means that in order to do the migration you need to ensure your Umbraco 7 site is running at least Umbraco 7.14.

    Database types supported

    Umbraco 8 does not support MySQL databases. This means that the migration will not work when moving from an Umbraco 7 site using MySQL to Umbraco 8 on SQL Server

    The database types that are supported are SQL Server and SQL CE.

    Known issues

    Feedback from user testing has shown that some databases are harder to migrate than others.

    We are collecting a list of these known issues on our GitHub Issue Tracker. There is a community package: Pre-migration health checks that you can install on your Umbraco 7 site before migration. This will help identify and resolve some of these common issues before triggering the migration steps detailed below.

    A migration was introduced in Umbraco 8.6 which can break the migration process. See Issue #7914 for more details.

    There are two ways to work around this issue:

    • Migrate to version 8.5 as a first step and then post-migration, carry out a normal Umbraco upgrade to the latest version of Umbraco 8, or

    • Install the following community Nuget Package: ProWorks Umbraco 8 Migrations into your Umbraco 8 project before running the migration (no configuration required). This package was created by Umbraco Gold Partner and patches the migration process so you can migrate directly from the latest Umbraco 7 to Umbraco 8.6+ without encountering the above issue. .

    Third party property editors

    The migration will transform the data stored in third party editors as well. However, it will be stored as it was in Umbraco 7. If the structure has changed or the property editor doesn't exist, you will still be able to find the data in the database. It will, however, not be available in the backoffice.

    Learn more about that in the Data Types Migrations

    Migrating data types

    When migrating content from Umbraco 7 to Umbraco 8, the Data Type 'pre-value' structure has changed. In Umbraco 8, the term 'pre-values' no longer exists and is instead referred to as property editor configuration.

    In Umbraco 8, property editor configuration is a strongly typed object. There are plenty of examples in the Umbraco-CMS codebase.

    This configuration is stored differently in Umbraco 8 than it was in Umbraco 7. In Umbraco 7, each pre-value property was stored as a different row in a different database table. In Umbraco 8 this is simplified and property editor configuration is stored as the JSON serialized version of the strongly typed configuration object.

    When upgrading from Umbraco 7 to Umbraco 8, Umbraco has no way of knowing how custom property editors have intended to structure their configuration data. During the upgrade, Umbraco will convert the key/value pairs from the old pre-value database table into a serialized JSON version of those values. There is a reasonable chance that the end result of this data conversion is not compatible with the custom property editor.

    There are 3 options that a developer can choose to do to work around this automatic data conversion:

    1: Implement a custom IPreValueMigrator

    This option requires you to create a custom C# migrator for each of your custom property editors that store custom configuration data. It will also require that you implement these migrators before you run the Umbraco 8 content migration.

    To do this, you will create an implementation of IPreValueMigrator or inherit from the base class .

    There are plenty of examples of this in the .

    You will then need to register them in a composer:

    When running the migrations and encountering a custom configuration, Umbraco will utilize the PreValueMigrator when converting the old pre-values into the new JSON format.

    2: Update your Angular configuration (pre-value) and property editor

    This option means that you will choose to use the automatically converted JSON data format. In this case, it will mean updating your pre-value and property editors to use the new JSON configuration data. The converted data won't be much different than the original/intended data format so this might not be too much work.

    3: Update the Angular configuration (pre-value) editor

    With this option the configuration/pre-value editor needs to be updated to transform the JSON converted data into the data structure you want. When this is done and when the Data Type is saved again, the JSON data structure will be saved back to the database. Your property editor will then continue to work.

    This will require you to update and save all custom pre-value editors to transform the converted structures back to your intended data structure.

    What will happen

    When the migrations are running, Umbraco will go through your entire Umbraco 7 database and update it to the format required for Umbraco 8. The schema will be remodeled and transformed into the correct format and your existing compatible data will be transformed to fit with Umbraco 8.

    These migrations will be running directly on your database. They are transforming schema and data - not transferring. Therefore always ensure that you have a backup before attempting to do this. In case something goes wrong, you will be able to rollback and try again.

    It is highly recommended to clean up your site before running this as it will be quicker.

    • Empty Content recycle bin

    • Empty Media recycle bin

    • Clean up the database version history (can be done with a script or a package like Unversion)

    How it works

    In the following guide we will migrate the content of an Umbraco 7.13.1 site to Umbraco 8.1.0.

    Step 1: Upgrading to 7.14+

    Before the content migration can start the site has to run Umbraco 7.14+. Make sure to always take a backup of the database before doing an upgrade, and then check the version specific upgrade instructions.

    The site in this example is an Umbraco 7.13.1 site, and we will use Nuget to update it.

    v7 site with content

    Following the general upgrade instructions we will now upgrade via Nuget until we get to this point:

    Upgrading to v7.14

    When upgrading an old website, check if you are using obsolete properties in your Data Types. These should be changed to their updated counterparts. The migration will fail if you are still using obsolete properties.

    The updated properties are:

    • Content Picker

    • Media Picker

    • Member Picker

    • Multinode Treepicker

    • Nested Content

    • Folder Browser

    • Related Links

    You can see if your site is using the obsolete properties from the (Obsolete) prefix in their name.

    Install the Pre-migration health checks plugin, and run it health check from the Developer section of the backoffice. This is done to identify and resolve some common database schema issues before migration.

    Once it is upgraded and you have verified everything is working, move on to the next step.

    Step 2: Migrating content to Umbraco 8

    The first thing to do is to spin up a fresh new Umbraco 8.1+ site. Make sure everything works and that no content is there.

    Fresh 8.1 site

    If you have customized the UsersMembershipProvider on your Umbraco 7 site you need to copy that over to the 8.1 web.config as well. Additionally you need to update the type attribute to be type="Umbraco.Web.Security.Providers.UsersMembershipProvider, Umbraco.Web".

    This also includes the attribute useLegacyEncoding value. Make sure that this setting is copied into your new Umbraco 8 site, as it is needed in order to log in.

    Take a backup of your database from the Umbraco 7.14 site. Take the information for the backup database and add that to the connectionstring for the Umbraco 8.1 site. If you are running SQL CE, you will have to copy the database over to the new site as well.

    Once the connectionstring is set, the final step is to change the Umbraco version number in the web.config on the Umbraco 8.1 site. Chang it to 7.14.0. This will indicate that there is an upgrade pending and it needs to run the migration.

    Set Umbraco version in the web.config

    The version will be set to 8.1.0, and you need to change it to the version you are currently migrating from.

    When you start the site it will ask you to login and then show you this screen:

    Upgrade database to 8.1

    From here, the automatic migration will take over, and after a little bit you can log in and see your content:

    Content is on 8.1

    Please be aware that this is a content migration. If you go to the frontend after following these steps, it will throw errors.

    At this point you will have the content but nothing else.

    Step 3: Files migration

    Before moving on to this step, make sure that the Umbraco 8 project is no longer running.

    The following files/folders need to be copied into the Umbraco 8 project:

    • ~/Views - do not overwrite the default Macro and Partial View Macro files, unless changes have been made to these.

    • ~/Media

    • Any files/folders related to Stylesheets and JavaScripts.

    • Any custom files/folders the Umbraco 7 project uses, that aren't in the ~/Config or ~/bin.

    • ~/App_Data/UmbracoForms - in the case Umbraco Forms was used on the Umbraco 7 site.

    Merge the configuration files carefully to ensure any custom settings are migrated while none of the default configurations for Umbraco 8 is overwritten.

    You'll have to revisit all templates and custom implementations to get the site up and running, as all markup is still Umbraco 7-specific.

    Are you planning on continuing the migration to the latest version on Umbraco CMS?

    Then you can skip the step to revisit the template files and custom implementation. We highly recommend waiting with this step until you've reached the latest version.

    If you're stopping at Umbraco 8, you can learn more about rendering content on the Legacy Docs site.

    Step 4: Post-migration checks

    As you are updating your template files and custom implementation, you should also verify your configuration files and settings.

    Umbraco 8 contains a few changes regarding the Sections in the Umbraco Backoffice. Because of this, you should also check your User Groups and make sure they have access to the appropriate sections.

    Learn more about the Section in the Sections article

    steps outlined in the Umbraco Cloud documentation

    Folder - a container for organizing media items in the Media section tree.

  • Image - used for uploading and storing images.

  • Vector Graphics (SVG) - used for uploading and storing Scalable Vector Graphics (SVG) files which are text files containing source code to draw the desired image.

  • Video - used for uploading and storing video files.

  • The default Media Types aim to cover most needs for media on a website. You do not need to define your Media Types to start using the Media section. The tools for organizing and uploading the media are already in place.

    If you have upgraded from an older version than 8.14 the Media Types listed above are not added automatically. You can add those types manually yourselves by following the steps below 'Creating a new Media Type'. On the default media types page, you will find a detailed overview of all Media Types.

    Uploading Media

    You can upload media in two different ways:

    • Through the Media section and

    • Through the Content section

    Add media through the Media section

    From the Media section in the Umbraco backoffice, you can add new media items by following either of the approaches defined below:

    • Use the Create dialog to create a new Media item in the Media section

      • The Media item will be created based on the type you choose.

      • Upload the image or file, give the Media item a name, and click Save.

      Upload Media - Create Button
    • Use the Drag and drop feature to add your files to the Media section.

      • Umbraco will automatically detect the Media Type and create the Media item.

      • You can drop entire folder structures to recreate that same structure in the Media section.

    Add media through the Content section

    New media items can be added to your site without interrupting the content creation flow. This can be done following either of the two approaches outlined below.

    • Drag and drop the image(s) from your file explorer directly into the Media Picker property on the Content page.

      • Images added this way is automatically added to the user's start node in the Media section of the Umbraco backoffice.

    Drag and drop images directly into the content
    • Select the "+" icon to open the "Select media" dialog where you can add images from your file explorer directly or using drag and drop.

    Add images from the "Select media" dialog

    Creating a folder

    It is always a good idea to start by creating a folder for your media items. It can be a good idea to align these folders with the content on your website. This will give the editors a better overview of the files and enable them to upload media items in the correct place.

    Follow these steps to create a folder in the Media section:

    1. Go to the Media section.

    2. Select ... next to Media.

    3. Select Create.

    4. Select Folder.

    5. Enter a name for the folder and select Save in the bottom-right corner.

    Media Type properties

    The Image Media Type has 5 properties: Upload Image, Width, Height, Size, and Type. These are populated once the image is uploaded. The properties can be viewed in the Media section and accessed in your Templates.

    Except for the Folder Media Type, the other Media Types have 3 properties: Upload Image, Type, and Size.

    Learn more about each Media Type in the article about default Media Types.

    Organizing and editing media items

    The default view for the Media section is a card view that lets you preview the different files that have been uploaded.

    Media Section - Cardview

    By selecting multiple media items it is possible to perform bulk operations like moving or deleting the items.

    To edit properties on a single media item, click the name of the item, which you will see once you hover over the item.

    Edit media item

    From the top-right corner of the Media section, you can toggle between the list and grid view. There is also an option to search for the items in the Media section.

    Using media items in the Content section

    By adding a Media Picker property to a Document Type the editor will have the ability to select media items when creating content.

    Creating a Media Type

    You can create custom Media Types and control the structure of the Media tree as you would with Document Types. This means you can store information that is specific to the media on the item itself.

    Video tutorial

    A Media Type is created in the Settings section using the Media Type editor.

    1. Go to the Settings section.

    2. Click ... next to Media Types.

    3. Click Create > New Media Type.

    4. Name the new Media Type Employee Image.

    5. Choose an icon by selecting the icon left of the name field.

    You will now see the Media Type editor. It is similar to the editor used for creating Document Types.

    Creating a Media Type

    Having different folders for different Media Types makes it possible to restrict where media items can be created and added. Only allowing PDF uploads in a certain folder and employee images in another make it easier to keep the Media section organized.

    Adding groups

    Before we start adding properties to the Media Type we need to add a group to put these in.

    1. Click on Add group.

    2. Call the group Image.

    Adding properties

    We need to add the same properties as on the default Image Media Type. These are:

    • umbracoFile

    • umbracoWidth

    • umbracoHeight

    • umbracoBytes

    • umbracoExtension

    Follow the steps outlined below to add the properties to the Media Type:

    1. Click Add property.

    2. Name it Upload image.

    3. Change the alias to umbracoFile.

    4. Click Select property editor.

    5. Select Image cropper.

    6. Rename the editor Employee Image Cropper.

    7. Add two new crops called Thumbnail (200px x 350px) and wideThumbnail (350px x 200px).

    8. Click Save. 9. Click Add. 10. Name the remaining four properties Width, Height, Size, and Type, and give them the aliases as mentioned above. They should all use the Label editor.

    As mentioned before these properties will automatically be populated once an image has been uploaded.

    Adding properties

    Defining a Media Type folder

    Next up, we will create a folder to hold the employee images. We could use the existing Folder Media Type but that would mean editors can upload employee images to any folder of that type. If we create a folder specifically for employee images there is only one place to put them.

    1. Go back to the Settings section and create a new Media Type.

    2. Name it Employee Images.

    3. Select the folder icon by clicking the icon to the left of the name.

    4. Navigate to the Structure tab.

    5. Click Configure as a Collection under Presentation.

    6. Choose List view - Media.

    7. Click Save.

    The new folder is created under the Media Types folder. We also need to only allow the Employee Image Media Type in our new folder. Both of these configurations can be set on the Structure tab.

    1. Go to the Structure tab of the Employee Images folder.

    2. Toggle the Allow at root.

    3. Click Choose in the Allowed Child Node Types.

    4. Select Employee Image.

    5. Click Choose.

    Permissions

    Creating the folder and media items

    1. Go to the Media section.

    2. Select ... next to Media.

    3. Click Create > Employee Images folder.

    4. Name it Employee Images.

    5. Click Save.

    Uncheck the Allow at root option on the Employee Images Media Type to prevent the creation of multiple folders of this type. This will only disable the creation of new ones and not affect existing folders.

    Cropping the images

    If you select an image that has been uploaded to the folder you will see the full image and the two defined crops.

    Moving the focal point circle on the image will update the crops to focus accordingly. You can also edit the individual crops by selecting them and moving the image or adjusting the slider to zoom.

    Cropping images

    More information

    • Rendering Media

    • Customizing Data Types

    Related Services

    • MediaService

    Serilog:WriteTo
    Logging
    Compact Log Viewer

    Content Picker

    Schema Alias: Umbraco.ContentPicker

    UI Alias: Umb.PropertyEditorUi.DocumentPicker

    Returns: IEnumerable<IPublishedContent>

    The Content Picker enables choosing the type of content tree to display and which specific part to render. It also allows you to set a dynamic root node for the content based on the current document using the Content Picker.

    The Content Picker was formerly known as the Multinode Treepicker in version 13 and below.

    The renaming is purely a client-side UI change, meaning the property editor still uses the Umbraco.MultiNodeTreePicker schema alias.

    The change was made as the word Content in the backoffice acts as an umbrella term covering Documents, Media, and Members.

    Are you looking for the original Content Picker?

    The Content Picker from version 13 and below has been renamed .

    Data Type Definition Example

    Minimum/maximum number of items

    Define a limit on the number of items allowed to be selected.

    Ignore user start nodes

    Checking this field allows users to choose nodes they normally cannot access.

    Node Type

    This option allows for configuring what type of content is available when using the Data Type. The available types of content are Content, Members, or Media items.

    When selecting Content from the dropdown, the option to specify a root node, also called the origin, becomes available.

    When picking the origin there are several different options available:

    The following options are available when picking the origin:

    • Root: The root is the first level item of the sub-tree of the current node.

    • Parent: The parent is the nearest ancestor of the current node.

    • Current: The current node.

      • A picker that uses the current node, cannot pick anything when the current node is created, as it will not have any children.

    When an origin has been specified, it becomes possible to continue to build a Dynamic Root by adding additional query steps.

    Navigate the content tree relative to the specified origin to execute multiple query steps and find the root node needed.

    The following options are available:

    • Nearest Ancestor or Self: Find the nearest ancestor or current item that fits with one of the configured Document Types.

    • Furthest Ancestor or Self: Find the furthest ancestor or current item that fits with one of the configured Document Types.

    • Nearest Descendant or Self: Find the nearest descendant or current item that fits with one of the configured Document Types.

    • Furthest Descendant or Self:

    The options above are all based on navigating the document hierarchy by locating ancestors and descendants. It is possible to execute custom steps to build even more complex queries. Once a custom query is available it will be added to the bottom of the Append steps to query dialog. Learn more about .

    Each query step takes the output from the origin or the previous step as input. It is only ever the result of the last query step that is passed to the next step.

    Adding a custom query step

    Custom query steps can be used to solve specific use cases, such as traversing sibling documents or matching property values. Before the custom query steps can be selected in the Data Type settings, they must be defined via code.

    When implementing a query step it requires a collection of origins and information about the query step. The collection is taken from where the name specified in the UI can be found.

    Specifying the origin is required for the custom query step to become available.

    Read the above to learn more about this.

    You can inject dependencies into the constructor. These dependencies could be custom repositories or the IVariationContextAccessor, if you want to use the current culture.

    The ExecuteAsync method receives a set of content keys from the last executed query step or the origin. It has to return a new set of content keys.

    To register the custom query step, append it to the existing query steps, DynamicRootSteps(). This is done from a composer as shown below.

    Finally, register the custom query step on the client side and provide a brief description.

    You can do this in an umbraco-package.json file, as shown below:

    Allow items of type

    Choose which types of content should be available to pick using the Content Picker.

    This is done by selecting one or more Document Types.

    Query Example

    Consider the following tree structure where the Document Type alias is presented in square brackets.

    • Codegarden

      • 2023 [year]

        • Talks [talks]

    Consider configuring a Content Picker on the talk Document Type to select a stage for the talk. Here, you want to display only the stages for the actual year. To do this, you need to set the parent as the origin.

    For instance, if you are on the Umbraco anno MMXXIII node, the collection of content keys passed into the first query step will only contain the Talks content node.

    • First, query for the nearest ancestors of the type year. This will return 2023.

    • Second, query for the nearest descendants of the type stages.

    When opening the picker on the Umbraco anno MMXXIII node, it will now show the children of the node on the path Codegarden > 2023 > Stages.

    MVC View Example

    Without Models Builder

    With Models Builder

    Add values programmatically

    See the example below to see how a value can be added or changed programmatically. To update the value of a property editor you need the .

    The example below demonstrates how to add values programmatically using a Razor view. However, this is used for illustrative purposes only and is not the recommended method for production environments.

    Although the use of a GUID is preferable, you can also use the numeric ID to get the page:

    If Models Builder is enabled you can get the alias of the desired property without using a magic string:

    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem>
    
    @{
        var quoteText = Model.Content.Value("quoteText")?.ToString();
        var citation = Model.Content.Value("citation")?.ToString();
    }
    
    <blockquote class="quote-block">
        @if (!string.IsNullOrEmpty(quoteText))
        {
            <p class="quote-text">@Html.Raw(quoteText)</p>
        }
    
        @if (!string.IsNullOrEmpty(citation))
        {
            <cite class="quote-citation">@citation</cite>
        }
    </blockquote>
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem>
    @using Umbraco.Cms.Core.Models
    
    @{
        // Get link from Multi URL Picker
        var linkPicker = Model.Content.Value<IEnumerable<Link>>("link");
        var link = linkPicker?.FirstOrDefault();
    
        // Get style from settings (if settings model exists)
        var style = "primary"; // Default style
        if (Model.Settings != null)
        {
            var settingsStyle = Model.Settings.Value("style")?.ToString();
            if (!string.IsNullOrEmpty(settingsStyle))
            {
                style = settingsStyle.ToLower();
            }
        }
    
        // CSS class based on style setting
        var cssClass = $"cta-button cta-button--{style}";
    }
    
    @if (link != null && !string.IsNullOrEmpty(link.Url))
    {
        <div class="cta-block">
            <a href="@link.Url"
               class="@cssClass"
               @(link.Target == "_blank" ? Html.Raw("target=\"_blank\" rel=\"noopener noreferrer\"") : Html.Raw(""))>
                @(!string.IsNullOrEmpty(link.Name) ? link.Name : "Learn More")
            </a>
        </div>
    }
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.RichTextBlockItem<QuoteBlock, QuoteBlockSettings>>
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    
    @{
        var style = "";
        if (Model.Settings?.Color != null)
        {
            style = $"style=\"border-left-color: {Model.Settings.Color};\"";
        }
    }
    
    <blockquote class="quote-block" @Html.Raw(style)>
        @if (!string.IsNullOrEmpty(Model.Content.QuoteText))
        {
            <p class="quote-text">@Html.Raw(Model.Content.QuoteText)</p>
        }
    
        @if (!string.IsNullOrEmpty(Model.Content.Citation))
        {
            <cite class="quote-citation">@Model.Content.Citation</cite>
        }
    </blockquote>
    using Azure;
    using Azure.Data.Tables;
    using Serilog.Events;
    using Serilog.Formatting.Compact.Reader;
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Core.Logging.Viewer;
    using Umbraco.Cms.Core.Serialization;
    using Umbraco.Cms.Core.Services;
    using Umbraco.Cms.Infrastructure.Logging.Serilog;
    using Umbraco.Cms.Infrastructure.Services.Implement;
    
    namespace My.Website;
    
    public class AzureTableLogsRepository : LogViewerRepositoryBase
    {
        private readonly IJsonSerializer _jsonSerializer;
    
        public AzureTableLogsRepository(UmbracoFileConfiguration umbracoFileConfig, IJsonSerializer jsonSerializer) : base(
            umbracoFileConfig)
        {
            _jsonSerializer = jsonSerializer;
        }
    
        protected override IEnumerable<ILogEntry> GetLogs(LogTimePeriod logTimePeriod, ILogFilter logFilter)
        {
            // This example uses a connection string compatible with the Azurite emulator
            // https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite
            var client =
                new TableClient(
                    "UseDevelopmentStorage=true",
                    "LogEventEntity");
    
            // Filter by timestamp to avoid retrieving all logs from the table, preventing memory and performance issues
            IEnumerable<AzureTableLogEntity> results = client.Query<AzureTableLogEntity>(
                entity => entity.Timestamp >= logTimePeriod.StartTime.Date &&
                          entity.Timestamp <= logTimePeriod.EndTime.Date.AddDays(1).AddSeconds(-1));
    
            // Read the data and apply logfilters
            IEnumerable<LogEvent> filteredData = results.Select(x => LogEventReader.ReadFromString(x.Data))
                .Where(logFilter.TakeLogEvent);
    
            return filteredData.Select(x => new LogEntry
            {
                Timestamp = x.Timestamp,
                Level = Enum.Parse<Core.Logging.LogLevel>(x.Level.ToString()),
                MessageTemplateText = x.MessageTemplate.Text,
                Exception = x.Exception?.ToString(),
                Properties = MapLogMessageProperties(x.Properties),
                RenderedMessage = x.RenderMessage(),
            });
        }
    
        private IReadOnlyDictionary<string, string?> MapLogMessageProperties(
            IReadOnlyDictionary<string, LogEventPropertyValue>? properties)
        {
            var result = new Dictionary<string, string?>();
    
            if (properties is not null)
            {
                foreach (KeyValuePair<string, LogEventPropertyValue> property in properties)
                {
                    string? value;
    
                    if (property.Value is ScalarValue scalarValue)
                    {
                        value = scalarValue.Value?.ToString();
                    }
                    else if (property.Value is StructureValue structureValue)
                    {
                        var textWriter = new StringWriter();
                        structureValue.Render(textWriter);
                        value = textWriter.ToString();
                    }
                    else
                    {
                        value = _jsonSerializer.Serialize(property.Value);
                    }
    
                    result.Add(property.Key, value);
                }
            }
    
            return result;
        }
    
        public class AzureTableLogEntity : ITableEntity
        {
            public required string Data { get; set; }
    
            public required string PartitionKey { get; set; }
    
            public required string RowKey { get; set; }
    
            public DateTimeOffset? Timestamp { get; set; }
    
            public ETag ETag { get; set; }
        }
    }
    public class AzureTableLogsService : LogViewerServiceBase
    {
        public AzureTableLogsService(
            ILogViewerQueryRepository logViewerQueryRepository,
            ICoreScopeProvider provider,
            ILogViewerRepository logViewerRepository)
            : base(logViewerQueryRepository, provider, logViewerRepository)
        {
        }
    
        // Change this to what you think is sensible.
        // As an example, check whether more than 5 days off logs are requested.
        public override Task<Attempt<bool, LogViewerOperationStatus>> CanViewLogsAsync(LogTimePeriod logTimePeriod)
        {
            return logTimePeriod.EndTime - logTimePeriod.StartTime < TimeSpan.FromDays(5)
                ? Task.FromResult(Attempt.SucceedWithStatus(LogViewerOperationStatus.Success, true))
                : Task.FromResult(Attempt.FailWithStatus(LogViewerOperationStatus.CancelledByLogsSizeValidation, false));
        }
    
        public override ReadOnlyDictionary<string, LogLevel> GetLogLevelsFromSinks()
        {
            var configuredLogLevels = new Dictionary<string, LogLevel>
            {
                { "Global", GetGlobalMinLogLevel() },
                { "AzureTableStorage", LogViewerRepository.RestrictedToMinimumLevel() },
            };
    
            return configuredLogLevels.AsReadOnly();
        }
    }
    using Umbraco.Cms.Core.Composing;
    using Umbraco.Cms.Infrastructure.DependencyInjection;
    using Umbraco.Cms.Core.Services;
    
    namespace My.Website;
    
    public class AzureTableLogsComposer : IComposer
        {
            public void Compose(IUmbracoBuilder builder)
            {
                builder.Services.AddUnique<ILogViewerRepository, AzureTableLogsRepository>();
                builder.Services.AddUnique<ILogViewerService, AzureTableLogsService>();
            }
        }
    }
    {
        "Name": "AzureTableStorage",
        "Args": {
            "storageTableName": "LogEventEntity",
            "formatter": "Serilog.Formatting.Compact.CompactJsonFormatter, Serilog.Formatting.Compact",
            "connectionString": "DefaultEndpointsProtocol=https;AccountName=ACCOUNT_NAME;AccountKey=KEY;EndpointSuffix=core.windows.net"
        }
    }

    Umbraco HQ offers a training course covering the basics of working with Umbraco CMS in a load-balanced setup. The course targets backend developers and operations engineers.

    Explore the Load Balancing Training Course to learn more about the topics covered and get more details about the course.

    Video Tutorial
    Learn how to use the Log Viewer to read and understand logs for your Umbraco CMS website.
    ProWorks
    Learn more about the package and the migration process on Prowork's blog
    DefaultPreValueMigrator
    Umbraco-CMS codebase
  • Site: The nearest ancestor of the current node with a domain assigned.

  • Specific node: A specific node selected from the existing content.

  • Find the furthest descendant or current item that fits with one of the configured Document Types.

    ...

  • Umbraco anno MMXXIII [talk]

  • Stages [stages]

    • Social Space [stage]

    • No 10 [stage]

    • No 16 [stage]

    • The Theatre [stage]

  • 2022 [year]

    • Talks [talks]

      • ...

    • Stages [stages]

      • Main Stage [stage]

      • The Barn [stage]

      • The Theatre [stage]

  • Document Picker
    adding custom query steps in the section below
    Node Type section
    Content Service
    Content Picker Data Type Settings
    The option to specify a root node also called the "origin" becomes available when Content is selected as the Node Type.
    The available options for setting a root node (origin) for the Content Picker.
    The default options for executing additional steps to locate the Dynamic Root.
    Query steps appended to a Content Picker with the type Content.
    [RuntimeLevel(MinLevel = RuntimeLevel.Upgrade, MaxLevel = RuntimeLevel.Upgrade)] // only on upgrades
    public class PreValueMigratorComposer : IUserComposer
    {
        public void Compose(Composition composition)
        {
            composition.WithCollectionBuilder<PreValueMigratorCollectionBuilder>()
                // Append all of the migrators required
                .Append<MyCustomPreValueMigrator>()
                .Append<AnotherPreValueMigrator>();
        }
    }
    public class MyCustomDynamicRootQueryStep : IDynamicRootQueryStep
    {
        private readonly IMyCustomRepository _myCustomRepository;
    
        public MyCustomDynamicRootQueryStep(IMyCustomRepository myCustomRepository)
        {
            _myCustomRepository = myCustomRepository;
        }
    
        // The string below is what you specify in the UI to execute this custom query step.
        public virtual string SupportedDirectionAlias { get; set; } = "MyCustomStep";
    
        public async Task<Attempt<ICollection<Guid>>> ExecuteAsync(ICollection<Guid> origins, DynamicRootQueryStep filter)
        {
            if (filter.Alias != SupportedDirectionAlias)
            {
                return Attempt<ICollection<Guid>>.Fail();
            }
    
            if (origins.Any() is false)
            {
                return Attempt<ICollection<Guid>>.Succeed(Array.Empty<Guid>());
            }
    
            // Replace the following with your custom logic
            var result = await _myCustomRepository.GetWhateverIWantAsync(origins);
    
            return Attempt<ICollection<Guid>>.Succeed(result);
        }
    }
    public class CustomQueryStepComposer : IComposer
    {
        public void Compose(IUmbracoBuilder builder)
        {
            builder.DynamicRootSteps().Append<MyCustomDynamicRootQueryStep>();
        }
    }
    {
      "$schema": "../../umbraco-package-schema.json",
      "name": "My.Test.Extension",
      "version": "0.1.0",
      "extensions": [
        {
          "type": "dynamicRootQueryStep",
          "alias": "Umb.DynamicRootQueryStep.MyCustomStep",
          "name": "Dynamic Root Query Step: My Custom Step",
          "meta": {
            "queryStepAlias": "MyCustomStep",
            "label": "My Custom Step",
            "description": "My custom step description.",
            "icon": "icon-coffee"
          },
          "weight": 0
        }
      ]
    }
    @{
        var typedContentPicker = Model.Value<IEnumerable<IPublishedContent>>("featuredArticles");
        if (typedContentPicker != null) {
            foreach (var item in typedContentPicker)
            {
                <p>@item.Name</p>
            }
    }
    @{
        var typedContentPicker = Model.FeaturedArticles;
        foreach (var item in typedContentPicker)
        {
            <p>@item.Name</p>
        }
    }
    @using Umbraco.Cms.Core
    @using Umbraco.Cms.Core.Services
    @inject IContentService ContentService
    @{
        // Create a variable for the GUID of the page you want to update
        var guid = Guid.Parse("32e60db4-1283-4caa-9645-f2153f9888ef");
    
        // Get the page using the GUID you've defined
        var content = ContentService.GetById(guid); // ID of your page
    
        // Get the pages you want to assign to the Content Picker
        var page = Umbraco.Content("665d7368-e43e-4a83-b1d4-43853860dc45");
        var anotherPage = Umbraco.Content("1f8cabd5-2b06-4ca1-9ed5-fbf14d300d59");
    
        // Create Udi's of the pages
        var pageUdi = Udi.Create(Constants.UdiEntityType.Document, page.Key);
        var anotherPageUdi = Udi.Create(Constants.UdiEntityType.Document, anotherPage.Key);
    
        // Create a list of the page udi's
        var udis = new List<string>{pageUdi.ToString(), anotherPageUdi.ToString()};
    
        // Set the value of the property with alias 'featuredArticles'.
        content.SetValue("featuredArticles", string.Join(",", udis));
    
        // Save the change
        ContentService.Save(content);
    }
    @{
        // Get the page using it's id
        var content = ContentService.GetById(1234);
    }
    @using Umbraco.Cms.Core.PublishedCache
    @inject IPublishedContentTypeCache PublishedContentTypeCache
    @{
        // Set the value of the property with alias 'featuredArticles'
        content.SetValue(Home.GetModelPropertyType(PublishedContentTypeCache, x => x.FeaturedArticles).Alias, string.Join(",", udis));
    }
    Upload Media - Media section
    Upload Media - Media section
    Media Section - List view
    Defining crops
    Configure Collection
    Employee Images
    Upload Media - Create Button
    Media Section - Cardview

    Defining Content

    Here you'll find an explanation of how content is defined in Umbraco

    Before a piece of content can be created in the Umbraco backoffice, first it needs to be defined. That is why, when opening a blank installation of Umbraco, it is not possible to create content in the Content section.

    All content needs a blueprint that holds information about what kind of data can be stored on the content node or which editors are used.

    Additionally, it also needs information on how it is organized, where in the structure it is allowed, and so forth. This blueprint or definition is called a Document Type.

    What is a Document Type?

    Document Types define what kind of content can be created in the Content section and what an end-user sees and can interact with.

    It can define entire pages or more limited content that can be reused on other nodes ie. a Search Engine Optimization (SEO) group. This means that you are in complete control of what type of content can be created and where.

    Another example is if there is a "Blog post" Document Type that has some properties containing a thumbnail, a name, and an author image. Then all blog posts using the "Blog post" Document Type, will allow the end user to fill in a thumbnail, author name, and an author image.

    A Document Type contains fieldsets (or groups) where you can apply rules about where the content can be created, allowed template(s), backoffice icons, etc.

    1. Creating a Document Type

    A Document Type is created using the Document Type editor in the Settings section.

    • Go to the Settings section in the backoffice.

    • On the Document Types node click the menu icon (•••) to bring up the context menu.

    • Here choose Document Type with Template. This will create a new Document Type with a template. The Template can be found under Templates in the Settings section which will be assigned as the default template for the Document Type.

    You can also choose to create a Document Type without a template and create Folders to organize your Document Types. Other options are to create Compositions and Element types, which you can read more about in the section.

    2. Defining the root node

    Name the Document Type

    First, we're prompted to give the Document Type a name. This first Document Type will be the root node for our content, name it "Home".

    The alias of the Document Type is automatically generated based on the property name. If you want to change the auto-generated alias, click the "lock" icon. The alias must be in camel case. For example: homePage.

    Having a root node lets you quickly query content as you know everything will be under the root node.

    Adding Icons to the Document Type

    Choosing appropriate icons for your content nodes is a good way to give editors a better overview of the content tree.

    To set an icon for the Document Type click the document icon in the top left corner. This will open the icon select dialog. Search for "Home"and select the icon. This icon will be used in the content tree.

    Setting Permissions

    This will allow this Document Type to be created as the first content in the Content section.

    • Go to the Structure tab

    • Tick the Allow as root toggle

    • Save the Document Type by clicking save in the bottom right corner.

    3. Creating the content

    Now that we have the Document Type in place, we can create the content.

    • Go to the Content section

    • Click on the menu icon next to Content

    • Select the "Home" Document Type. We'll name it "Home"

    As we haven't created our properties, all we can see on the "Home" node is the Properties tab. This tab contains the default properties that are available on all content nodes in Umbraco.

    Let's add some properties of our own.

    4. Groups and properties

    In order to add the option to create different content on the same Document Type, some groups and properties need to be added.

    Groups

    Groups are a way to organize and structure the properties within the content, making it more manageable. It also makes it more user-friendly for content editors when creating or editing content on a website.

    A name can be added to the group and after properties can be added.

    Properties

    Each field on a Document Type is called a property. The property is given a name, an alias (used to output the properties contained in a template), and an editor.

    The editor determines what type of data the property will store and the input method. There is a wide range of default and you can .

    Some editors require configuration where a configured editor is saved as a Data Type and can be reused for multiple properties and document types. These can be seen in the Settings section under Data Types.

    • Go to the Settings section

    • Expand Document Types by clicking the arrow to the left

    • Select the "Home" Document Type.

    Keyboard Shortcuts

    Keyboard shortcuts are available when you are working with the Document Type editor. To see which shortcuts are available, click ALT + SHIFT + K.

    Adding groups

    Before we start adding properties to the Document Type we need to create a group to hold the property.

    • Click Add group and name the group "Content".

    If you have multiple groups and/or properties you can order them with drag and drop or by entering a numeric sort order value. This is done by clicking Reorder.

    To convert a group to a tab, see the section in the article.

    Adding properties

    Now that we have created a group we can start adding properties. Let's add a Rich Text editor to the Content group.

    • Click the Add property link in the Content group. This opens the property settings dialog. Here you can set the metadata for each property (name, alias, description)

    • Choose which Data Type/property editor to use, and add validation if needed.

    • Give the property a name. The name will be shown to the editor to make it relevant and understandable. Notice the alias is automatically generated based on the name. We'll name this "Body Text".

    Property Editors

    • Clicking Select Editor will open the Select Editor dialog. Here, you can choose between all the available editors on the Create a new Configuration tab. This will create a new configuration or already configured editors in the Available Configurations tab.

    • To make it easier to find what you need use the search field to filter by typing "Rich". Filtering will display configured properties first (under Available configurations) and all available editors under that.

    • Select the Rich Text editor under Create new. This will let you configure the editor settings - the Rich Text editor for this property.

    The name of the Data Type is based on the name of the Document Type, the name of the property, and the property editor. Flor example: Home - Body Text - Rich Text editor.

    • Let's rename it to "Basic Rich Text editor" and only select the most necessary options.

      • bold

      • italic

    Selecting the Mandatory toggle makes the property mandatory and the content cannot be saved if no value is entered (in this case, the Richtext editor).

    You have the option to add additional validation by selecting a predefined validation method under the Custom validation dropdown (such as email, number, or URL). Or by selecting a custom validation and adding a regular expression.

    • Save the Document Type.

    • If you go to the Content section and click on the Home node you will now see the Contentgroup with the Body Text property.

    Property descriptions

    The description of the property is not necessary, but it´s a best practice as it guides the editor to use the property correctly. The property description supports some markdown and one custom collapse syntax:

    Bold

    You can make text in the description bold by wrapping it with **

    Italic

    You can make text in the description italic by wrapping it with *

    Links

    You can make links by using the syntax:

    Note: Links will always have thetarget="_blank" set. This is currently not configurable.

    Images

    You can embed images by using this syntax:

    Collapsible description

    You can make the description collapsible by using this syntax:

    Now if we put it all together we get something like this:

    5. Defining child nodes

    Next up we'll create a text page Document Type that will be used for subpages on the site.

    • Go back to the Settings section

    • Create a new Document Type

    • Name it "Text Page".

    • Add a group called "Content

    Creating child nodes

    Before creating a Text Page in Content section, allow the Text Page Document Type to be created as a child node to the Home node.

    • Select the "Home" Document Type

    • Go to the Structure group.

    • Click Add child

    • Select "Text Page

    • Go to the Content section

    • Click the menu icon (•••) next to the "Home" node

    • Select the "Text page" Document Type. We'll name the page "About us". We now have a basic content structure.

    Document Types are flexible and can be used for defining pieces of reusable content or an entire page, to act as a container or repository.

    6. Exporting/Importing the Document Type

    You can also export document types from an already existing project/installation and import them into another project/installation.

    • Go to the Settings section

    • Click ... next to the Document type

    • Select Export. When you click on the Export button, the Document Type is saved as a *.udt file.

    To import a Document Type:

    • Go to the Settings section

    • Click ... next to the Document type

    • Select Import Document Type

    • Click on the Import button and browse to the Document Type you exported. The Name and

    1. If your Document Type contains compositions or inherits from another Document Type, then you need to export/import the Composition/Document Type too.

    2. You cannot export/import document types on Umbraco Cloud.

    More information

    Related Services

    Tutorials

    Login

    In this article you can learn the various ways of customizing the Umbraco backoffice login screen and form.

    To access the backoffice, you will need to login. You can do this by adding /umbraco at the end of your website URL, for example http://mywebsite.com/umbraco.

    You will be presented with a login form similar to this:

    The login screen contains a short greeting, a login form and an optional Forgotten password link.

    Below, you will find instructions on how to customize the login screen.

    Watch this tutorial and learn how to create your own Media Types in Umbraco CMS.
    Then click the Save and Publish button.

    alignLeft

  • alignCenter

  • link

  • umbMediaPicker

  • When you are happy with the settings click Submit.

  • "
  • This time we'll add two properties:

    • First, make a property called "Summary" using the Textarea editor

    • Secondly, create a property called "Body Text" and reuse the Rich Text Editor Data Type.

  • ".
    Alias
    of the Document Type are displayed.
  • Click Import to complete the process.

  • Default Document Types
    property editors available
    customize additional editors
    Convert a group to a tab
    Using Tabs
    Rendering Content
    Customizing Data Types
    ContentService
    ContentTypeService
    Creating a basic website with Umbraco
    CreateDoctype
    Name the Document Type
    Home icon
    Allow as root
    Create homepage
    Creating groups
    Creating groups
    Adding a property
    Choosing the Rich Text editor
    Makrdown description example
    Allow Child page
    Allow Child page
    Exporting a Document Type
    Importing a Document Type
    This is **bold**
    This is *italic*
    [This is an absolute link](https://google.com)
    [This is a relative link](/umbraco#/media)
    ![Image alt text](https://media.giphy.com/media/bezxCUK2D2TuBCJ7r5/giphy.gif)
    <details>
      <summary>This is displayed</summary>
      This is hidden.
    </details>
    This is **bold**
    This is *italic*
    [This is an absolute link](https://google.com)
    [This is a relative link](/umbraco#/media)
    --
    ![Image alt text](https://media.giphy.com/media/bezxCUK2D2TuBCJ7r5/giphy.gif)
    Greeting

    The login screen features a greeting text: The "Welcome" headline. This can be personalized by overriding the existing language translation keys.

    To do this follow the steps below:

    1. Register a 'localization' manifest for the default language of your Umbraco site, (usually en-US) to override the greetings.

    1. Add an en-us.js file containing the following:

    This will override the default greetings with the ones you provide. The login screen will now display "It is Sunday" instead of "Welcome" for example.

    The login screen has its own set of localization files independent of the rest of the Backoffice. You can read more about Backoffice localization in the UI Localization article.

    You can customize other text on the login screen as well. First, grab the default values and keys from the en.ts in the Umbraco CMS GitHub repository. Thereafter copy the ones you want to translate into ~/App_Plugins/Login/umbraco-package.json file.

    Password reset

    The Forgotten password? link allows your backoffice users to reset their password. To use this feature, you will need to add the following key to the Umbraco.Cms.Security section in the appsettings.json file:

    Set it to true to enable the password reset feature, and false to disable the feature.

    You will also need to configure a Simple Mail Transfer Protocol (SMTP) server in your appsettings.json file. When you get a successful result on the SMTP configuration when running a health check in the backoffice, you are good to go!

    An example:

    Custom background image and logo

    It is possible to customize the background image and the logo for the backoffice login screen by adding the "Content" section in the appsettings.json file:

    The LoginBackgroundImage, LoginLogoImage, and LoginLogoImageAlternative are referenced from the /wwwroot/umbraco/ folder.

    The LoginLogoImage is displayed on top of the LoginBackgroundImage and the LoginLogoImageAlternative is displayed when the LoginLogoImage is not available, for example on small resolutions.

    Custom CSS

    You can also customize the login screen by adding a custom CSS file. To do this, you will need to add a new file inside the ~/App_Plugins folder, for example ~/App_Plugins/Login/my-custom-login-screen.css.

    You can then add your custom CSS to the file:

    This will change the color of the SVG graphics (curves) shown on the login screen. You can also hide the curves by adding the following CSS:

    Load the custom CSS file

    To tell Umbraco about your custom CSS file, you will need to add a umbraco-package.json file. The umbraco-package.json file should look like this:

    Next add a JavaScript file, for example ~/App_Plugins/Login/my-custom-login-screen.js, and add the following code to load the custom CSS file:

    This will load the custom CSS file into Umbraco.

    Be aware that the custom CSS file will be loaded on all Umbraco screens, not only the login screen.

    Custom CSS properties reference

    The following CSS properties are available for customization:

    CSS Property
    Description
    Default Value

    --umb-login-background

    The background of the layout

    #f4f4f4

    --umb-login-primary-color

    The color of the headline

    #283a97

    --umb-login-text-color

    The color of the text

    #000

    --umb-login-header-font-size

    The font-size of the headline

    The CSS custom properties may change in future versions of Umbraco. You can always find the latest values in the login layout element in the Umbraco CMS GitHub repository.

    The Time Out Screen

    Time out screen

    The time out screen is displayed when the user has been inactive for a certain amount of time. The screen resembles the login screen in many ways and the two are sometimes confused. The most notable difference is that the time out screen does not have a login form. It only has a message and a button to log in again with Umbraco.

    If you have added more than one login provider, the users will also see this screen first. This is because they need to choose which provider to use first. In that case, the screen is also referred to as the Choose provider screen.

    You can customize the time out screen in the same way as the login screen. The time out screen uses the same localization files as the rest of the Backoffice and not those of the login screen. The notable difference is that the time out screen is scoped to the login section. The login screen is scoped to the auth section of the localization files.

    Greeting

    To update the greeting message on this screen, you will have to change the section to login:

    The en-us.js file should contain the following:

    The instruction key is shown when the user has timed out, and the greeting0..6 keys are shown when the user has to choose a login provider.

    Image

    You can update the image on the time out screen through a custom CSS variable. The default value is --umb-login-image and it is set to the same value as the login screen. You can override this value in your custom CSS file:

    Login screen
    App_Plugins/Login/umbraco-package.json
    {
        "alias": "login.extensions",
        "name": "Login extensions",
        "version": "1.0.0",
        "allowPublicAccess": true,
        "extensions": [
            {
                "type": "localization",
                "alias": "Login.Localize.EnUS",
                "name": "English",
                "js": "/App_Plugins/Login/en-us.js",
                "meta": {
                    "culture": "en-US"
                }
            }
        ]
    }
    App_Plugins/Login/en-us.js
    export default {
      auth: {
        instruction: "Log in again to continue",
        greeting0: "Is is Sunday",
        greeting1: "Is is Monday",
        greeting2: "Is is Tuesday",
        greeting3: "Is is Wednesday",
        greeting4: "Is is Thursday",
        greeting5: "Is is Friday",
        greeting6: "Is is Saturday",
      }
    }
    "Umbraco": {
        "CMS": {
          "Security": {
            "AllowPasswordReset": true
          }
       }
    }
    "Umbraco": {
        "CMS": {
          "Global": {
            "Id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "Smtp": {
              "From": "[email protected]",
              "Host": "127.0.0.1",
              "Username": "username",
              "Password": "password"
            }
          }
        }
    }
    "Umbraco": {
        "CMS": {
          "Content": {
            "LoginBackgroundImage": "../myImagesFolder/myLogin.jpg",
            "LoginLogoImage": "../myImagesFolder/myLogo.svg",
            "LoginLogoImageAlternative": "../myImagesFolder/myLogo.svg"
          }
       }
    }
    :root {
        --umb-login-curves-color: rgba(0, 0, 0, 0.1);
    }
    :root {
        --umb-login-curves-display: none;
    }
    {
        "alias": "login.extensions",
        "name": "Login extensions",
        "version": "1.0.0",
        "allowPublicAccess": true,
        "extensions": [
            {
                "type": "appEntryPoint",
                "alias": "MyCustomLoginScreen",
                "name": "My Custom Login Screen",
                "js": "/App_Plugins/Login/my-custom-login-screen.js"
            }
        ]
    }
    const link = document.createElement('link');
    link.rel = 'stylesheet';
    link.href = '/App_Plugins/Login/my-custom-login-screen.css';
    document.head.appendChild(link);
    App_Plugins/Login/umbraco-package.json
    {
        "alias": "login.extensions",
        "name": "Login extensions",
        "version": "1.0.0",
        "allowPublicAccess": true,
        "extensions": [
            {
                "type": "localization",
                "alias": "Login.Localize.EnUS",
                "name": "English",
                "js": "/App_Plugins/Login/en-us.js",
                "meta": {
                    "culture": "en-US"
                }
            }
        ]
    }
    App_Plugins/Login/en-us.js
    export default {
      auth: {
        instruction: "Log in again to continue",
        greeting0: "Is is Sunday",
        greeting1: "Is is Monday",
        greeting2: "Is is Tuesday",
        greeting3: "Is is Wednesday",
        greeting4: "Is is Thursday",
        greeting5: "Is is Friday",
        greeting6: "Is is Saturday",
      }
    }
    :root {
        --umb-login-image: url(../myImagesFolder/myTimeout.jpg);
    }

    3rem

    --umb-login-header-font-size-large

    The font-size of the headline on large screens

    4rem

    --umb-login-header-secondary-font-size

    The font-size of the secondary headline

    2.4rem

    --umb-login-image

    The background of the image wrapper

    The value of the LoginBackgroundImage setting

    --umb-login-image-display

    The display of the image wrapper

    flex

    --umb-login-image-border-radius

    The border-radius of the image wrapper

    38px

    --umb-login-content-background

    The background of the content wrapper

    none

    --umb-login-content-display

    The display of the content wrapper

    flex

    --umb-login-content-width

    The width of the content wrapper

    100%

    --umb-login-content-height

    The height of the content wrapper

    100%

    --umb-login-content-border-radius

    The border-radius of the content wrapper

    0

    --umb-login-align-items

    The align-items of the main wrapper

    unset

    --umb-login-button-border-radius

    The border-radius of the buttons

    45px

    --umb-login-curves-color

    The color of the curves

    #f5c1bc

    --umb-login-curves-display

    The display of the curves

    inline

    Block Grid

    Schema Alias: Umbraco.BlockGrid

    UI Alias: Umb.PropertyEditorUi.BlockGrid

    Returns: BlockGridModel

    The Block Grid property editor enables editors to layout their content in the Umbraco backoffice. The content is made of Blocks that can contain different types of data.

    This article is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.

    Sample configuration

    When testing out the property editor, you can use a set of predefined Blocks. The option will only be possible when there are no other Data Types using the Block Grid property editor.

    • Create a new Data Type.

    • Select the Block Grid as the Property editor.

    • Install the "Sample Configuration".

    4 Blocks will be added to the property, ready for testing.

    Configuring the Block Grid

    The Block Grid property editor is configured via the Data Types backoffice interface.

    To set up the Block Grid property editor, follow these steps:

    1. Navigate to the Settings section in the Umbraco backoffice.

    2. Click ... next to the Data Types folder.

    3. Select Create -> New Data Type.

    4. Select Block Grid from the list of available property editors.

    You will see the configuration options for a Block Grid property editor as shown below:

    The Data Type editor allows you to configure the following properties:

    • Blocks - Defines the Block Types available for use in the property. For more information, see .

    • Amount - Sets the minimum and/or the maximum number of Blocks that should be allowed at the root of the layout.

    • Live editing mode - Enabling this option will allow you to see the changes as you are editing them.

    • Editor width - Overwrites the width of the property editor. This field takes any valid CSS value for "max-width". For example: 100% or 800px.

    Setup Block Types

    Block Types are based on . These can be created beforehand or while setting up your Block Types.

    Once you have added an Element Type as a Block Type on your Block Grid Data Type you have the option to configure it.

    Groups

    Blocks can also be grouped. This is visible in the Block Catalogue and can also be used to allow a group of Blocks in an Area.

    Block Configuration Settings

    Each Block has a set of properties that are optional to configure. These are described below.

    General

    Customize the user experience for your content editors when they work with the Blocks in the Content section.

    • Label - Defines a label for the appearance of the Block in the editor. The label can use AngularJS template-string-syntax to display values of properties. The label is also used for search in the Add Block dialog during content editing. If no label is defined, the block will not be searchable. The search does not fall back to the block’s name.

    Label example: "My Block {=myPropertyAlias}" will be shown as: "My Block FooBar".

    • Content model - Presents the Element Type used as model for the Content section of this Block. This cannot be changed but you can open the Element Type to perform edits or view the properties available. Useful when writing your Label.

    • Settings model - Adds a Settings section to your Block based on a given Element Type. When selected you can open the Element Type or choose to remove the Settings section again.

    Size options

    Customize the Blocks size in the Grid. If you define multiple options, the Block becomes scalable.

    By default, a Block takes up the available width.

    A Block can be resized in two ways:

    1. When a Block is placed in an Area, it will fit to the Areas width. Learn more about .

    2. A Block can have one or more Column Span options defined.

    A Column Span option is used to define the width of a Block. With multiple Column Span options defined, the Content Editor can scale the Block to fit specific needs.

    Additionally, Blocks can be configured to span rows, this enables one Block to be placed next to a few rows containing other Blocks.

    • Available column spans - Defines one or more columns, the Block spans across. For example: in a 12 columns grid, 6 columns is equivalent to half width. By enabling 6 columns and 12 columns, the Block can be scaled to either half width or full width.

    • Available row spans - Defines the amount of rows the Block spans across.

    See the section of this article for an example of how scaling works.

    Catalogue appearance

    These properties refer to how the Block is presented in the Block catalogue when editors choose which Blocks to use for their content.

    • Background color - Defines a background color to be displayed beneath the icon or thumbnail. Example: #424242.

    • Icon color - Changes the color of the Element Type icon. Example: #242424.

    • Thumbnail - Pick an image or Scalable Vector Graphics (SVG) file to replace the icon of the Block in the catalogue.

    The thumbnails for the catalogue are presented in the format of 16:10. We recommend a resolution of 400px width and 250px height.

    Permissions

    • Allow in root - Determines whether the Block can be created at the root of your layout. Turn this off if you only want a Block to appear within Block Areas.

    • Allow in areas - Determines whether the Block can be created inside Areas of other Blocks. If this is turned off it can still be allowed in Block Areas by defining specific allowed Blocks.

    Areas

    Blocks can nest other Blocks to support specific compositions. These compositions can be used as a layout for other Blocks.

    To achieve nesting, a Block must have one or more Areas defined. Each Area can contain one or more Blocks.

    Each Area has a size, defined by column and rows spans. The grid for the Areas are based on the same amount of columns as your root grid, unless you choose to change it.

    To scale an Area, click and drag the scale-button in the bottom-right corner of an Area.

    • Grid Columns for Areas - Overwrites the amount of columns used for the Area grid.

    • Areas - Determines whether the Block can be created inside Areas of other Blocks.

    Area configuration

    • Alias - The alias is used to identify this Area. It is being printed by GetBlockGridHTML() and used as name for the Area slot in Custom Views. The alias is also available for CSS Selectors to target the HTML-Element representing an Area.

    • Create Button Label - Overwrites the Create Button Label of the Area.

    • Number of blocks - Determines the total number of Blocks in an Area.

    When allowing a Group of Blocks, you might want to require a specific amount for a certain Block of that Group. This can be done by adding that Block Type to the list as well and set the requirements.

    Advanced

    These properties are relevant when working with custom views or complex projects.

    • Custom view - Overwrites the AngularJS view for the block presentation in the Content editor. Use this view to make a more visual presentation of the Block or make your own editing experience by adding your own AngularJS controller to the view.

    Notice that any styling of a Block is scoped. This means that the default backoffice styles are not present for the view of this Block.

    • Custom stylesheet - Pick your own stylesheet to be used by the Block in the Content editor.

    • Overlay editor size - Sets the size for the Content editor overlay for editing this block.

    • Hide content editor - Hides the UI for editing the content in a Block Editor. This is only relevant if you made a custom view that provides the UI for editing of content.

    Editing Blocks

    When viewing a Block Grid property editor in the Content section for the first time, you will be presented with the option to Add content.

    Clicking the Add content button opens up the Block Catalogue.

    The Block Catalogue looks different depending on the amount of available Blocks and their catalogue appearance.

    Click the Block Type you wish to create and a new Block will appear in the layout.

    More Blocks can be added to the layout by clicking the Add content button. Alternatively, use the Add content button that appears on hover to add new Blocks between, besides, or above the existing Blocks.

    To delete a Block, click the trash icon which appears on the mouse hover.

    Sorting Blocks

    Blocks can be rearranged using the click and drag feature. Move them up or down to place them in the desired order.

    Moving a Block from one Area to another is done in the same way. If a Block is not allowed in the given position, the area will display a red color and not allow the new position.

    Scaling Blocks

    If a Block has multiple size options it can be scaled via the UI. This appears in the bottom left corner of the Block.

    The Block is resized using a click-and-drag feature. Moving the mouse will change the size to the size options closest to the mouse pointer.

    Rendering Block Grid Content

    Rendering the stored value of your Block Grid property editor can be done in two ways:

    1. Default rendering

    You can choose to use the built-in rendering mechanism for rendering Blocks using a Partial View for each block.

    The default rendering method is named GetBlockGridHtmlAsync() and comes with a few options - for example:

    In the sample above "myGrid" is the alias of the Block Grid editor.

    If you are using ModelsBuilder, the example will look like this:

    To use the GetBlockGridHtmlAsync() method, you will need to create a Partial View for each Block Type. The Partial View must be named using the alias of the Element Type that is being used as Content Model for the Block Type.

    These Partial View files need to go into the Views/Partials/blockgrid/Components/ folder.

    Example: Views/Partials/blockgrid/Components/MyElementTypeAliasOfContent.cshtml.

    The Partial Views will receive a model of type Umbraco.Cms.Core.Models.Blocks.BlockGridItem. This model contains Content and Settings from your block, as well as the configured RowSpan, ColumnSpan, and Areas of the Block.

    Rendering the Block Areas

    The Partial View for the Block is responsible for rendering its own Block Areas. This is done using another built-in rendering mechanism:

    Here you will need to create a Partial View for each Block Type within the Block Area. For the name, use the alias of the Element Type that is being used as Content Model for the Block Type.

    These Partial Views must be placed in the same folder as before, (Views/Partials/blockgrid/Components/), and will receive a model of type Umbraco.Cms.Core.Models.Blocks.BlockGridItem.

    Putting it all together

    The following is an example of a Partial View for a Block Type of type MyElementTypeAliasOfContent.

    If you are using ModelsBuilder, you can make the property rendering strongly typed by letting your view accept a model of type BlockGridItem<T>. For example:

    Stylesheet

    Using the default rendering together with your layout stylesheet will provide what you need for rendering the layout.

    To use the Default Layout Stylesheet, copy the stylesheet to your frontend. You can download the default layout stylesheet from the link within the DataType, we recommend putting the file in the css folder, example: wwwroot/css/umbraco-blockgridlayout.css.

    A set of built-in Partial Views are responsible for rendering the Blocks and Areas in a Block Grid. If you want to tweak or change the way the Block Grid is rendered, you can use the built-in Partial Views as a template:

    1. Clone the views from . They can be found in src/Umbraco.Web.UI/Views/Partials/blockgrid .

    2. Copy the cloned views to the local folder Views/Partials/blockgrid/

    2. Build custom rendering

    The built-in value converter for the Block Grid property editor lets you use the block data as you like. Call the Value<T> method with a type of BlockGridModel to have the stored value returned as a BlockGridModel instance.

    BlockGridModel contains the Block Grid configuration (like the number of columns as GridColumns) whilst also being an implementation of IEnumerable<BlockGridItem> (see details for BlockGridItem above).

    The following example mimics the built-in rendering mechanism for rendering Blocks using Partial Views:

    If you do not want to use Partial Views, you can access the block item data directly within your rendering:

    Write a Custom Layout Stylesheet

    The default layout stylesheet is using CSS Grid. This can be modified to fit your implementation and your project.

    Adjusting the Default Layout Stylesheet

    To make additions or overwrite parts of the default layout stylesheet, import the default stylesheet at the top of your own file.

    You need to copy the Default Layout Stylesheet to your frontend. You can download the default layout stylesheet from the link within the DataType, we recommend putting the file in the css folder, example: wwwroot/css/umbraco-blockgridlayout.css.

    Write a new Layout Stylesheet

    In this case, you would have to write the layout from scratch.

    You are free to pick any style, meaning there is no requirement to use CSS Grid. It is, however, recommended to use CSS Grid to ensure complete compatibility with the Umbraco backoffice.

    CSS Class structure and available data

    When extending or writing your own layout, you need to know the structure and what data is available.

    For example: You can use the below HTML structure:

    Build a Custom Backoffice View

    Building Custom Views for Block representations in Backoffice is based on the same API for all Block Editors.

    Creating a Block Grid programmatically

    In this example, we will be creating content programmatically for a "spot" Blocks in a Block Grid.

    1. Create an element type to represent block content called Spot Element with the following properties:

    • A property called title with the editor of Textstring

    • A property called text with the editor of Textstring

    1. Create an element type to represent block content called Spot Settings with the following properties:

    • A property called featured with the editor of True/false.

    1. Add a property called blockGrid in a Document Type.

    2. Select Block Grid as the property editor.

    3. Click Add in the Blocks Settings and select Spot Element.

    4. Select Spot Settings in the

    The raw input data for the spots looks like this:

    The resulting JSON object stored for the Block Grid will look like this:

    For each item in the raw data, we need to create:

    • One contentData entry with the title and text.

    • One settingsData entry with the featured value (the checkbox expects "0" or "1" as data value).

    • One layout

    All contentData and layoutData entries need their own unique Udi as well as the ID (key) of their corresponding Element Types. In this sample, we only have one Element Type for content (spotElement) and one for settings (spotSettings). In a real life scenario, there could be any number of Element Type combinations.

    1. Create a class called Model.cs containing the following to transform the raw data into Block Grid-compatible JSON:

    1. Create a class called BlockGridTestController.cs. By injecting IContentService and IContentTypeService into an API controller, the raw data can be transformed into Block Grid JSON. It can then be saved to the target content item.

    For the above code IContent? content = _contentService.GetById(Guid.Parse("efba7b97-91b6-4ddf-b2cc-eef89ff48c3b")); change the id with your content node that is using the Block Grid.

    1. To test this implementation, run the project and send a POST request to /umbraco/api/blockgridtest/create after your domain name. If the result shows as Saved, then check your content node, and you will see the 2 spotElement contents.

  • Grid Columns - Define the number of columns in your Block Grid. The default is 12 columns.

  • Layout Stylesheet - Replaces the built-in Layout Stylesheet. Additionally, you can retrieve the default layout stylesheet to use as a base for your own inspiration or for writing your own stylesheet.

  • Create Button Label - Overwrites the label on the Create button.

  • Allowed block types - When this is empty, all Blocks with Permissions for creation in Areas, will be available. This can be overwritten by specifying the allowed Blocks. Define the types of Blocks or Groups of Blocks that are allowed. Additionally, you can also set how many Blocks of each type/group should be present.
    .
  • Make changes to your copied views. The entry point for GetBlockGridHtmlAsync() is the view default.cshtml .

  • Settings model
    field.
    entry with the desired column and row spans.
    Setup Block Types
    Element Types
    Areas
    scaling blocks
    Default rendering
    Build your own rendering
    GitHub
    Read about building a Custom View for Blocks here
    Block Grid - Data Type Configuration
    Block Grid - Data Type Block Configuration
    Block Grid - Areas
    Block Grid - Area Configuration
    Block Grid - Add Content
    Block Grid - Setup
    Block Grid - example setup
    Block Grid - Add Content Inline
    Block Grid - Delete Content
    Block Grid - Sorting Blocks
    Scale blocks in the grid by dragging from the bottom-right corner.
    Block Grid - Block Configuration
    Block Grid - Result
    @await Html.GetBlockGridHtmlAsync(Model, "myGrid")
    @await Html.GetBlockGridHtmlAsync(Model.MyGrid)
    @await Html.GetBlockGridItemAreasHtmlAsync(Model)
    MyElementTypeAliasOfContent.cshtml
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem>;
    
    @* Render the value of field with alias 'heading' from the Element Type selected as Content section *@
    <h1>@Model.Content.Value("heading")</h1>
    
    @* Render the block areas *@
    @await Html.GetBlockGridItemAreasHtmlAsync(Model)
    MyElementTypeAliasOfContent.cshtml
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem<ContentModels.MyElementTypeAliasOfContent>>;
    @using ContentModels = Umbraco.Cms.Web.Common.PublishedModels;
    
    @* Render the Heading property from the Element Type selected as Content section *@
    <h1>@Model.Content.Heading</h1>
    
    @* Render the block areas *@
    @await Html.GetBlockGridItemAreasHtmlAsync(Model)
    <link rel="stylesheet" href="@Url.Content("~/css/blockgridlayout.css")" />
    View.cshtml
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
    @using Umbraco.Cms.Core.Models.Blocks
    @{
        var grid = Model.Value<BlockGridModel>("myGrid");
    
        // get the number of columns defined for the grid
        var gridColumns = grid.GridColumns;
    
        // iterate the block items
        foreach (var item in grid)
        {
            var content = item.Content;
    
            @await Html.PartialAsync("PathToMyFolderOfPartialViews/" + content.ContentType.Alias, item);
        }
    }
    View.cshtml
    @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage
    @using Umbraco.Cms.Core.Models.Blocks
    @{
        var grid = Model.Value<BlockGridModel>("myGrid");
    
        // get the number of columns defined for the grid
        var gridColumns = grid.GridColumns;
    
        // iterate the block items
        foreach (var item in grid)
        {
            // get the content and settings of the block
            var content = item.Content;
            var settings = item.Settings;
            // get the areas of the block
            var areas = item.Areas;
            // get the dimensions of the block
            var rowSpan = item.RowSpan;
            var columnSpan = item.ColumnSpan;
    
            // render the block data
            <div style="background-color: #@(settings.Value<string>("color"))">
                <h2>@(content.Value<string>("title"))</h2>
                <span>This block is supposed to span <b>@rowSpan rows</b> and <b>@columnSpan columns</b></span>
            </div>
        }
    }
    @import 'css/umbblockgridlayout.css';
    <div class="umb-block-grid"
         style="--umb-block-grid--grid-columns: 12;"
    >
    
        <!-- Notice this is the same markup used every time we will be printing a list of blocks: -->
        <div class="umb-block-grid__layout-container">
    
            <!-- repeated for each layout entry -->
            <div
                class="umb-block-grid__layout-item"
                data-content-element-type-alias="MyElementTypeAlias"
                data-content-element-type-key="00000000-0000-0000-0000-000000000000"
                data-element-udi="00000000-0000-0000-0000-000000000000"
                data-col-span="6"
                data-row-span="1"
                style="
                --umb-block-grid--item-column-span: 6;
                --umb-block-grid--item-row-span: 1;
                "
            >
    
                <!-- Here the Razor View or Custom View for this block will be rendered. -->
    
                <!-- Each razor view must render the 'area-container' them self.
                This can be done by the Razor helper method:
    
                @await Html.GetBlockGridItemAreasHtmlAsync(Model)
    
                The structure will be as printed below,
                Do notice targeting the 'area-container' needs a double selector as markup will be different in Backoffice.
                Here is an example of the CSS selector:
                    .umb-block-grid__area-container, .umb-block-grid__block--view::part(area-container) {
                        position: relative;
                    }
                -->
                <div
                    class="umb-block-grid__area-container"
                    style="--umb-block-grid--area-grid-columns: 9;"
                >
    
                    <!-- repeated for each area for this block type. -->
                    <div
                        class="umb-block-grid__area"
                        data-area-col-span="3"
                        data-area-row-span="1"
                        data-area-alias="MyAreaAlias"
                        style="
                        --umb-block-grid--grid-columns: 3;
                        --umb-block-grid--area-column-span: 3;
                        --umb-block-grid--area-row-span: 1;
                        ">
    
                            <!-- Notice here we print the same markup as when we print a list of blocks(same as the one in the root of this structure..):
                            <div class="umb-block-grid__layout-container">
                                ...
                            </div>
                            End of notice.  -->
                    </div>
                    <!-- end of repeat -->
    
                </div>
    
    
            </div>
            <!-- end of repeat -->
    
        </div>
    
    </div>
    new[]
    {
        new { Title = "Item one", Text = "This is item one", Featured = false, ColumnSpan = 12, RowSpan = 1 },
        new { Title = "Item two", Text = "This is item two", Featured = true, ColumnSpan = 6, RowSpan = 2 }
    }
    {
       "contentData":[
          {
             "contentTypeKey":"fd01539a-5bcf-48f7-aee5-8ad925c75902",
             "udi":null,
             "key":"019f2a7a-35b4-45b3-b867-910b3f340f25",
             "values":[
                {
                   "editorAlias":"Umbraco.TextBox",
                   "culture":null,
                   "segment":null,
                   "alias":"title",
                   "value":"Item one"
                },
                {
                   "editorAlias":"Umbraco.TextBox",
                   "culture":null,
                   "segment":null,
                   "alias":"text",
                   "value":"This is item one"
                }
             ]
          },
          {
             "contentTypeKey":"fd01539a-5bcf-48f7-aee5-8ad925c75902",
             "udi":null,
             "key":"063f8062-8610-441a-97f1-ea6d73fe2678",
             "values":[
                {
                   "editorAlias":"Umbraco.TextBox",
                   "culture":null,
                   "segment":null,
                   "alias":"title",
                   "value":"Item two"
                },
                {
                   "editorAlias":"Umbraco.TextBox",
                   "culture":null,
                   "segment":null,
                   "alias":"text",
                   "value":"This is item two"
                }
             ]
          }
       ],
       "settingsData":[
          {
             "contentTypeKey":"03c43074-a4ba-4bd2-92b1-c3a35a0eed4d",
             "udi":null,
             "key":"5b2d74bc-3e85-4aa3-b684-4b1f11522d7c",
             "values":[
                {
                   "editorAlias":"Umbraco.TrueFalse",
                   "culture":null,
                   "segment":null,
                   "alias":"featured",
                   "value":0
                }
             ]
          },
          {
             "contentTypeKey":"03c43074-a4ba-4bd2-92b1-c3a35a0eed4d",
             "udi":null,
             "key":"1c6599fc-6558-4a0b-9da8-4f002925f59f",
             "values":[
                {
                   "editorAlias":"Umbraco.TrueFalse",
                   "culture":null,
                   "segment":null,
                   "alias":"featured",
                   "value":1
                }
             ]
          }
       ],
       "expose":[
          {
             "contentKey":"019f2a7a-35b4-45b3-b867-910b3f340f25",
             "culture":null,
             "segment":null
          },
          {
             "contentKey":"063f8062-8610-441a-97f1-ea6d73fe2678",
             "culture":null,
             "segment":null
          }
       ],
       "Layout":{
          "Umbraco.BlockGrid":[
             {
                "columnSpan":12,
                "rowSpan":1,
                "areas":[
    
                ],
                "contentUdi":null,
                "settingsUdi":null,
                "contentKey":"019f2a7a-35b4-45b3-b867-910b3f340f25",
                "settingsKey":"5b2d74bc-3e85-4aa3-b684-4b1f11522d7c"
             },
             {
                "columnSpan":12,
                "rowSpan":1,
                "areas":[
    
                ],
                "contentUdi":null,
                "settingsUdi":null,
                "contentKey":"063f8062-8610-441a-97f1-ea6d73fe2678",
                "settingsKey":"1c6599fc-6558-4a0b-9da8-4f002925f59f"
             }
          ]
       }
    }
    Models.cs
    using System.Text.Json.Serialization;
    
    namespace My.Site.Models;
    
    // this is the "root" of the block grid data
    public class BlockGridData
    {
        public BlockGridData(BlockGridElementData[] contentData, BlockGridElementData[] settingsData, BlockGridExposeData[] expose, BlockGridLayout layout)
        {
            ContentData = contentData;
            SettingsData = settingsData;
            Expose = expose;
            Layout = layout;
        }
    
        [JsonPropertyName("contentData")]
        public BlockGridElementData[] ContentData { get; }
    
        [JsonPropertyName("settingsData")]
        public BlockGridElementData[] SettingsData { get; }
    
        [JsonPropertyName("expose")]
        public BlockGridExposeData[] Expose { get; }
    
        [JsonPropertyName("Layout")]
        public BlockGridLayout Layout { get; }
    }
    
    // this represents an item in the block grid content or settings data collection
    public class BlockGridElementData
    {
        public BlockGridElementData(Guid contentTypeKey, Guid key, BlockGridValueData[] values)
        {
            ContentTypeKey = contentTypeKey;
            Key = key;
            Values = values;
        }
    
        [JsonPropertyName("contentTypeKey")]
        public Guid ContentTypeKey { get; }
    
        [JsonPropertyName("key")]
        public Guid Key { get; }
    
        [JsonPropertyName("values")]
        public BlockGridValueData[] Values { get; }
    }
    
    public class BlockGridValueData
    {
        public BlockGridValueData(string alias, string editorAlias, object? value)
        {
            Alias = alias;
            EditorAlias = editorAlias;
            Value = value;
        }
    
        [JsonPropertyName("alias")]
        public string Alias { get; }
    
        [JsonPropertyName("editorAlias")]
        public string EditorAlias { get; }
    
        [JsonPropertyName("value")]
        public object? Value { get; }
    }
    
    // this represents an item in the block grid expose data collection
    public class BlockGridExposeData
    {
        public BlockGridExposeData(Guid contentKey) => ContentKey = contentKey;
    
        [JsonPropertyName("contentKey")]
        public Guid ContentKey { get; }
    }
    
    // this is a wrapper for the block grid layout, purely required for correct serialization
    public class BlockGridLayout
    {
        public BlockGridLayout(BlockGridLayoutItem[] layoutItems) => LayoutItems = layoutItems;
    
        [JsonPropertyName("Umbraco.BlockGrid")]
        public BlockGridLayoutItem[] LayoutItems { get; }
    }
    
    // this represents an item in the block grid layout collection
    public class BlockGridLayoutItem
    {
        public BlockGridLayoutItem(int columnSpan, int rowSpan, Guid contentKey, Guid settingsKey)
        {
            ColumnSpan = columnSpan;
            RowSpan = rowSpan;
            ContentKey = contentKey;
            SettingsKey = settingsKey;
        }
    
        [JsonPropertyName("columnSpan")]
        public int ColumnSpan { get; }
    
        [JsonPropertyName("rowSpan")]
        public int RowSpan { get; }
    
        [JsonPropertyName("contentKey")]
        public Guid ContentKey { get; }
    
        [JsonPropertyName("settingsKey")]
        public Guid SettingsKey { get; }
    
        [JsonPropertyName("areas")]
        // areas are omitted from this sample for abbreviation
        public object[] Areas { get; } = [];
    }
    BlockGridTestController.cs
    using Microsoft.AspNetCore.Mvc;
    using My.Site.Models;
    using Umbraco.Cms.Core.Models;
    using Umbraco.Cms.Core.Serialization;
    using Umbraco.Cms.Core.Services;
    
    namespace My.Site.Controllers;
    
    [ApiController]
    [Route("/umbraco/api/blockgridtest")]
    public class BlockGridTestController : Controller
    {
        private readonly IContentService _contentService;
        private readonly IContentTypeService _contentTypeService;
        private readonly IJsonSerializer _serializer;
    
        public BlockGridTestController(IContentService contentService, IContentTypeService contentTypeService, IJsonSerializer serializer)
        {
            _contentService = contentService;
            _contentTypeService = contentTypeService;
            _serializer = serializer;
        }
    
        // POST: /umbraco/api/blockgridtest/create
        [HttpPost("create")]
        public ActionResult Create()
        {
            // get the item content to modify
            IContent? content = _contentService.GetById(Guid.Parse("7ed0bd1f-2a52-4b45-9811-2560b907fe48"));
            if (content == null)
            {
                return NotFound("Could not find the content item to modify");
            }
    
            // get the element types for spot blocks (content and settings)
            IContentType? spotContentType = _contentTypeService.Get("spotElement");
            IContentType? spotSettingsType = _contentTypeService.Get("spotSettings");
            if (spotContentType == null || spotSettingsType == null)
            {
                return NotFound("Could not find one or more content types for block data");
            }
    
            // this is the raw data to insert into the block grid
            var rawData = new[]
            {
                new { Title = "Item one", Text = "This is item one", Featured = false, ColumnSpan = 12, RowSpan = 1 },
                new { Title = "Item two", Text = "This is item two", Featured = true, ColumnSpan = 6, RowSpan = 2 }
            };
    
            // build the individual parts of the block grid data from the raw data
            var contentData = new List<BlockGridElementData>();
            var settingsData = new List<BlockGridElementData>();
            var exposeData = new List<BlockGridExposeData>();
            var layoutItems = new List<BlockGridLayoutItem>();
            foreach (var data in rawData)
            {
                // generate new keys for block content and settings
                var contentKey = Guid.NewGuid();
                var settingsKey = Guid.NewGuid();
    
                // create new content data
                var contentValues = new BlockGridValueData[]
                {
                    new("title", "Umbraco.TextBox", data.Title),
                    new("text", "Umbraco.TextBox", data.Text),
                };
                contentData.Add(new BlockGridElementData(spotContentType.Key, contentKey, contentValues));
    
                // create new settings data
                var settingValues = new BlockGridValueData[]
                {
                    new("featured", "Umbraco.TrueFalse", data.Featured ? "1" : "0"),
                };
                settingsData.Add(new BlockGridElementData(spotSettingsType.Key, settingsKey, settingValues));
    
                // create a new expose item
                exposeData.Add(new BlockGridExposeData(contentKey));
    
                // create a new layout item
                layoutItems.Add(new BlockGridLayoutItem(data.ColumnSpan, data.RowSpan, contentKey, settingsKey));
            }
    
            // construct the block grid data from layout, content and settings
            var blockGridData = new BlockGridData(
                [.. contentData],
                [.. settingsData],
                [.. exposeData],
                new BlockGridLayout([.. layoutItems]));
    
            // serialize the block grid data as JSON and save it to the "blockGrid" property on the content item
            var propertyValue = _serializer.Serialize(blockGridData);
            content.SetValue("blockGrid", propertyValue);
            _contentService.Save(content);
    
            return Ok("Saved");
        }
    }

    Version Specific Upgrades

    This document covers specific upgrade steps if a version requires them. Most versions do not require specific upgrade steps and you will be able to upgrade directly from your current version.

    Version Specific Upgrades

    Use the information below to learn about any potential breaking changes and common pitfalls when upgrading your Umbraco CMS project.

    If any specific steps are involved with upgrading to a specific version they will be listed below.

    Use the general upgrade guide to complete the upgrade of your project.

    Breaking changes

    Umbraco 17

    System dates are updated to UTC

    In earlier versions of Umbraco, system dates have been primarily persisted as server time without time zone information, with some stored as UTC. With Umbraco 17, system dates are now always stored in UTC.

    To ensure that existing stored system dates align, a migration will run when upgrading to Umbraco 17.

    The migration consists of:

    • Determining the current time zone for the server.

    Umbraco 16

    TinyMCE is removed

    In Umbraco 15, two property editors were available for a rich text editor: TinyMCE and TipTap.

    With Umbraco 16, only TipTap is available as an option out of the box. TinyMCE's precludes us from shipping it with the MIT-licensed Umbraco CMS.

    When upgrading to Umbraco 16, any data types using TinyMCE will be migrated to use TipTap.

    To continue to use TinyMCE, a third-party package must be installed prior to the upgrade. This will disable the migration and allow you to continue with TinyMCE.

    Package migrations are asynchronous

    Umbraco 16 adds support for asynchronous migrations and part of this work involved creating a new base class for package migrations. This leads to a source-compatible but binary-incompatible breaking change. In practice, this means that package code using migrations and calling base class helper methods such as

    Umbraco 15

    Snapshots are removed

    Snapshots have been removed, meaning any code using IPublishedSnapshot, and by extension IPublishedSnapshotAccessor, must be updated. Inject IPublishedContentCache or IPublishedMediaCache and use those directly instead.

    Modelsbuilder models needs to be rebuilt

    Models generated by ModelsBuilder used the IPublishedSnapshot

    Umbraco 14

    Read more about the release of Umbraco 14 in the .

    Below you can find the list of breaking changes introduced in Umbraco 14 CMS.

    This is by far the most impactful update of Umbraco in years. We’ve fundamentally changed the way you extend Umbraco. If you are experienced in developing Web Components you can now use your preferred framework for this. If you are unsure how to proceed, you can implement it with TypeScript and the Lit library like we’ve done. In this case, start with this article on how to .

    The new Backoffice (Bellissima) is entirely built on the Umbraco UI Library. This means that you might experience some of your components not being rendered on the page because the name has been changed. You should be able to find equivalents to what you were used to. For example, the

    Umbraco 14 RC Versions

    Below you can find the list of breaking changes introduced in Umbraco 14 RC release versions.

    RC 5

    Umbraco 14 Beta Versions

    Below you can find the list of breaking changes introduced in Umbraco 14 Beta release versions.

    Beta 3

    Umbraco 13

    Below you can find the list of breaking changes introduced in Umbraco 13.

    Umbraco 12

    Umbraco 12 does not include many binary breaking changes, but there are some.

    Most notable is a functional breaking change in Migrations, that from Umbraco 12. Each translation will be executed in its own transactions instead of all migrations in one big transaction. This change has been made to ease the support for Sqlite.

    A type, enum, record, or struct visible outside the assembly is missing in the compared assembly when required to be present.

    • PagedModel has moved namespace from Umbraco.New.Cms.Core.Models to Umbraco.Cms.Core.Models

    Umbraco 11

    Most breaking changes are introduced due to updated dependencies. The breaking changes in .NET 7 and ASP.NET Core 7 are documented by .

    Besides the documented changes, we have also seen a few method signatures that are changed to support Nullable-Reference-Types.

    If you are using TinyMCE plugins or custom TinyMCE configuration you need to migrate to the latest version. Learn more about this in the .

    The breaking changes in TinyMCE are also documented in the official migration guides for and from .

    The breaking changes in Umbraco 11 are mainly the removal of classes, methods, and so on, marked as obsolete in Umbraco 9.

    A few methods and classes have also been moved and changed namespace. Decoupled dependencies are documented on the

    Umbraco 10

    The diff library used in the Backoffice client has been updated and introduces a breaking change since the exposed global object has been renamed from JsDiff to Diff.

    Removes mutable ContentSchedule property from IContent/Content to read/write content schedules.

    Release notes

    You can find a list of all the released Umbraco versions on website. When you visit Our Umbraco website, click on the version number to view the changes made in that specific version.

    Find your upgrade path

    Are you looking to upgrade an Umbraco Cloud project from 9 to 10? Follow the guide instead, as it requires a few steps specific to Umbraco Cloud.

    13.latest to the latest version

    Update _ViewImports.cshtml file

    In Umbraco 14, Smidge has been removed from the CMS.

    In the _ViewImports.cshtml of your project, remove the following lines:

    Otherwise, it will cause an error on the front end.

    Update program.cs file

    Remove u.UseInstallerEndpoints(); from the program.cs

    10.latest to 13.latest

    It might be necessary to delete all of the bin and obj directories in each of the projects of your solution. It has been observed that Visual Studio's "Clean Solution" option is sometimes not enough.

    You can upgrade from Umbraco 10 to the latest version directly. If you choose to skip upgrading to versions 11 and 12, you will no longer receive warning messages for obsolete features. However, if you do skip these versions, any breaking changes will no longer compile.

    It is recommended that you upgrade to the closest version before upgrading to the latest version. For Umbraco 10, the closest long-term support version is Umbraco 13 so a direct upgrade is possible.

    9.latest to 10

    Important: .NET version 6.0.5 is the minimum required version for Umbraco 10 to be able to run. You can check with dotnet --list-sdks what your latest installed Software Development Kit (SDK) version is. The latest SDK version 6.0.301 includes .NET 6.0.6, while SDK version 6.0.300 includes .NET 6.0.5.

    Watch the for a complete walk-through of all the steps.

    The upgrade path between Umbraco 9 and Umbraco 10 can be done directly by upgrading your project using NuGet. You will need to ensure the packages you are using are available in Umbraco 10.

    SQL CE is no longer a supported database engine

    There is no official migration path from SQL CE to another database engine.

    The following options may suit your needs:

    8.latest to 9

    There is no direct upgrade path from Umbraco 8 to Umbraco 9. It is however possible to migrate from Umbraco 8 sites to Umbraco 9 sites.

    You can reuse your content by restoring your Umbraco 8 database into a new database used for an Umbraco 9 site.

    You need to ensure the packages you are using are available in Umbraco 9, and you will need to reimplement your custom code and templates.

    The direct upgrade path is not possible because the codebase has been fundamentally updated in Umbraco 9. The underlying web framework has been updated from ASP.NET to ASP.NET Core.

    It is not possible to take this step while maintaining full compatibility with Umbraco 8.

    8.0.0 to 8.1.0

    There are a few breaking changes from 8.0.x to 8.1.0. Make sure to check the .

    IPublishedContent breaking changes in 8.1.0

    Due to the there are a few steps you will need to take, to make sure that your site works.

    The IPublishedContent interface is central to Umbraco, as it represents published content and media items at the rendering layer level. This could be in controllers or views. In other words, it is the interface that is used everywhere when building sites.

    The introduction of multilingual support in version 8 required changes to the interface. For instance, a property value could be obtained with GetPropertyValue(alias) in version 7. Version 8 requires a new parameter for culture, and the call thus became

    7.latest to 8.0.0

    There is no direct upgrade path from Umbraco 7 to Umbraco 8. It is however possible to migrate content from Umbraco 7 sites to Umbraco 8 sites. We have added content migrations in Umbraco 8.1.0 enabling you to migrate your content from Umbraco 7 to Umbraco 8.

    It is not possible to upgrade an Umbraco 7 site to Umbraco 8 because the codebase has been fundamentally updated in Umbraco 8. A lot of outdated code and technology has been removed and instead new, faster, and more secure technology has been implemented.

    In Umbraco 8 we have added improvements and updated dependencies. We have also done a thorough clean-up to make it simpler for you to work with and extend your Umbraco project.

    7.6.3 to 7.7.0

    Version 7.7.0 introduces User Groups, better user management, and security facilities. This means that anything to do with "User Types" no longer exists including APIs that work with User Types. If your code or any package's code refers to "User Type" APIs, you need to make changes to your code. In many cases, we've added backward compatibility for these scenarios and obsoleted APIs that should no longer be used.

    We are now by default using the e-mail address and not the username for the credentials. When trying to login to the backoffice you need to use the e-mail address as opposed to the username. If you do an upgrade from an older version and would like to keep using the username, change the <usernameIsEmail>true</usernameIsEmail> setting to false.

    For a full list of breaking changes see:

    Version 7.7.2 no longer ships with the CookComputing.XmlRpcV2 assembly. If you reference this assembly or have a package that requires this assembly, you need to copy it back into your website.

    7.6.0 to 7.6.3

    In short:

    In Umbraco version 7.6.2 we made a mistake in the Property Value Converts (PVCs). This was corrected 2 days later in version 7.6.3. If you were having problems with querying the following Data Types on the frontend, make sure to upgrade to 7.6.3:

    • Multi Node Tree Picker

    • Related Links

    7.4.0 to 7.6.0

    Find a list of all the breaking changes below and

    The three most important things to note are:

    1. In web.config do not change useLegacyEncoding to false if it is currently set to true - changing the password encoding will cause you not being able to log in any more.

    7.3.0 to 7.4.0

    For manual upgrades:

    • Copy the new folder ~/App_Plugins/ModelsBuilder into the site

    • Do not forget to merge ~/Config/trees.config and ~/Config/Dashboard.config

    7.2.0 to 7.3.0

    Make sure to manually clear your cookies after updating all the files, otherwise you might an error relating to Umbraco.Core.Security.UmbracoBackOfficeIdentity.AddUserDataClaims(). The error looks like: Value cannot be null. Parameter name: value.

    NuGet will do the following for you. If you're upgrading manually make sure to also:

    • Delete bin/Microsoft.Web.Helpers.dll

    7.1.0 to 7.2.0
    • Copy in the /Views/Partials/Grid (contains Grid rendering views).

    Follow the to complete the upgrade.

    7.0.2 to 7.1.0
    • Remove the /Install folder.

    Follow the to complete the upgrade.

    7.0.1 to 7.0.2
    • There was an update to the /umbraco/config/create/ui.xml which needs to be manually updated. The original element had this text:

    • The usercontrol value has changed to: /create/user.ascx

    7.0.0 to 7.0.1
    • Remove all uGoLive dlls from /bin

      • These are not compatible with V7

    6.latest to 7

    Read and follow

    4.latest to 6
    • If your site was ever a version between 4.10.0 and 4.11.4 and you have upgraded to 6.0.0 install the and run it after the upgrade process is finished.

    • The DocType Mixins package is not compatible with v6+ and will cause problems in your Document Types.

    Version 4

    Version 4.10.x to 4.11.x

    • If your site was ever a version between 4.10.0 and 4.11.4 install the and run it after the upgrade process is finished.

    Version 4.8.0 to 4.10.0

    • Delete the

    If a time zone is detected and it is not already UTC, database queries will update all system dates previously stored as server time to UTC.

    There is configuration available to customize this migration.

    Adding the following configuration setting will disable the migration from running.

    You can also explicitly define the time zone for your server. If this is provided as the standard English name of the time zone, it will be used over the detected one.

    Progress of the migration is written to the Umbraco log file.

    For more details on this update see the following PRs: #19705, #19798, and #20112.

    InMemoryAuto models builder and Razor runtime compilation have moved into their own package

    The InMemoryAuto models builder and the Umbraco feature that uses Razor runtime compilation (Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation) have been moved to a separate package: Umbraco.Cms.DevelopmentMode.Backoffice.

    Why was this change made?

    Razor runtime compilation is obsolete in .NET and prevents Hot Reload from working. Since InMemoryAuto depends on Razor runtime compilation, keeping it in the core would prevent Hot Reload from working.

    By moving InMemoryAuto to its own package, Umbraco can enable Hot Reload by default for a better development experience.

    When you need to reference Umbraco.Cms.DevelopmentMode.Backoffice?

    Add the package if any of the following apply:

    1. You use InMemoryAuto models builder

      • Explicitly selecting InMemoryAuto

      • Starting a new project with the default --models-mode (default is InMemoryAuto, so the package is added automatically)

    2. You rely on Razor runtime compilation to edit templates via the backoffice.

    3. You use the RoslynCompiler class (you'll also need to update your namespace usings).

    When you do not need the package?

    You don’t need to reference it if you use Models Builder in a source-code mode, such as:

    • AppData

    • SourceCodeAuto

    • SourceCodeManual

    These modes do not rely on Razor runtime compilation. However, ensure the following settings are removed from your .csproj file:

    Additional notes

    If you use the ModelsMode enum or its extension methods, use the string constants in Constants.ModelsBuilder.ModelsModes instead.

    For more details on this update, see PR #20187.

    Date Picker Property Editor Kind

    The existing date picker that returns a DateTime object has been updated to provide one with a Kind of Unspecified. Previously, it was UTc, but this was incorrect because Umbraco cannot determine the intended use of a particular date picker. This update makes that explicit.

    For more details on this update see the following PR: #19727.

    Color Picker Property Editor

    The color picker property editor used for the built-in approved color Data Type will now always make available a PickedColor object. Previously, this was only output when labels were configured on the Data Type. Without labels the previous behavior was to expose a string.

    For more details on this update see the following PR: #19430.

    Segmented Content Fallback

    The Template and Delivery API output for segmented properties will perform an explicit fallback to the default segment, if they do not have a value.

    In earlier versions, if you created a segmented version of a document, you had to complete every property. This made segments an editorial burden unless the behavior was customized. With the new behavior, segmented content now only needs to have the properties that require a segmented value completed.

    For more details on this update see the following PR: #20309.

    Removal of Extension Methods

    Extension and public helper methods, unused in Umbraco and obsolete in previous versions, have been removed.

    These are:

    • GetAssemblyFile

    • ToSingleItemCollection

    • GenerateDataTable, CreateTableData, AddRowData, ChildrenAsTable, ChildrenAsTable all related to DataTable

    • RetryUntilSuccessOrTimeout

    • RetryUntilSuccessOrMaxAttempts

    • HasFlagAny

    • Deconstruct

    • AsEnumerable, ContainsKey and GetValue extending NameValueCollection

    • DisposeIfDisposable

    • SafeCast

    • ToDictionary on object

    • SanitizeThreadCulture

    For more details on this update see the following PR: #17051.

    Tiptap external extensions package

    The import namespace @umbraco-cms/backoffice/external/tiptap has been removed, replaced with @umbraco-cms/backoffice/tiptap.

    This means backoffice extension code must be updated from:

    To:

    For more details on this update see the following PR: #20256.

    Client-side user related entities

    The following components have been moved from user to current-user and exported.

    • UmbCurrentUserAllowMfaActionCondition

    • UmbCurrentUserConfigRepository

    • UmbCurrentUserConfigStore

    • UMB_CURRENT_USER_CONFIG_STORE_CONTEXT

    They should now be imported from @umbraco-cms/backoffice/current-user.

    For more details on this update see the following PR: #20125.

    URL provider updates

    URL providers are now responsible for generating content preview URLs. To achieve this, the IUrlProvider interface has been extended with the GetPreviewUrlAsync() method.

    The IUrlProvider interface must also provide a unique system-wide Alias.

    Lastly, the UrlInfo class has been revamped to support this setup.

    For more details on this update see the following PR: #20021.

    See also this announcement: #27.

    HTTPS is enabled by default

    The default value of the UseHttps configuration in Global Settings has been changed from false to true.

    If you need to run Umbraco without HTTPS, make sure to update appsettings.json accordingly.

    Authentication for the backoffice client

    Following the draft Request for Comments (RFC) from the Internet Engineering Task Force (IETF), the backoffice client authentication has been changed to tighten security.

    This change affects only the backoffice client authentication against the Management API. API user authentication against the Management API remains unaffected, as does the Delivery API.

    This change might affect custom backoffice extensions that interact with the Management API. All fetch requests to the Management API must include credentials by declaring credentials: 'include'.

    By default, backoffice extensions built using the HQ package starter template are not affected.

    For more details on this update, see the following PRs: #20779 and #20820.

    Updated dependencies

    As is usual for a major upgrade, Umbraco’s dependencies have been updated to their latest compatible versions.

    NPoco was updated by a major version from 5.7.1 to 6.1.0. There were some changes to Umbraco code necessary after this update, so customer projects or packages that use NPoco directly may also require some changes.

    Swashbuckle was updated to a new major version 10.0.1. If you are using this library to provide a Swagger document in your package or project, changes around namespaces, nullability, and types will be encountered.

    The other specific dependency updates made for Umbraco 17 for server and client-side libraries can be found in these PRs:

    • #20385

    • #20184

    • #20925

    Other breaking changes

    The full details of breaking changes can be found from this list of labelled PRs.

    TableExists
    can be recompiled without change. But if built against 15 and run on 16, a "method missing" exception will be thrown. For more details on the feature and the changes implemented, see the
    .

    Examine is now registered via a composer

    A new abstraction and implementation for search is being worked on in an external package. To support this, a method has been implemented to disable the default Examine-based search in Umbraco. This has required moving the Examine component registration to a composer.

    There is no effect on the default search experience in Umbraco, but it may affect search customizations. As Examine is now registered in a composer, any custom code registered the same way is not guaranteed to run after the core setup. You should ensure to use a [ComposeAfter(typeof(Umbraco.Cms.Infrastructure.Examine.AddExamineComposer))] attribute to make sure custom code runs after Umbraco's default setup of Examine.

    Read more in the article on custom indexing and see PR #18988 for reference.

    Updated dependencies

    As is usual for a major upgrade, the dependencies Umbraco takes have been updated to their latest, compatible versions. This had little impact on the code of Umbraco itself, so we don't expect this to affect upgraded customer projects.

    The specific dependency updates made for Umbraco 16 can be found in these PRs: for server-side and client-side libraries.

    Other breaking changes

    Other than the above, breaking changes are minimal in Umbraco 16. On the server side, changes are limited to removing already obsolete constructors and methods.

    Client-side there are a few things to look out for if you've built extensions to the backoffice:

    • When consuming contexts, an undefined response will be resolved when the context can't be provided or the host is disconnected. See PR 19113 for more information.

    • Similarly, consuming a context as a promise can result in a promise rejection and getting a context can result in an undefined response. See PR 18611 for more information.

    • When making calls to retrieve data from the server, if you used either of Umbraco's helper methods tryExecute or tryExecuteAndNotify, then you need to adjust your code slightly. tryExecuteAndNotify is obsolete, and tryExecute takes the 'host' as the first argument. See for more information.

    • The urls property is no longer populated on the document and media detail response models. This was removed to alleviate performance concerns. Dedicated repositories and management API endpoints exist for retrieving URLs for documents and media. See and .

    The full details of breaking changes can be found from this list of labelled PRs.

    interface, which has been removed. This means that the models need to be rebuilt. The approach to this will differ depending on the mode chosen:

    InMemoryAuto

    Remove the umbraco\Data\TEMP\InMemoryAuto folder to trigger a rebuild of the models.

    SourceCodeAuto and SourceCodeManual

    Remove the old models located in the \umbraco\models folder by default. This will cause your views to no longer be able to build due to missing types. To get around this you can disable the precompiled view temporarily by adding the following to your .csproj file:

    This will allow your site to start up, but you will still see an error page when loading a page.

    1. Disregard the error.

    2. Enter the backoffice.

    3. Rebuild the models from the ModelsBuilder dashboard.

    You can now re-enable precompiled views and rebuild your site.

    If you have custom C# code that references the models this will also not build. You can either comment out your custom code temporarily until the models have been rebuilt or fix the models manually. To fix the models manually you need to find and replace IPublishedSnapshotAccessor with IPublishedContentTypeCache.

    Handling Precompressed Files

    When upgrading from Umbraco 14 to 15, you might notice that JavaScript and CSS files are automatically precompressed, adding additional .br and .gz files. This behavior is introduced in ASP.NET Core version 9, where static files are fingerprinted and precompressed by default at build and publish time.

    To disable this feature, set <CompressionEnabled>false</CompressionEnabled> in your project file. If you are using Umbraco's templates - dotnet new umbraco, this setting is already included.

    Set <CompressionEnabled>false</CompressionEnabled> in your Umbraco project to avoid compressing backoffice files unnecessarily. For your own web project, set it to true to improve performance by serving precompressed assets to users.

    For more details, see the ASP.NET Core Documentation.

    umb-button
    is now called
    uui-button
    , and
    umb-box
    is now
    uui-box
    . When extending the Backoffice, we encourage you to use our
    to ensure the same look and feel in your extensions. The UI Library is Open Source and
    , so feel free to contribute with new components or raise issues or discussions.
    • Icons are based on Lucide.

    Umbraco 13 and earlier used sets of icons ranging from custom SVGs to Font Awesome. This has all been converged into the Lucide icon pack with icon names mapped from Umbraco 13.

    • Custom icons

    To add custom icons to the Backoffice, you must add an extension type called “icons”, which can provide icons given a Name and a File. The file can reside anywhere on disk or in RCLs the only requirements being that it must be routable and it must be an SVG.

    • User provided translations

    Translations used in the UI (which are most of them) have been migrated from XML to JavaScript modules. This means that if you wish to override any of the built-in translation keys for the UI, you have to add an extension type called “localization”. It is still possible to add XML translations, but they can no longer be used in the Backoffice UI. However, you may still find usage for them in server-to-server scenarios. Umbraco also keeps its e-mail templates as XML translations. Package and extension developers working with localization will find many benefits from this change seeing that you can add logic to JavaScript modules making your localization files more dynamic and even making them able to react to input parameters.

    You can read more about localization on the Umbraco Documentation.

    • BackOffice controllers have been replaced with the Management API

    Following the implementation of the new Backoffice (Bellissima), Umbraco has now internally upgraded Headless to a first-class citizen. This means that all controllers previously available under the /umbraco/api route have been removed and replaced with controllers in the Management API. You can read more about the Management API on the Management API article. You can also check out the Swagger UI in your local Umbraco instance available under /umbraco/swagger.

    • A new way of writing authorized controllers

    If you have implemented API controllers in Umbraco before, we recommend you update or rewrite these. Follow the Documenting your Controllers article, as you’ll then ensure the same cool documentation of your APIs. Notice, that we’ve made a much better separation of concern between controllers and services so that there is no more business logic in controllers.

    • Migration from Newtonsoft.Json to the System.Text.Json which removes Nested Content and Grid value converter and so on

    Although this sounds like it's not a big change, it’s one of the most breaking changes on the backend. Whereas Newtonsoft.Json was flexible and error-tolerant by default, System.Text.Json is strict but more secure by default. You can therefore run into things that will not be serialized. You can read more about the differences between Newtonsoft.Json and System.Text.Json here.

    • Nested Content and Grid Layout have been removed

    These two property editors have been deprecated in Umbraco for some time as you can read in our breaking change announcements for Nested Content and Grid Layout. The recommended action is to use blocks instead - Block Grid for the grid layout and either Block Grid or Block List for Nested Content.

    • The legacy media picker has been removed

    We have for some time encouraged to not use the legacy Media Picker, and now it’s fully removed. You should use the default Media Picker instead.

    • Macros and Partial View Macros have been removed. Use partial views and/or blocks in the Rich Text Editor (RTE)

    Depending on the usage of macros, you’ll be able to use either partial views or blocks in the Rich Text Editor. They are not the same kind of functionality, but they cover all the identified use cases in a way more consistent and supportable way.

    • XPath has been removed

    An alternative is using the Dynamic Roots in the Multinode Treepicker and for ContentXPath the alternative is IContentLastChanceFinder.

    • The package manifest format has changed

    The package.manifest file is no longer supported and has been replaced with the umbraco-package.json file. The format is similar and after building your Umbraco solution, you have access to a JSON schema file which you can reference and thereby have type-safety in the file. You can read more about the new format on the Package Manifest article.

    • Smidge is no longer a default dependency

    Smidge has been removed from the default installation along with the RuntimeMinification setting and related classes. Smidge used to bundle up Backoffice and package assets before, however, with the Bellissima, we have migrated entirely to ESModules. This means we can no longer predict how modules work in automated bundles.

    It's recommended that you bundle up your Backoffice static assets for instance by a tool called Vite. You can read more about this on the Vite Package Setup article. You can still use libraries like Smidge for frontend static assets by manually installing the package from NuGet.

    You can read the Smidge documentation on how to set up a similar setting to RuntimeMinification. For sites being upgraded from V13 or below, remove these two lines from the _ViewImports.cshtml file.

    • Base classes for Backoffice controllers have been removed

    The UmbracoAuthorizedApiController and UmbracoAuthorizedJsonController classes have been removed. We recommend basing your Backoffice APIs on the ManagementApiControllerBase class from the Umbraco.Cms.Api.Management project.

    Read the Creating a Backoffice API article for a comprehensive guide to writing APIs for the Management API.

    • Removal of certain AppSettings

    Some AppSettings have been removed or found a new place. In general, any UI-related app settings will now have to be configured as extensions through the manifest system.

    • RichTextEditor

    The global configuration of TinyMCE has been removed in order to support more rich text editors in the future. Instead, a new extension type called “tinyMcePlugin” has been added. This extension type gives you access to each instance of TinyMCE allowing you to configure it exactly as you see fit. You can even make it dependent on more factors such as Document Type, user group, environment, and much more. You have access to the full array of contexts in the Backoffice.

    • ShowDeprecatedPropertyEditors

    There are no deprecated property editors in Bellissima and this configuration will no longer have an effect.

    • HideBackOfficeLogo

    This configuration will no longer have an effect. Instead, you can add a CSS file where you can modify the default CSS variables in the Backoffice. The Backoffice loads a CSS file which can be overwritten by placing a similar file in your project at /umbraco/backoffice/css/user-defined.css with the following content:

    • IconsPath

    This configuration will no longer have an effect. Instead, you should add icons through the “icons” extension type.

    • AllowedMediaHosts

    This configuration will no longer have an effect.

    • Notifications

    Notifications have changed their behavior to an extent. You can still implement notifications such as ContentSavingNotification to react to changes for related systems or add messages to be shown in the Backoffice. You can no longer modify the models being transferred through the API.

    If you wish to modify the Backoffice UI, register the extensions through the manifest system that hook on to the desired areas of the Backoffice UI. If you used to modify the models because you needed more data on the models, it's recommended that you build your own API controller to achieve this. You can read more about building custom API controllers on the Umbraco Documentation and even learn how to register your controllers in the Swagger UI.

    • Property editors have been split in two

    The new Backoffice and the Management API ushers in a shift in responsibility. Traditionally, a lot of UI responsibility has been misplaced on the server.

    For example, it is hardly a server concern how many rows a text area should span by default.

    To this end, property editors have been split into two, individually reusable parts; the server implementation and the client implementation.

    This change will likely impact custom Property Editors. See the Migrate custom Property Editors to Umbraco version 14 and later article for details.

    • Property value converters for package.manifest based property editors

    The package.manifest file format is no longer known on the server side. It has been changed to be a purely client-side responsibility (and it has adopted a new format and a new name). If you have implemented a property value converter for a property editor defined in a package.manifest file, you will likely need to make a small change to the property value converter.

    The property value converter must implement IsConverter() to determine if it can handle a given property. In this implementation, it is common to use the EditorAlias of the passed in IPublishedPropertyType. However, in Umbraco 14 you should use the EditorUiAlias instead.

    More details can be found in this article.

    • UmbracoApiController breakage

    Due to the shift from Newtonsoft.Json to the System.Text.Json, the UmbracoApiController will yield camel-cased output in Umbraco 14, where it was pascal-cased in the previous versions.

    Make sure to perform thorough testing of all usages of UmbracoApiController. As the class has now been marked as obsolete, we recommend these controllers to be based on the Controller class from ASP.NET Core moving forward.

    • Two-Factor Authentication requires a client registration

    The C# models for Two-Factor Authentication previously supported setting a custom AngularJS view to setup the QR code. This has been moved to the Backoffice client and requires a registration through the new extension type mfaLoginProvider:

    This will use Umbraco’s default configuration of the two-factor provider. The user scans a QR code using an app such as Google Authenticator or Authy by Twilio.

    It is additionally possible to register your own configurator similar to Umbraco 13. You can achieve this by providing a custom JavaScript element through the elementJs property.

    More details and code examples can be found in the Two-Factor Authentication article.

    • External Login Providers require a client registration

    The C# models for External Login Providers have changed and no longer hold configuration options for the “Sign in with XYZ” button. To show a button in the Backoffice to sign in with an external provider, you need to register this through the extension type called authProvider :

    This will use Umbraco’s default button to sign in with the provider. You can also choose to provide your own element to show in the login form. You can achieve this by adding the elementJs property.

    Additionally, on the backend side, there is an additional helper available to do proper error handling. You can utilize this by using the options pattern to configure the provider.

    More details and code examples can be found in the External Login Providers article.

    • Deprecated SQLite provider name removed

    In previous versions of Umbraco the umbracoDbDSN_ProviderName (and umbracoCommerceDbDSN_ProviderName) value could be Microsoft.Data.SQLite or Microsoft.Data.Sqlite with the former being deprecated in Umbraco 12.

    The deprecated version, Microsoft.Data.SQlite, has been removed and will require the value to be updated to Microsoft.Data.Sqlite for installations using an SQLite database.

    • Webhook payload property casing has changed

    Following changes to serialization, property names in the payload now use camelCase instead of PascalCase. For example, the 'CreateDate' property is now 'createDate'.

    In-depth and further breaking changes for Umbraco 14 can be found on the CMS GitHub repository and on Our Website.

    RC 4
    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    RC 3

    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    RC 2

    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    RC 1 First RC release - 17th of April. Breaking changes since Beta 3:

    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    Beta 2

    There are a few breaking changes since Beta 1. Most of the changes concern property editors and getting them to work with migrations as well as new values.

    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    Beta 1 Official release of Beta, 6th March 2023.

    • Bellissima (frontend/backoffice) changes

    • Backend (CMS) changes

    V13: New login screen
  • Updated NuGet Dependencies

  • Fix `JsonNetSerializer` settings leaking into derived implementations

  • Add default property value converters for all value types

  • V13: Add config to limit concurrent logins

  • Updates and support for re-use of CMS logic in Deploy

  • Don't explicitly index nested property by default

  • Blocks in the Rich Text Editor

  • Fix FurthestAncestorOrSelfDynamicRootQueryStep and FurthestDescendantOrSelfDynamicRootQueryStep

  • Remove parameter value/return nullability in `IImageSourceParser`, `ILocalLinkParser` and `IMacroParser`

  • Update PackageMigrationsPlans collection to be Weighted and not Lazy

  • Move IContextCache parameter to base Deploy interfaces and add checksum to artifact dependency

  • V13: Update IWebHookService to proper casing

  • V13: Implement webhook as i entity

  • Change `WebhookEventCollectionBuilder` to set collection

  • V13: Log webhook firing exceptions when they happen

  • Remove date header from webhook request and use constants

  • You can find more information about all breaking changes for v13.0.0 on Our Umbraco website.

    Note: You need to be aware of some things if you are using EF Core, and have installed the Microsoft.EntityFrameworkCore.Design 8.0.0 package:

    • This package has a transient dependency to Microsoft.CodeAnalysis.Common which clashes with the same transient dependency from Umbraco.Cms 13.0.0. This happens because Microsoft.EntityFrameworkCore.Design 8.0.0 requires Microsoft.CodeAnalysis.CSharp.Workspaces in v4.5.0 or higher.

    • If there are no other dependencies that need that package then it installs it in the lowest allowed version (4.5.0). That package then has a strict dependency on Microsoft.CodeAnalysis.Common version 4.5.0. The problem is Umbraco.Cms through its own transient dependencies that require the version of Microsoft.CodeAnalysis.Common to be >= 4.8.0.

    • This can be fixed by installing Microsoft.CodeAnalysis.CSharp.Workspaces version 4.8.0 as a specific package instead of leaving it as a transient dependency. This is because it will then have a strict transient dependency on Microsoft.CodeAnalysis.Common version 4.8.0, which is the same that Umbraco has.

    Umbraco.Cms.Infrastructure.Migrations.PostMigrations.ClearCsrfCookies is removed. The functionality can be archived by implementing a notification handler for the new UmbracoPlanExecutedNotification.

  • Umbraco.Cms.Core.Cache.DistributedCacheBinder is now divided into separate files for each notification handler

  • Umbraco.Cms.Infrastructure.Migrations.PostMigrations.DeleteLogViewerQueryFile was a no-op method removed.

  • Umbraco.Cms.Infrastructure.Migrations.PostMigrations.RebuildPublishedSnapshot replaced with a RebuildCache flag on the MigrationBase

  • A member that is visible outside of the assembly is missing in the compared assembly when required to be present.

    • Umbraco.Cms.Core.Migrations.IMigrationPlanExecutor.Execute(Umbraco.Cms.Infrastructure.Migrations.MigrationPlan,System.String) replaced with Umbraco.Cms.Core.Migrations.IMigrationPlanExecutor.ExecutePlan(Umbraco.Cms.Infrastructure.* * Migrations.MigrationPlan,System.String) that returns an rich object instead of a string

    • Umbraco.Cms.Infrastructure.Migrations.IMigrationContext.AddPostMigration``1 Removed and replaced with notification

    • Umbraco.Cms.Infrastructure.Migrations.MigrationPlan.AddPostMigration``1

    • Removed and replaced with notification

    • Umbraco.Cms.Infrastructure.Migrations.MigrationPlan.get_PostMigrationTypes removed.

    • Umbraco.Cms.Infrastructure.Migrations.Upgrade.Upgrader.Execute(Umbraco.Cms.Core.Migrations.IMigrationPlanExecutor,Umbraco.Cms.Core.Scoping.IScopeProvider,Umbraco.Cms.Core.Services.IKeyValueService) was obsolete and is replaced by method taking a ICoreScopeProvider instead of a IScopeProvider

    An abstract member was added to the right side of the comparison to an unsealed type.

    • PublishedPropertyBase now requires inheritors to implement GetDeliveryApiValue(System.Boolean,System.String,System.String)

    A member was added to an interface without a default implementation.

    • Umbraco.Cms.Core.Events.IEventAggregator.Publish2(System.Collections.Generic.IEnumerable{0})

    • Umbraco.Cms.Core.Events.IEventAggregator.PublishAsync2(System.Collections.Generic.IEnumerable{0},System.Threading.CancellationToken)

    • Umbraco.Cms.Core.Models.PublishedContent.IPublishedProperty.GetDeliveryApiValue(System.Boolean,System.String,System.String)

    • Umbraco.Cms.Core.Models.PublishedContent.IPublishedPropertyType.ConvertInterToDeliveryApiObject(Umbraco.Cms.Core.Models.PublishedContent.IPublishedElement,Umbraco.Cms.Core.PropertyEditors.PropertyCacheLevel,System.Object,System.Boolean,System.Boolean)

    • Umbraco.Cms.Core.Models.PublishedContent.IPublishedPropertyType.ConvertInterToDeliveryApiObject(Umbraco.Cms.Core.Models.PublishedContent.IPublishedElement,Umbraco.Cms.Core.PropertyEditors.PropertyCacheLevel,System.Object,System.Boolean)

    • Umbraco.Cms.Core.Models.PublishedContent.IPublishedPropertyType.DeliveryApiCacheLevel

    • Umbraco.Cms.Core.Scoping.ICoreScope.Locks

    • Umbraco.Cms.Core.Migrations.IMigrationPlanExecutor.ExecutePlan(Umbraco.Cms.Infrastructure.Migrations.MigrationPlan,System.String)

    • Umbraco.Cms.Infrastructure.Search.IUmbracoIndexingHandler.RemoveProtectedContent

    • Umbraco.Cms.Infrastructure.Examine.IUmbracoIndex.SupportProtectedContent

    .

    The full list of API-breaking changes can be found below.

    Obsolete code removed

    The following have been removed after having been obsoleted since Umbraco 9.

    Umbraco.Extensions

    Umbraco.Cms.Core

    Umbraco.Cms.Infrastructure

    Umbraco.Cms.Web

    Umbraco.Cms.Tests

    Code moved to new assemblies and namespaces

    The following have been moved to new assemblies and their namespaces have been updated accordingly.

    Umbraco.Extensions

    Umbraco.Cms.Web

    Umbraco.Cms.Infrastructure

    New interface methods

    A few interfaces have been merged, adding new members to the original interfaces.

    Umbraco.Cms.Core

    No-Operation methods removed

    A method not doing anything for the last couple of major releases have been removed.

    Umbraco.Cms.Core

    Changes due to models made immutable

    A single model have been made immutable, so the default constructor and the setters are not available anymore.

    Umbraco.Cms.Infrastructure

    Classes that does not inherit from base type anymore

    The following classes now directly inherit from OEmbedProviderBase instead of EmbedProviderBase.

    Umbraco.Cms.Core

    Use IContentService.GetContentScheduleByContentId && IContentService.PersistContentSchedule or the optional contentSchedule parameter on IContentService.Save instead.

    Removed redundant event handling code

    • Removed public methods: PublishedSnapshotServiceEventHandler.Dispose, PublishedSnapshotServiceEventHandler.Dispose(bool), and .PublishedSnapshotServiceEventHandler.Initialize.

    • Removed public ctor.

    Scope provider cleanup

    • Some public classes in the Cms.Core.Services namespace have moved assembly from Umbraco.Cms.Infrastructure to Umbraco.Cms.Core.

    • These same public classes have changed namespace from Umbraco.Cms.Core.Services.Implement to Umbraco.Cms.Core.Services.

    Update to NPoco5

    NPoco types and interfaces are part of our public interface which means that this upgrade imposes breaking changes.

    SQLite support

    • Removed support for Microsoft SQL Server Compact (SQL CE).

    • Removed ReadLock and WriteLock methods from ISqlSyntaxProvider interface. Use IDistributedLockingMechanism (or IScope which delegates to IDistributedLockingMechanism) instead.

    • Constants for SQL Server provider name moved+consolidated from Core.Constants.DatabaseProviders and Core.Constants.-DbProviderNames to Umbraco.Cms.Persistence.SqlServer.Constants

    • Some SQL Server related services moved from the Umbraco.Infrastructure project to the new Umbraco.Cms.Persistence.

    • SqlServer project with altered namespaces e.g. SqlServerSyntaxProvider, SqlServerBulkSqlInsertProvider, SqlServerDatabaseCreator.

    Added the following methods/properties to ISqlSyntaxProvider. These must be implemented in any downstream implementation e.g:

    • ISqlSyntaxProvider.HandleCreateTable(IDatabase,TableDefinition,Boolean)

    • ISqlSyntaxProvider.GetFieldNameForUpdate()

    • ISqlSyntaxProvider.GetColumn(DatabaseType,String,String,String,String,Boolean)

    • ISqlSyntaxProvider.InsertForUpdateHint(Sql)

    • ISqlSyntaxProvider.AppendForUpdateHint(Sql)

    • ISqlSyntaxProvider.LeftJoinWithNestedJoin(Sql,Func<Sql,Sql>,String)

    Update to ImageSharp v2

    Update dependency versions:

    • SixLabors.ImageSharp from 1.0.4 to 2.1.1

    • SixLabors.ImageSharp.Web from 1.0.5 to 2.0.0

    Renamed the CachedNameLength property to CacheHashLength on ImagingCacheSettings.

    Moved ImageSharpImageUrlGenerator from project Umbraco.Infrastructure to Umbraco.Web.Common and updated the corresponding namespace and DI registration (from AddCoreInitialServices() to AddUmbracoImageSharp());

    Moved ImageSharp configuration from the AddUmbracoImageSharp() extension method into separate IConfigureOptions<> implementations:

    • The middleware is configured in ConfigureImageSharpMiddlewareOptions (which also replaces ImageSharpConfigurationOptions that previously only set the default ImageSharp configuration);

    • The default physical cache is configured in ConfigurePhysicalFileSystemCacheOptions.

    Migrate Member properties to columns on the Member table

    This is breaking because it is no longer possible to access the properties listed below through the IMember.Properties collection. You must now access them through their specific properties that is IMember.IsLockedOut.

    • umbracoMemberFailedPasswordAttempts

    • umbracoMemberApproved

    • umbracoMemberLockedOut

    • umbracoMemberLastLockoutDate

    • umbracoMemberLastLogin

    • umbracoMemberLastPasswordChangeDate

    Additionally, when previously you resolved a Member as published content, all the default properties would be there twice. For instance, IsLockedOut would be there both as a property with the alias umbracoMemberLockedOut and with the alias IsLockedOut. Now it'll only be there once, with the alias being the name of the property, so IsLockedOut in this instance.

    Lastly the nullable dates on a user, i.e. LastLoginLate will now be null instead of DateTime.MinValue when getting a user with the UserService.

    Update examine to version 3

    Examine 3 breaking changes:

    • ValueSet immutable.

    • ValueSetValidationResult is renamed to ValueSetValidationStatus and ValueSetValidationResult is now a type.

    Async support for content finders

    Has changed to:

    Improve redirect Content finder scalability

    • Added more methods to IRedirectUrlRepository and IRedirectUrlService.cs.

    Fix Block List settings exception and optimize PVCs

    • Added a new method on IPublishedModelFactory: Type GetModelType(string? alias);

    • The generic types of a BlockListItem<TContent, TSettings>instance in theBlockListModelreturned byBlockListPropertyValueConverteris now determined by calling this new method, which can be different and cause aModelBindingException` in your views.

    Async tree search

    Has changed to:

    Moved StackQueue to correct namespace

    StackQueue has been moved from Umbraco.Core.Collections to the Umbraco.Cms.Core.Collections namespace.

    Globalsetting SqlWriteLockTimeOut has been removed

    This setting has been superseded by DistributedLockingWriteLockDefaultTimeout.

    GlobalSetting UmbracoPath cannot be configured

    It is no longer possible to rename the /Umbraco folder path using configuration. The property still exists but is hardcoded to /Umbraco and will be removed in Umbraco 12, planned for release in June 2023.

    file to avoid issues when running the project

    Update code using Angular JS

    Angular JS has been removed in Umbraco 14. If you have extended your Umbraco project using Angular JS, it must be updated. for more information read the Customize Backoffice documentation.

    Deprecated property editors

    Nested Content and Grid Layout have been removed. We recommend rebuilding it using Block Grid for the grid layout and either Block Grid or Block List for Nested Content.

    The legacy Media Picker has been removed, use the default Media Picker.

    Macros and partial views macros removed

    Macros and partial views macros have been removed in Umbraco 14. We recommend using partial views or blocks in the Rich Text Editor (RTE).

    For more information on what has changed in Umbraco 14 read the Breaking changes in Umbraco 14.

    Block Editor data format has changes

    In Umbraco 15, the internal data format for Block Editors has changed. This causes a content migration to run when upgrading.

    This content migration can take a while to complete on a large site, causing it to be unresponsive for the duration. To speed up the migration, it is advised to clean up old content versions before upgrading.

    While we don't recommend this, it might be possible for you to skip the content migration. More details can be found in the Migrate content to Umbraco 15 article.

    • Follow a community guide to migrate from a SQL CE database to SQL Server, like the article by Jan Reilink

    • Setup a new database for v10 and use uSync to transfer document types and content across.

    • Setup a new database for v10 and use a premium tool such as redgate SQL Data Compare to copy database contents across.

    • Setup a new database for v10 and use a premium tool such as Umbraco Deploy to transfer document types and content across.

    Steps to upgrade using Visual Studio

    It's recommended that you upgrade the site offline, and test the upgrade fully before deploying it to the production environment.

    1. Stop your site in IIS to prevent any changes being made to the database or filesystem while you are upgrading.

    2. Open your Umbraco 9 project in Visual Studio.

    3. Right-click on the project name in the Solution Explorer and select Properties.

    4. Select .NET 6.0 from the Target Framework drop-down.

    5. Go to Tools > NuGet Package Manager > Manage NuGet Packages for Solution...

    6. Go to the Installed tab in the NuGet Package manager.

    7. Choose Umbraco.Cms.

    8. Select 10.0.0 from the Version drop-down and click Install to upgrade your project to version 10.

    9. Update Program.cs to the following:

    1. Remove the following files and folders:

      • /wwwroot/umbraco

      • /umbraco/PartialViewMacros

      • /umbraco/UmbracoBackOffice

      • /umbraco/UmbracoInstall

      • /umbraco/UmbracoWebsite

      • /umbraco/config/lang

      • /umbraco/config/appsettings-schema.json

    2. If using Umbraco Forms, update your files and folders according to the for version 10 article.

    3. Restart your site in IIS, build and run your project to finish the installation of Umbraco 10.

    To re-enable the appsettings IntelliSense, you must update your schema reference in the appsettings.json file and any other appsettings.{Environment}.json files from:

    To:

    To upgrade to Umbraco 10, your database needs to be at least on Umbraco 8.18.

    Upgrade of any publicly hosted environment

    When the upgrade is completed and tested, and prior to deploying to any publicly accessible environment, you should consider the following:

    1. Ensure you have backups for both the database and the file system.

    2. Stop the site so it is not accessible during the upgrade process.

    3. Delete the relevant folders from the filesystem prior to deploying:

      • /wwwroot/umbraco

      • /umbraco/PartialViewMacros

      • /umbraco/UmbracoBackOffice

      • /umbraco/UmbracoInstall

      • /umbraco/UmbracoWebsite

      • /umbraco/config/lang

      • /umbraco/config/appsettings-schema.json

    4. If you are using Umbraco Forms, update your files and folders according to the for version 10 article.

    5. Deploy the site how you normally would to your public facing environment.

    6. Start the site. At this point it will launch and upgrade the database, after which the site should become accessible and your upgrade is complete.

    7. Check the logs for any errors which may have occurred during the upgrade process.

    Value(alias, culture)
    .

    In the excitement of the version 8 release, we assumed that IPublishedContent was "done". By our tests, everything was looking good. However, feedback from early testers showed that the interface was in some places odd or inconsistent or had issues.

    Fixing the bugs is a requirement. Some of the required bug fixes could not be achieved without introducing some breaking changes.

    At that point, we decided to give IPublishedContent some love. We fixed the bugs and made it clean, friendly, discoverable, and predictable for the entire life of version 8.

    Breaking changes to such a central interface is not something we take lightly. Even though they do not impact the "concepts" nor require heavy refactoring, they may demand an amount of small fixes here and there.

    The general idea underlying these changes is that:

    • The proper way to retrieve "something" from an IPublishedContent instance is always through a method, for example: Children(). And, when that method can be multilingual, the method accepts a culture parameter, which can be left null to get the "current" culture value.

    • To reduce the amount of breaking changes, and to simplify things for non-multilingual sites, existing properties such as document.Name and document.Children (and others) still exist, and return the value for the current culture. In other words, these properties are now implemented as document.Name => document.Name() or document.Children => document.Children().

    The rest of this document presents each change in details.

    More interfaces

    It was possible to mock and test the IPublishedContent interface in version 7. It has been improved in version 8, but it still relies on concrete PublishedContentType and PublishedPropertyType classes to represent the content types, which complicates things.

    In version 8.1, these two classes are abstracted as IPublishedContentType and IPublishedPropertyType, thus making IPublishedContent easier to mock and test.

    CHANGE: This impacts every method accepting or returning a content type. For instance, the signature of most IPropertyValueConverter methods changes. References to PublishedContentType must be replaced with references to IPublishedContentType.

    The following IPublishedContent members change:

    Name

    The document.Name property is complemented by the document.Name(string culture = null) extension method. The property returns the name for the current culture. The document.GetCulture(...).Name syntax is removed.

    CHANGE: Calls to document.GetCulture(culture).Name must be replaced with document.Name(culture).

    UrlSegment

    The document.UrlSegment property is complemented by the document.UrlSegment(string culture = null) extension method. The property returns the Url segment for the current culture. The document.GetCulture(...).UrlSegment syntax is removed.

    CHANGE: Calls to document.GetCulture(culture).UrlSegment must be replaced with document.UrlSegment(culture).

    Culture

    The document.GetCulture() method is removed. The proper way to get a culture date is document.CultureDate(string culture = null). The document.Cultures property now returns the invariant culture, for invariant documents.

    CHANGE: Calls to document.GetCulture(culture).Date must be replaced with document.CultureDate(culture). Calls to document.Cultures must take into account the invariant culture.

    Children

    The document.Children property is complemented by the document.Children(string culture = null) extension method which, when a culture is specified always return children available for the specified culture. The property returns the children available for the current culture.

    A new document.ChildrenForAllCultures property is introduced, which returns all children, regardless of whether they are available for a culture or not.

    CHANGE: Calls to document.Children may have to be replaced by document.ChildrenForAllCultures depending on if the 8.0.x usage of this was relying on it returning unfiltered/all children regardless of the current routed culture.

    Url

    The document.Url property is complemented by the document.Url(string culture = null, UrlMode mode = UrlMode.Auto) extension method. The document.GetUrl(...) and document.UrlAbsolute() methods are removed. The UrlProviderMode enumeration is renamed UrlMode.

    CHANGE: Calls to document.GetUrl(...) must be replaced with document.Url(...). Calls to document.UrlAbsolute() must be replaced with document.Url(mode: UrlMode.Absolute).

    UmbracoContext

    Due to the UrlProviderMode enumeration being renamed UrlMode, the signature of some overloads of the Url(...) method has changed. Methods that do not have a mode parameter remain unchanged.

    CHANGE: Code such as context.Url(1234, UrlProviderMode.Absolute) must become context.Url(1234, UrlMode.Absolute).

    The UmbracoContext class gives access to the rendering layer, which is more than a "cache". To reflect this, its ContentCache and MediaCache properties are renamed Content and Media. However, the old properties remain as obsolete properties.

    CHANGE: None required in 8.1, but code such as context.ContentCache.GetById(1234) should eventually be converted to context.Content.GetById(1234) as the obsolete properties may be removed in a further release.

    GetCulture

    Version 7 had a document.GetCulture() method that was deriving a culture from domains configured in the tree. Somehow, that method was lost during version 8 development (issue #5269).

    Because that method is useful, especially when building traditional, non-multilingual sites, it has been re-introduced in version 8.1 as document.GetCultureFromDomains().

    CHANGE: None.

    DomainHelper

    DomainHelper has been replaced with a static DomainUtilities class.

    CHANGE: It is rare that DomainHelper is used in code since it only contains one public method but if developers are using this, it can no longer be injected since it's now a static class called DomainUtilities.

    Models Builder

    If you're using ModelsBuilder in dll mode you need to delete the dlls before upgrading. Otherwise, they're going to be wrong and cause your whole site to throw errors.

    If you're using ModelsBuilder in AppData mode and you have your generated models in your solution you need to update them after upgrading. PublishedContentType will need to be replaced with IPublishedContentType. If you have an implementation of the PropertyValueConverter class, you need to replace all references to PublishedPropertyType with IPublishedPropertyType within that class. Only after you do that will your solution build again.

    AutoMapper

    Umbraco 8.1 replaces AutoMapper with UmbracoMapper. This in itself will not break anything on your site. If you have used AutoMapper in your own code you will have to either include the package yourself or switch your implementation to use UmbracoMapper.

    Follow the upgrade guide for Umbraco 8 to complete the upgrade

    This version also ships with far fewer client files that were only relevant for older versions of Umbraco (i.e. < 7.0.0). There might be some packages that were referencing these old client files. If you see missing image references you may need to contact the vendor of the package in question to update their references.

    Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    Member Picker

    Depending on whether you tried to fix the problem with those, you will need to fix them after you upgrade to 7.6.3.

    Property Value Converters (PVC)

    Umbraco stores data for Data Types in different ways. For a lot of pickers it will store 1072 or 1083,1283. These numbers refer to the identifier of the item in Umbraco. In the past, when building your templates, you would manually have to take that value and find the content item it belongs to. Then you would be able to get the data you wanted from there. An example of that is shown below:

    In Umbraco 7.6.0, this is what you would do instead:

    This is possible using Models Builder and through the inclusion of core property value converters, a package by community member Jeavon Leopold.

    To not break everybody's sites (the results of queries are different when PVCs are enabled), we disabled these PVCs by default.

    Umbraco 7.6.0 also came with new pickers that store their data as a UDI (Umbraco Identifier). We wanted to simplify the use of these new pickers and by default we wanted PVC's to always be enabled for those pickers.

    We noticed that some new pickers also got their PVC's disabled when the configuration setting was set to false (<EnablePropertyValueConverters>false</EnablePropertyValueConverters>).

    To make everything consistent, we made sure that the UDI pickers would always use PVC's in 7.6.2, this however reversed the behavior. So when PVC's were enabled, the property would not be converted and when PVC's were disabled, the property would be converted after all. This is the exact opposite behavior of 7.6.2.

    So we have fixed this now in 7.6.3.

    This issue only affects:

    • Multi Node Tree Picker

    • Related Links

    • Member Picker

    Have you already upgraded to 7.6.2 and fixed queries for those three Data Types? Then you have to do that again in version 7.6.3.

    Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    In umbracoSettings.config leave EnablePropertyValueConverters set to false - this will help your existing content queries to still work.

  • In tinyMceConfig.config make sure to remove <plugin loadOnFrontend="true">umbracolink</plugin> so that the rich text editor works as it should.

  • Breaking Changes

    Dependencies

    UrlRewriting.Net (U4-9004)

    UrlRewriting was old, leaking memory, and slowing down website startup when dealing with more than a few rules. It's entirely replaced by the IIS Url Rewrite extension.

    Json.Net (U4-9499)

    Json.Net has been updated to version 10.0.0 to benefit from improvements in features, fixes, and performances (see release notes). This might be a breaking change for people relying on one of the changed functionality.

    Log4net (U4-1324)

    Umbraco has used a custom build of an old (1.2.11) version of log4net that supported Medium Trust. However, Umbraco itself does not support Medium Trust anymore, and therefore log4net has been upgraded to the standard, latest build of log4net 2.0.8.

    ImageProcessor (U4-8963)

    An optional parameter has been added to the GetCropUrl method in order to support the background color parameter. This breaks the method signature and therefore might require a recompile of user's code.

    HtmlAgilityPack (U4-9655)

    The HtmlAgilityPack has been upgraded to version 1.4.9.5. The Umbraco upgrade process should take care of setting up the binding redirects appropriately.

    Core

    Membership Provider Encoding (U4-6566)

    The Membership Provider useLegacyEncoding setting is now false by default, as the legacy password encoding has weaknesses.

    This change only impacts new installs (no change for upgrades).

    Property Value Converters (U4-7318)

    A large amount of property value converters contributed by the community have been merged in and are now the default value converters. These converters change the object types returned by GetPropertyValue for more convenient types.

    Instead of returning comma-separated string values like it did before, the SliderValueConverter now returns a decimal or a Range<decimal> value that can be used directly in views.

    This change only impacts new installs (no change for upgrades).

    The new property value converters are controlled by an umbracoSettings.config setting. In the section settings/content, setting EnablePropertyValueConverters needs to be present and true to activate them.

    Database (U4-9201)

    Umbraco has been using a PetaPoco-managed UmbracoDatabase instance since version 7 came out. We realized that some of our legacy code still bypassed that mechanism and used parallel, out-of-band database connections, causing issues with transactions.

    The legacy code has been refactored to rely on the UmbracoDatabase instance. However, because that database is disposed of during EndRequest, the code that ran after it has been disposed may not work anymore. This should then be updated to use either an HttpModule event that occurs before EndRequest or the new UmbracoModule.EndRequest event.

    More details are available on issue 146 on the 301 Redirect Tracker GitHub issue tracker.

    Scopes (U4-9406)

    Version 7.6 introduces the notion of scopes, which allow for wrapping multiple service-level operations in one single transaction. The scopes API is partially public. Scopes are not meant for public use at this stage and we need a few more releases to ensure that the APIs are stable.

    Scopes should not change how Umbraco functions.

    Introducing scopes means that some public APIs signatures are changing. Most of these changes target internal and/or non-breaking APIs (as per our guidelines). This should therefore have no impact on sites but may break unit tests.

    Property Editors storing UDI instead of ID (U4-9310)

    The property editors for pickers for content, media, members, and related links have been updated to store UDI instead of the node ID. Pickers in sites being upgraded have been marked as obsolete but will continue to work as they always did.

    New sites will have the obsolete pickers filtered out from the list of available property editors, but they can be enabled by a configuration flag.

    Rich Text Editor (RTE) Images attributes (U4-6228, U4-6595)

    For a long time, we had a rel attribute on an <img> tag when inserted into the RTE. This is invalid HTML markup. We worked around this by stripping this attribute using a Property Editor Value converter. Some developers relied on this attribute so we didn't change it to a "data-id" attribute which would have been valid. In 7.6 we are not storing integer IDs in these attributes. Instead of storing UDI values so with this change we no longer use rel or data-id and instead there will be a "data-udi" attribute. This change should affect only a small amount of people that were previously relying on the values from the "rel" attribute.

    Others

    We are shipping with SignalR in the core at version 2.2.1. If you already have SignalR installed into your app and are using an older version there may be conflicts.

    The creation and editing of WebForms templates will no longer be supported as for version 7.6.0.

    Upgrading via NuGet

    This is an important one and there was no perfect solution to this. We have removed the UrlRewriting dependency and no longer ship with it. However, if you are using it we didn't want to have NuGet delete all of your rewrites. The good news is that if you are using it, the NuGet upgrade will not delete your rewrite file and everything should continue to work.

    However, if you are not using it, you will get an error after upgrading. Here's how to fix it:

    Since you aren't using UrlRewriting you will have probably never edited the UrlRewriting file. In this case, NuGet will detect that and remove it. However you will need to manually remove these UrlRewriting references from your web.config:

    and

    Remove the following httpModules from your web.config:

    and

    Forms

    Umbraco Forms 6.0.0 has been released to be compatible with Umbraco 7.6. It is a new major version release of Forms primarily due to the strict dependency on 7.6+. If you are using Forms, you will need to update it to version 6.0.0

    There are important Forms upgrade documentation that you will need to read..

    Courier

    Umbraco Courier 3.1.0 has been released to be compatible with Umbraco 7.6. If you are using Courier, you will need to update it to version 3.1.0.

    Follow the upgrade guide for Umbraco 7 to complete the upgrade

    - they contain new and updated entries that are required to be there
    • If you forget trees.config you will either not be able to browse the Developer section or you will be logged out immediately when trying to go to the developer section

  • You may experience an error saying Invalid object name 'umbracoUser' - this can be fixed by clearing your cookies on localhost

  • Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    Delete bin/Microsoft.Web.Mvc.FixedDisplayModes.dll

  • Delete bin/System.Net.Http.dll

  • Delete bin/System.Net.Http.*.dll (all dll files starting with System.Net.Http) except for System.Net.Http.Formatting.dll

  • Delete bin/umbraco.XmlSerializers.dll

  • Add this in the appSetting section of your web.config file: <add key="owin:appStartup" value="UmbracoDefaultOwinStartup" />

  • Other considerations:

    • WebApi has been updated, normally you don’t have to do anything unless you have custom webapi configuration:

      • See this article if you are using WebApiConfig.Register: https://www.asp.net/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2

      • You need to update your web.config file to have the correct WebApi version references - this should be done by doing a compare/merge of your ~/web.config file with the ~/web.config file in the release

    • MVC has been updated to MVC5

      • You need to update your web.config file to have the correct MVC version references - this should be done by doing a compare/merge of your ~/web.config file with the ~/web.config file in the release

      • The upgrader will take care of updating all other web.config’s (in all other folders, for example, the Views and

    • It is not required that you merge the changes for the Examine index paths in the ExamineIndex.config file. However, if you do, your indexes will be rebuilt on startup because Examine will detect that they don’t exist at the new location.

    • It's highly recommended to clear the browser cache - the ClientDependency version is automatically bumped during installation which should force the browser cache to refresh, however in some edge cases this might not be enough.

    Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    . This is a required change otherwise creating a new user will not work.
  • There is a breaking change to be aware of, full details can be found here.

  • Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    Move appSettings/connectionStrings back to web.config

    • If you are on 7.0.0 you should migrate these settings into the web.config instead of having them in separate files in /config/

    • The keys in config/AppSettings.config need to be moved back to the web.config <appSettings> section and similarly, the config/ConnectionStrings.config holds the Umbraco database connections in v7.0.0 and they should be moved back to the web.config <connectionStrings> section.

    • /config/AppSettings.config and /config/ConnectionString.config can be removed after the contents have been moved back to web.config.

  • Delete all files in ~/App_Data/TEMP/Razor/

    • Related to issues with razor macros

  • Follow the upgrade guide for Umbraco 7 to complete the upgrade.

    bin/umbraco.linq.core.dll
    file
  • Copy the new files and folders from the zip file into your site's folder

    • /App_Plugins

    • /Views

    • Global.asax

  • Remove the Config/formHandlers.config file

  • Version 4.7.2 to 4.8.0

    • Delete the bin/App_Browsers.dll file

    • Delete the bin/App_global.asax.dll file

    • Delete the bin/Fizzler.Systems.HtmlAgilityPack.dll file

    • For people using uComponents 3.1.2 or below, 4.8.0 breaks support for it. Either upgrade to a newer version beforehand or follow the workaround

    Version 4.7.1.1 to 4.7.2

    • Delete the bin/umbraco.MacroEngines.Legacy.dll file

    Version 4.6.1 to 4.7.1.1

    • Delete bin/Iron*.dll (all dll files starting with "Iron")

    • Delete bin/RazorEngine*.dll (all dll files starting with "RazorEngine")

    • Delete bin/umbraco.MacroEngines.Legacy.dll

    • Delete bin/Microsoft.Scripting.Debugging.dll

    • Delete bin/Microsoft.Dynamic.dll

    change of license
    Blog Post
    AngularJS removed: A new backoffice built with Web Components, Lit, and fueled by the Umbraco UI Library
    customize the Backoffice
    Bellissima (frontend/backoffice) changes
    Backend (CMS) changes
    Bellissima (frontend/backoffice) changes
    Backend (CMS) changes
    Use ISO codes instead of language IDs for fallback languages and translations
    Breaking changes for the Delivery API
    Microsoft
    Rich Text Editor documentation
    version 4 to 5
    version 5 to 6
    Update 'diff' from 3.5.0 to 5.0.0
    Content Schedule performance
    Our Umbraco
    Upgrading your project from Umbraco 9 to 10
    Long-term Support (LTS) major
    'Upgrading from Umbraco 9 to Umbraco 10 video tutorial'
    full list
    changes in IPublishedContent
    Migrate your content to Umbraco 8
    the list on the issue tracker
    a list of the items is also available on the tracker
    upgrade guide for Umbraco 7
    upgrade guide for Umbraco 7
    the full v7 upgrade guide
    fixup package
    fixup package
    PR
    Umbraco UI Library
    hosted on GitHub
    Umbraco Announcements repository
      "Umbraco": {
        "CMS": {
          "SystemDateMigration": {
            "Enabled": false
          }
        }
      }
      "Umbraco": {
        "CMS": {
          "SystemDateMigration": {
            "LocalServerTimeZone": "Eastern Standard Time"
          }
        }
      }
    {
        ...
        "ConnectionStrings": {
            "umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
            "umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite",
            "umbracoCommerceDbDSN": "Data Source=|DataDirectory|/Umbraco.Commerce.sqlite.db;Mode=ReadWrite;Foreign Keys=True;Pooling=True;Cache=Shared",
            
    
    import { Editor } from '@umbraco-cms/backoffice/external/tiptap';
    import { Editor } from '@umbraco-cms/backoffice/tiptap';
        {
          "type": "mfaLoginProvider",
          "alias": "my.2fa.provider",
          "name": "My 2fa Provider",
          "forProviderName": "UmbracoUserAppAuthenticator",
          "meta": {
            "label":
    
       {
          "type": "authProvider",
          "alias": "My.AuthProvider.Google",
          "name": "Google Auth Provider",
          "forProviderName": "Umbraco.Google",
          "meta": {
            "label":
    
    :root {
      --umb-header-logo-display: none;
    }
    <RazorCompileOnBuild>false</RazorCompileOnBuild>
    <RazorCompileOnPublish>false</RazorCompileOnPublish>
    <PropertyGroup>
      <RazorCompileOnBuild>false</RazorCompileOnBuild>
      <RazorCompileOnPublish>false</RazorCompileOnPublish>
    </PropertyGroup>
    @addTagHelper *, Smidge
    @inject Smidge.SmidgeHelper SmidgeHelper
    <nodeType alias="users">
        <header>User</header>
        <usercontrol>/create/simple.ascx</usercontrol>
        <tasks>
        <create assembly="umbraco" type="userTasks" />
        <delete assembly="umbraco" type="userTasks" />
        </tasks>
    </nodeType>
    Umbraco.Extensions.ServiceCollectionExtensions.AddUnique<TImplementing>(Microsoft.Extensions.DependencyInjection.IServiceCollection)
    
    Umbraco.Extensions.EnumExtensions.HasFlagAll<T>(T, T)
    
    Umbraco.Extensions.FriendlyImageCropperTemplateExtensions.GetLocalCropUrl(Umbraco.Cms.Core.Models.MediaWithCrops, string, string?)
    Umbraco.Cms.Core.Constants.Conventions.Member.IsApproved
    Umbraco.Cms.Core.Constants.Conventions.Member.IsApprovedLabel
    Umbraco.Cms.Core.Constants.Conventions.Member.IsLockedOut
    Umbraco.Cms.Core.Constants.Conventions.Member.IsLockedOutLabel
    Umbraco.Cms.Core.Constants.Conventions.Member.LastLoginDate
    Umbraco.Cms.Core.Constants.Conventions.Member.LastLoginDateLabel
    Umbraco.Cms.Core.Constants.Conventions.Member.LastPasswordChangeDate
    Umbraco.Cms.Core.Constants.Conventions.Member.LastPasswordChangeDateLabel
    Umbraco.Cms.Core.Constants.Conventions.Member.LastLockoutDate
    Umbraco.Cms.Core.Constants.Conventions.Member.LastLockoutDateLabel
    Umbraco.Cms.Core.Constants.Conventions.Member.FailedPasswordAttempts
    Umbraco.Cms.Core.Constants.Conventions.Member.FailedPasswordAttemptsLabel
    
    Umbraco.Cms.Core.WebAssets.IRuntimeMinifier.Reset()
    
    Umbraco.Cms.Core.Services.IExternalLoginService
    
    Umbraco.Cms.Core.Services.ExternalLoginService.ExternalLoginService(
        Umbraco.Cms.Core.Scoping.ICoreScopeProvider,
        Microsoft.Extensions.Logging.ILoggerFactory,
        Umbraco.Cms.Core.Events.IEventMessagesFactory,
        Umbraco.Cms.Core.Persistence.Repositories.IExternalLoginRepository)
    
    Umbraco.Cms.Core.Services.ExternalLoginService.GetExternalLogins(int)
    
    Umbraco.Cms.Core.Services.ExternalLoginService.GetExternalLoginTokens(int)
    
    Umbraco.Cms.Core.Services.ExternalLoginService.Save(int,
        System.Collections.Generic.IEnumerable<Umbraco.Cms.Core.Security.IExternalLogin>)
    
    Umbraco.Cms.Core.Services.ExternalLoginService.Save(int,
        System.Collections.Generic.IEnumerable<Umbraco.Cms.Core.Security.IExternalLoginToken>)
    
    Umbraco.Cms.Core.Services.ExternalLoginService.DeleteUserLogins(int)
    
    Umbraco.Cms.Core.Services.IMacroWithAliasService
    
    Umbraco.Cms.Core.Services.ITwoFactorLoginService2
    
    Umbraco.Cms.Core.Services.LocalizedTextService.LocalizedTextService(
        System.Collections.Generic.IDictionary<System.Globalization.CultureInfo, System.Collections.Generic.IDictionary<string, System.Collections.Generic.IDictionary<string, string>>>,
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Core.Services.LocalizedTextService>)
    
    Umbraco.Cms.Core.Services.ServiceContext.ServiceContext(
        System.Lazy<Umbraco.Cms.Core.Services.IPublicAccessService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IDomainService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IAuditService>?,
        System.Lazy<Umbraco.Cms.Core.Services.ILocalizedTextService>?,
        System.Lazy<Umbraco.Cms.Core.Services.ITagService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IContentService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IUserService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMemberService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMediaService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IContentTypeService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMediaTypeService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IDataTypeService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IFileService>?,
        System.Lazy<Umbraco.Cms.Core.Services.ILocalizationService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IPackagingService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IServerRegistrationService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IEntityService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IRelationService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMacroService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMemberTypeService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IMemberGroupService>?,
        System.Lazy<Umbraco.Cms.Core.Services.INotificationService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IExternalLoginService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IRedirectUrlService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IConsentService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IKeyValueService>?,
        System.Lazy<Umbraco.Cms.Core.Services.IContentTypeBaseServiceProvider>?)
    
    Umbraco.Cms.Core.Services.ServiceContext.CreatePartial(
        Umbraco.Cms.Core.Services.IContentService?,
        Umbraco.Cms.Core.Services.IMediaService?,
        Umbraco.Cms.Core.Services.IContentTypeService?,
        Umbraco.Cms.Core.Services.IMediaTypeService?,
        Umbraco.Cms.Core.Services.IDataTypeService?,
        Umbraco.Cms.Core.Services.IFileService?,
        Umbraco.Cms.Core.Services.ILocalizationService?,
        Umbraco.Cms.Core.Services.IPackagingService?,
        Umbraco.Cms.Core.Services.IEntityService?,
        Umbraco.Cms.Core.Services.IRelationService?,
        Umbraco.Cms.Core.Services.IMemberGroupService?,
        Umbraco.Cms.Core.Services.IMemberTypeService?,
        Umbraco.Cms.Core.Services.IMemberService?,
        Umbraco.Cms.Core.Services.IUserService?,
        Umbraco.Cms.Core.Services.ITagService?,
        Umbraco.Cms.Core.Services.INotificationService?,
        Umbraco.Cms.Core.Services.ILocalizedTextService?,
        Umbraco.Cms.Core.Services.IAuditService?,
        Umbraco.Cms.Core.Services.IDomainService?,
        Umbraco.Cms.Core.Services.IMacroService?,
        Umbraco.Cms.Core.Services.IPublicAccessService?,
        Umbraco.Cms.Core.Services.IExternalLoginService?,
        Umbraco.Cms.Core.Services.IServerRegistrationService?,
        Umbraco.Cms.Core.Services.IRedirectUrlService?,
        Umbraco.Cms.Core.Services.IConsentService?,
        Umbraco.Cms.Core.Services.IKeyValueService?,
        Umbraco.Cms.Core.Services.IContentTypeBaseServiceProvider?)
    
    Umbraco.Cms.Core.Services.TwoFactorLoginService.TwoFactorLoginService(
        Umbraco.Cms.Core.Persistence.Repositories.ITwoFactorLoginRepository,
        Umbraco.Cms.Core.Scoping.ICoreScopeProvider,
        System.Collections.Generic.IEnumerable<Umbraco.Cms.Core.Security.ITwoFactorProvider>,
        Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Identity.IdentityOptions>,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Security.BackOfficeIdentityOptions>)
    
    Umbraco.Cms.Core.Routing.DefaultUrlProvider.DefaultUrlProvider(
        Microsoft.Extensions.Options.IOptionsMonitor<Umbraco.Cms.Core.Configuration.Models.RequestHandlerSettings>,
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Core.Routing.DefaultUrlProvider>,
        Umbraco.Cms.Core.Routing.ISiteDomainMapper,
        Umbraco.Cms.Core.Web.IUmbracoContextAccessor,
        Umbraco.Cms.Core.Routing.UriUtility)
    
    Umbraco.Cms.Core.Persistence.Repositories.IExternalLoginRepository
    
    Umbraco.Cms.Core.Persistence.Repositories.IMacroWithAliasRepository
    
    Umbraco.Cms.Core.Persistence.Repositories.IMemberRepository.SetLastLogin(string, System.DateTime)
    
    Umbraco.Cms.Core.Notifications.UmbracoApplicationComponentsInstallingNotification
    
    Umbraco.Cms.Core.Notifications.UmbracoApplicationMainDomAcquiredNotification
    
    
    Umbraco.Cms.Core.Notifications.UmbracoApplicationStartingNotification.UmbracoApplicationStartingNotification(Umbraco.Cms.Core.RuntimeLevel)
    
    Umbraco.Cms.Core.Notifications.UmbracoApplicationStoppingNotification.UmbracoApplicationStoppingNotification()
    
    Umbraco.Cms.Core.Models.IContentTypeWithHistoryCleanup
    
    Umbraco.Cms.Core.Models.Language.Language(Umbraco.Cms.Core.Configuration.Models.GlobalSettings, string)
    
    Umbraco.Cms.Core.Models.RelationType.RelationType(string, string, bool, System.Nullable<System.Guid>, System.Nullable<System.Guid>)
    
    Umbraco.Cms.Core.Models.PublishedContent.PublishedContentType.PublishedContentType(int, string,
        Umbraco.Cms.Core.Models.PublishedContent.PublishedItemType,
        System.Collections.Generic.IEnumerable<string>,
        System.Collections.Generic.IEnumerable<Umbraco.Cms.Core.Models.PublishedContent.PublishedPropertyType>,
        Umbraco.Cms.Core.Models.ContentVariation,
        bool)
    
    Umbraco.Cms.Core.Models.PublishedContent.PublishedContentType.PublishedContentType(int, string,
        Umbraco.Cms.Core.Models.PublishedContent.PublishedItemType, System.Collections.Generic.IEnumerable<string>,
        System.Func<Umbraco.Cms.Core.Models.PublishedContent.IPublishedContentType,
        System.Collections.Generic.IEnumerable<Umbraco.Cms.Core.Models.PublishedContent.IPublishedPropertyType>>,
        Umbraco.Cms.Core.Models.ContentVariation,
        bool)
    
    Umbraco.Cms.Core.Models.Mapping.ContentTypeMapDefinition.ContentTypeMapDefinition(
        Umbraco.Cms.Core.Models.Mapping.CommonMapper,
        Umbraco.Cms.Core.PropertyEditors.PropertyEditorCollection,
        Umbraco.Cms.Core.Services.IDataTypeService,
        Umbraco.Cms.Core.Services.IFileService,
        Umbraco.Cms.Core.Services.IContentTypeService,
        Umbraco.Cms.Core.Services.IMediaTypeService,
        Umbraco.Cms.Core.Services.IMemberTypeService,
        Microsoft.Extensions.Logging.ILoggerFactory,
        Umbraco.Cms.Core.Strings.IShortStringHelper,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Configuration.Models.GlobalSettings>,
        Umbraco.Cms.Core.Hosting.IHostingEnvironment)
    
    Umbraco.Cms.Core.Models.ContentEditing.UserGroupPermissionsSave.Validate(System.ComponentModel.DataAnnotations.ValidationContext)
    
    Umbraco.Cms.Core.Install.InstallSteps.TelemetryIdentifierStep.TelemetryIdentifierStep(
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Core.Install.InstallSteps.TelemetryIdentifierStep>,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Configuration.Models.GlobalSettings>,
        Umbraco.Cms.Core.Configuration.IConfigManipulator)
    
    Umbraco.Cms.Core.IO.ViewHelper.ViewHelper(Umbraco.Cms.Core.IO.IFileSystem)
    
    Umbraco.Cms.Core.HealthChecks.Checks.Security.BaseHttpHeaderCheck.BaseHttpHeaderCheck(
        Umbraco.Cms.Core.Hosting.IHostingEnvironment,
        Umbraco.Cms.Core.Services.ILocalizedTextService,
        string,
        string,
        string,
        bool)
    
    Umbraco.Cms.Core.DependencyInjection.UmbracoBuilderExtensions.AddOEmbedProvider<T>(Umbraco.Cms.Core.DependencyInjection.IUmbracoBuilder)
    
    Umbraco.Cms.Core.DependencyInjection.UmbracoBuilderExtensions.OEmbedProviders(Umbraco.Cms.Core.DependencyInjection.IUmbracoBuilder)
    
    Umbraco.Cms.Core.Configuration.Models.RequestHandlerSettings.CharCollection.get
    Umbraco.Cms.Core.Configuration.Models.RequestHandlerSettings.CharCollection.set
    
    Umbraco.Cms.Core.Composing.IUserComposer
    
    Umbraco.Cms.Core.Security.BackOfficeUserStore.BackOfficeUserStore(
        Umbraco.Cms.Core.Scoping.ICoreScopeProvider,
        Umbraco.Cms.Core.Services.IUserService,
        Umbraco.Cms.Core.Services.IEntityService,
        Umbraco.Cms.Core.Services.IExternalLoginService,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Configuration.Models.GlobalSettings>,
        Umbraco.Cms.Core.Mapping.IUmbracoMapper,
        Umbraco.Cms.Core.Security.BackOfficeErrorDescriber,
        Umbraco.Cms.Core.Cache.AppCaches)
    
    Umbraco.Cms.Core.Security.MemberUserStore.MemberUserStore(
        Umbraco.Cms.Core.Services.IMemberService,
        Umbraco.Cms.Core.Mapping.IUmbracoMapper,
        Umbraco.Cms.Core.Scoping.ICoreScopeProvider,
        Microsoft.AspNetCore.Identity.IdentityErrorDescriber,
        Umbraco.Cms.Core.PublishedCache.IPublishedSnapshotAccessor,
        Umbraco.Cms.Core.Services.IExternalLoginService)
    
    Umbraco.Cms.Core.Logging.Viewer.ILogViewer.GetLogLevel()
    
    Umbraco.Cms.Core.Logging.Viewer.SerilogLogViewerSourceBase.SerilogLogViewerSourceBase(
        Umbraco.Cms.Core.Logging.Viewer.ILogViewerConfig,
        Serilog.ILogger)
    
    Umbraco.Cms.Core.Logging.Viewer.SerilogLogViewerSourceBase.GetLogLevel()
    
    Umbraco.Cms.Core.Configuration.JsonConfigManipulator.JsonConfigManipulator(Microsoft.Extensions.Configuration.IConfiguration)
    Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement.MemberRepository.SetLastLogin(string, System.DateTime)
    
    Umbraco.Cms.Infrastructure.Packaging.PackageMigrationBase.PackageMigrationBase(
        Umbraco.Cms.Core.Services.IPackagingService,
        Umbraco.Cms.Core.Services.IMediaService,
        Umbraco.Cms.Core.IO.MediaFileManager,
        Umbraco.Cms.Core.PropertyEditors.MediaUrlGeneratorCollection,
        Umbraco.Cms.Core.Strings.IShortStringHelper,
        Umbraco.Cms.Core.Services.IContentTypeBaseServiceProvider,
        Umbraco.Cms.Infrastructure.Migrations.IMigrationContext)
    
    Umbraco.Cms.Infrastructure.Migrations.Install.DatabaseSchemaCreator.DatabaseSchemaCreator(
        Umbraco.Cms.Infrastructure.Persistence.IUmbracoDatabase?,
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Infrastructure.Migrations.Install.DatabaseSchemaCreator>,
        Microsoft.Extensions.Logging.ILoggerFactory,
        Umbraco.Cms.Core.Configuration.IUmbracoVersion,
        Umbraco.Cms.Core.Events.IEventAggregator)
    
    Umbraco.Cms.Infrastructure.Migrations.Install.DatabaseSchemaCreatorFactory.DatabaseSchemaCreatorFactory(
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Infrastructure.Migrations.Install.DatabaseSchemaCreator>,
        Microsoft.Extensions.Logging.ILoggerFactory,
        Umbraco.Cms.Core.Configuration.IUmbracoVersion,
        Umbraco.Cms.Core.Events.IEventAggregator)
    
    Umbraco.Cms.Infrastructure.HostedServices.RecurringHostedServiceBase.RecurringHostedServiceBase(
        System.TimeSpan,
        System.TimeSpan)
    
    Umbraco.Cms.Infrastructure.HostedServices.ReportSiteTask.ReportSiteTask(
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Infrastructure.HostedServices.ReportSiteTask>,
        Umbraco.Cms.Core.Configuration.IUmbracoVersion,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Configuration.Models.GlobalSettings>)
    Umbraco.Cms.Web.Common.Security.ConfigureIISServerOptions
    
    Umbraco.Cms.Web.Common.RuntimeMinification.SmidgeRuntimeMinifier.Reset()
    
    Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware.UmbracoRequestMiddleware(
        Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Web.Common.Middleware.UmbracoRequestMiddleware>,
        Umbraco.Cms.Core.Web.IUmbracoContextFactory,
        Umbraco.Cms.Core.Cache.IRequestCache,
        Umbraco.Cms.Core.Events.IEventAggregator,
        Umbraco.Cms.Core.Logging.IProfiler,
        Umbraco.Cms.Core.Hosting.IHostingEnvironment,
        Umbraco.Cms.Core.Routing.UmbracoRequestPaths,
        Umbraco.Cms.Infrastructure.WebAssets.BackOfficeWebAssets,
        Microsoft.Extensions.Options.IOptionsMonitor<Smidge.Options.SmidgeOptions>,
        Umbraco.Cms.Core.Services.IRuntimeState,
        Umbraco.Cms.Core.Models.PublishedContent.IVariationContextAccessor,
        Umbraco.Cms.Core.PublishedCache.IDefaultCultureAccessor)
    
    Umbraco.Cms.Web.Website.Controllers.UmbLoginController.UmbLoginController(
        Umbraco.Cms.Core.Web.IUmbracoContextAccessor,
        Umbraco.Cms.Infrastructure.Persistence.IUmbracoDatabaseFactory,
        Umbraco.Cms.Core.Services.ServiceContext,
        Umbraco.Cms.Core.Cache.AppCaches,
        Umbraco.Cms.Core.Logging.IProfilingLogger,
        Umbraco.Cms.Core.Routing.IPublishedUrlProvider,
        Umbraco.Cms.Web.Common.Security.IMemberSignInManager)
    
    Umbraco.Cms.Web.BackOffice.Trees.MemberTypeAndGroupTreeControllerBase.MemberTypeAndGroupTreeControllerBase(
        Umbraco.Cms.Core.Services.ILocalizedTextService,
        Umbraco.Cms.Core.UmbracoApiControllerTypeCollection,
        Umbraco.Cms.Core.Trees.IMenuItemCollectionFactory,
        Umbraco.Cms.Core.Events.IEventAggregator)
    
    Umbraco.Cms.Web.BackOffice.Controllers.CurrentUserController.CurrentUserController(
        Umbraco.Cms.Core.IO.MediaFileManager,
        Microsoft.Extensions.Options.IOptions<Umbraco.Cms.Core.Configuration.Models.ContentSettings>,
        Umbraco.Cms.Core.Hosting.IHostingEnvironment,
        Umbraco.Cms.Core.Media.IImageUrlGenerator,
        Umbraco.Cms.Core.Security.IBackOfficeSecurityAccessor,
        Umbraco.Cms.Core.Services.IUserService,
        Umbraco.Cms.Core.Mapping.IUmbracoMapper,
        Umbraco.Cms.Core.Security.IBackOfficeUserManager,
        Microsoft.Extensions.Logging.ILoggerFactory,
        Umbraco.Cms.Core.Services.ILocalizedTextService,
        Umbraco.Cms.Core.Cache.AppCaches,
        Umbraco.Cms.Core.Strings.IShortStringHelper,
        Umbraco.Cms.Web.Common.Security.IPasswordChanger<Umbraco.Cms.Core.Security.BackOfficeIdentityUser>)
    
    Umbraco.Cms.Web.BackOffice.Controllers.EntityController.GetUrlsByUdis(Umbraco.Cms.Core.Udi[], string?)
    
    Umbraco.Cms.Web.BackOffice.Controllers.HelpController.HelpController(Microsoft.Extensions.Logging.ILogger<Umbraco.Cms.Web.BackOffice.Controllers.HelpController>)
    
    Umbraco.Cms.Web.BackOffice.Controllers.LanguageController.LanguageController(
        Umbraco.Cms.Core.Services.ILocalizationService,
        Umbraco.Cms.Core.Mapping.IUmbracoMapper,
        Microsoft.Extensions.Options.IOptionsSnapshot<Umbraco.Cms.Core.Configuration.Models.GlobalSettings>)
    
    Umbraco.Cms.Web.BackOffice.Controllers.LogViewerController.LogViewerController(Umbraco.Cms.Core.Logging.Viewer.ILogViewer)
    Umbraco.Cms.Web.BackOffice.Controllers.LogViewerController.GetLogLevel()
    
    Umbraco.Cms.Web.BackOffice.Controllers.MediaController.GetPagedReferences(int, string, int, int)
    
    Umbraco.Cms.Web.BackOffice.Controllers.MemberTypeController.GetAllTypes()
    
    Umbraco.Cms.Web.BackOffice.Controllers.TemplateController.TemplateController(
        Umbraco.Cms.Core.Services.IFileService,
        Umbraco.Cms.Core.Mapping.IUmbracoMapper,
        Umbraco.Cms.Core.Strings.IShortStringHelper)
    Umbraco.Cms.Tests.Common.Testing.TestOptionAttributeBase.ScanAssemblies
    Umbraco.Extensions.NPocoDatabaseExtensions.ConfigureNPocoBulkExtensions()
    
    Umbraco.Extensions.UmbracoBuilderExtensions.AddUmbracoImageSharp(Umbraco.Cms.Core.DependencyInjection.IUmbracoBuilder)
    Umbraco.Cms.Web.Common.Media.ImageSharpImageUrlGenerator
    
    Umbraco.Cms.Web.Common.ImageProcessors.CropWebProcessor
    
    Umbraco.Cms.Web.Common.DependencyInjection.ConfigureImageSharpMiddlewareOptions
    Umbraco.Cms.Web.Common.DependencyInjection.ConfigurePhysicalFileSystemCacheOptions
    Umbraco.Cms.Infrastructure.Persistence.LocalDb
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.RetryPolicyFactory
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.ThrottlingMode
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.ThrottlingType
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.ThrottledResourceType
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.ThrottlingCondition
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.Strategies.NetworkConnectivityErrorDetectionStrategy
    Umbraco.Cms.Infrastructure.Persistence.FaultHandling.Strategies.SqlAzureTransientErrorDetectionStrategy
    Umbraco.Cms.Core.Services.IMacroService.GetAll(params string[])
    
    Umbraco.Cms.Core.Persistence.Repositories.IMacroRepository.GetByAlias(string)
    Umbraco.Cms.Core.Persistence.Repositories.IMacroRepository.GetAllByAlias(string[])
    
    Umbraco.Cms.Core.Services.ITwoFactorLoginService.DisableWithCodeAsync(string, System.Guid, string)
    Umbraco.Cms.Core.Services.ITwoFactorLoginService.ValidateAndSaveAsync(string, System.Guid, string, string)
    
    Umbraco.Cms.Core.Models.IContentType.HistoryCleanup
    
    Umbraco.Cms.Core.Media.IImageDimensionExtractor.SupportedImageFileTypes
    Umbraco.Cms.Core.Services.IMembershipMemberService<T>.SetLastLogin(string, System.DateTime)
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.ContentData()
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.Name.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.UrlSegment.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.VersionId.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.VersionDate.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.WriterId.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.TemplateId.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.Published.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.Properties.set
    Umbraco.Cms.Infrastructure.PublishedCache.DataSource.ContentData.CultureInfos.set
    Umbraco.Cms.Core.Media.EmbedProviders.DailyMotion
    Umbraco.Cms.Core.Media.EmbedProviders.Flickr
    Umbraco.Cms.Core.Media.EmbedProviders.GettyImages
    Umbraco.Cms.Core.Media.EmbedProviders.Giphy
    Umbraco.Cms.Core.Media.EmbedProviders.Hulu
    Umbraco.Cms.Core.Media.EmbedProviders.Issuu
    Umbraco.Cms.Core.Media.EmbedProviders.Kickstarter
    Umbraco.Cms.Core.Media.EmbedProviders.Slideshare
    Umbraco.Cms.Core.Media.EmbedProviders.Soundcloud
    Umbraco.Cms.Core.Media.EmbedProviders.Ted
    Umbraco.Cms.Core.Media.EmbedProviders.Twitter
    Umbraco.Cms.Core.Media.EmbedProviders.Vimeo
    Umbraco.Cms.Core.Media.EmbedProviders.YouTube
    bool TryFindContent(IPublishedRequestBuilder request);
    Task<bool> TryFindContent(IPublishedRequestBuilder request);
    IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom
    = null)
    Task<EntitySearchResults> SearchAsync(string query, int pageSize, long pageIndex, string? searchFrom = null);
    public class Program
    {
        public static void Main(string[] args)
            => CreateHostBuilder(args)
                .Build()
                .Run();
    
        // The calls to `ConfigureUmbracoDefaults` and `webBuilder.UseStaticWebAssets()` are new.
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureUmbracoDefaults()
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStaticWebAssets();
                    webBuilder.UseStartup<Startup>();
                });
    }
    "$schema": "./umbraco/config/appsettings-schema.json",
    "$schema": "./appsettings-schema.json",
    @{
        IPublishedContent contactPage;
        var contactPageId = Model.Content.GetPropertyValue<int>("contactPagePicker");
        if (contactPageId > 0)
        {
            contactPage = Umbraco.TypedContent(contactPageId);
        }
    }
    
    <p>
      <a href="@contactPage.Url">@contactPage.Name</a>
    </p>
    <p>
        <a href="@Model.Content.ContactPagePicker.Url">@Model.ContactPagePicker.Name</a>
    </p>
    <section name="urlrewritingnet" restartOnExternalChanges="true" requirePermission="false" type="UrlRewritingNet.Configuration.UrlRewriteSection, UrlRewritingNet.UrlRewriter" />
    <urlrewritingnet configSource="config\UrlRewriting.config" />
    <system.web>
    <httpModules>
        <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/>
        ...
    </httpModules>
    <system.web>
    <system.webServer>
        <modules>
        <remove name="UrlRewriteModule"/>
        <add name="UrlRewriteModule" type="UrlRewritingNet.Web.UrlRewriteModule, UrlRewritingNet.UrlRewriter"/>
        ...
        </modules>
    </system.webServer>
    App_Plugins
    folders) to have the correct settings
  • For general ASP.NET MVC 5 upgrade details see: https://www.asp.net/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2

  • "umbracoCommerceDbDSN_ProviderName"
    :
    "Microsoft.Data.Sqlite"
    },
    ...
    }
    "Authenticate with a 2FA code"
    }
    }
    "Google"
    ,
    "defaultView": {
    "icon": "icon-google"
    },
    "linking": {
    "allowManualLinking": true
    }
    }
    }
    PR 18939
    PR #19030
    PR 19130
    Upgrading - version specific
    Upgrading - version specific
    posted here