In this tutorial, you will learn about content migration within Umbraco v9. Content migration is the process of moving data from one environment into another one. In essence, content migration is just a fancy word for importing and exporting content within the CMS πŸ€”

When working on a CMS project, there are two main scenarios that will require you to move content between environments. On a daily basis, you will need to promote the content, document types and data types created within your development environment to your production environment. Having to manually recreate all these changes is a pain in the ass. To work efficiently with Umbraco, you need to know how to automate this process 🀯🀯🀯

The second facet of content migration will come before go-live. If a client is switching from an older CMS to Umbraco, it is highly likely that you will be asked to create some sort of magic script that maps the data between the two systems. Often these scripts can take longer to create than simply manually copying the content across, however, in certain circumstances, automating the process makes sense.

If you want to learn what options are available to you in order to deal with either of these situations, this is the tutorial for you πŸ”₯πŸ”₯πŸ”₯

How To Import And Export Content Within Umbraco 9

Within Umbraco v8 and below, you could use the package section to import and export content, document types and data types:

How To Deal With Content Migration In Umbraco 9 1

Sadly, with the move to ASP.NET 5 this capability is no longer provided by the CMS (read more here. You can no longer import a packahe.xml, which means there is no out of the box import and export feature anymore 😞. This means that you will need to rely on a community package to get the job done.


uSync is one of the most useful Umbraco community packages to have ever been written. uSync was created by a legend called Kevin Jump and the best news is that it is FREE πŸ’ΈπŸ’ΈπŸ’Έ

uSync will allow you to easily import and export content from Umbraco. uSync comes in a few flavours and when you search for the term in NuGet explorer you will see about 10-15 related packages. The versions that I have personally found the most useful are listed below:

uSync: This is the main package you need to install. The package works by serializing and de-serializing the data within the CMS and creating corresponding files on the server. These files can then be copied between environments and automatically imported. More information about this package can be found here

uSync.BackOffice: This package will allow you to configure uSync from within the Umbraco backend. More information about this package can be found here

uSync People Edition: This package will allow you to additionally Import and export content editors and members. More information about this package can be found here

uSync.Snapshots: This package will allow you to create a point in time backup of your data. This can be very useful within a disaster recovery situation if you need to roll back. More information can be found here

When installing uSync, ensure you only install the versions that are compatible with v9. Packages like uSync.ContentEdition are compatible with Umbraco v8 and below only. Installing a non-compatible package will break your website, so be warned πŸ€”

After installing uSync and uSync.BackOffice, load the backend and go to the Settings tab. On the left-hand panel, you will see a new Synchronization section. Within here you can access uSync and start importing and exporting data

How To Deal With Content Migration In Umbraco 9 3

After clicking on any of the export options, uSync will generate corresponding export files. These files will be created in this location:

usync ➑ v9

To import this data into another environment, you could add those files to source-control. uSync can be configured to automatically import content on CMS start-up. If you have a Ci/Cd pipeline that is triggered by a new commit, you can use that process to easily promote those files to a different server. The other option is to manually copy the files yourself and import them, the choice is yours πŸ’₯

uSync has several useful configuration options, however, most of them are disabled by default. To change uSync settings, you will need to add some JSON manually into appsettings.json. The config to enable uSync to automatically import content on save is shown below. Copy this into appsettings.json:

Importing Content From An Old CMS Into Umbraco

The process to do a complete content migration from one system to another will likely involve lots of custom code. I have spent a whole month writing these types of scripts before, so trust me when I say it can be tedious code to write 😞

Sharing re-useable code for content migration in a tutorial is hard, as each migration will be very custom to your website. The code you will need to write will be based on your custom document-types

My advice is to export all your old content into a csv or a bunch of JSON files first. To import these files into Umbraco, you will need to create a composer and a component. The composer will register the component to run on application start

The component is the class where you can add your custom import code. One useful tip before you start writing this code is that you should also import the ID of the old CMS during the import process. Typically whenever I am doing content modelling on a new Umbraco project, I create a base document type within Umbraco that all my pages inherit from. Within this base document, I add the shared SEO meta-data properties. This base document type is an ideal place to add a property to store the old CMS Id reference. Having this ID within Umbraco means that you can target content based on the old system Id very easily in the new world 🌎

A basic example of how to create a component that reads in data from a JSON file and imports that data into the Umbraco is shown below:

Get The Page Content: You need to write some code that will get the page content from the old CMS so it is available to access in memory within your site. In this example, I read the data from disk using System.IO.File.ReadAllText. I convert that file into a JSON object, using a NuGet package called NewtonSofts JSON.NET. As you can see on Lines 13 and 14, reading data from disk and converting it to an object is a two-liner!

A Reference To The Parent Node: In order to save your new page, you will need to provide the API with a reference to the node that you want your new page to be created underneath. You can see this code on Line 17. Using the Key property exposed by IPublishedContent, you can get access to a Guid that uniquely references the parent node.

Document Type Alias: The API requires you to specify the type of page you would like to create. This is done by passing in a document type alias. If you are using the Umbraco Models builder, you can get access to any document types alias using the ModelTypeAlias. An example of the code required to do this is seen on Line 27

Create and Save a Page: To create a new page in the CMS, you will need to create a new CMS object of type IContent and then pass that object to the CMS in order to save and publish it on your website. The code to do this can be seen on Line 24 and on Line 32. Using the IContentService you can create and publish pages within the CMS

In order for this component to be run when the CMS starts, you will need to register it. This is done using this code below:

With these two classes added to your solution, running this code should now import data from a file in your webRoot called example.json and create a page in the CMS underneath the homepage:

How To Deal With Content Migration In Umbraco 9 2

Job done πŸ’₯

You are now a Umbraco importing and exporting LEGEND ✨✨✨. No matter what the situation, you now have the tools to copy shizzle as you need. It is definitely a pain that the out-of-the-box package export is no longer a thing. The trade for moving to ASP.NET 5 within v9 meant certain things needed to change and package export was one of them. Using uSync has always been a better way to transfer content, so losing this capability is not really a disaster😊

If you find yourself needing to do a full system migration, consider if the time required to write the import/export scripts is worth the effort. In a lot of situations, telling the content editors to stop being so lazy is the better route. Happy Coding 🀘