Adventures in Content Migration
Tags: kontent, cms, contentmigration
Published: 2021-11-15 22:39:03

---
title: "Adventures in Content Migration"
published: true
description: In this article, I’m going to be looking through some of the options for content migration into Kontent
tags: kontent, cms, contentMigration
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrefho0farc1p38yr29n.jpg
---

Migration from one CMS to another gives many businesses pause for thought. You’ve invested a chunk of money in your current CMS but the time has come to modernise and move to a new platform. What adventures are you in for?

In this article, I’ll take you through the process of migrating content to a headless CMS, introduce the possibilities and explain the reasoning behind every choice that we’ve made for our client.

## Content Migration is inevitable

<figure data-asset-id="e0bffef4-cb61-4db5-b47d-ce4bc9d4ec33" data-image-id="e0bffef4-cb61-4db5-b47d-ce4bc9d4ec33">![Photo by Danique Photography on Unsplash, a hand on a dashboard](https://assets-eu-01.kc-usercontent.com:443/cddb472f-6cfe-012c-a4f1-231959d72514/9d4a3c37-b07a-46a3-8f43-25804c56bb12/danique-photography-fMfo248Bpig-unsplash.jpg)</figure>

A new platform means redevelopment which can be exciting and bring much-needed evolution and enhancement to your digital offering. But then you think about the content. You’ve built up a vast swathe of content over the years. Sure, some of it will be rewritten but you have a lot of content that needs moving. It’s a standard scenario in every re-platforming / rebuild project. Content migration is an unenviable task.

We had a client on a legacy CMS which no longer fulfilled their digital needs. They were due to move to a brand-new site powered by a headless CMS [Kontent by Kentico](https://kontent.ai/ "Kontent by Kentico"). And as they had their old CMS for a long time, as you’d expect, they had generated a lot of content in it – most of which needed to be ported through to the new site.

Obviously, they could have manually copied the content over, but they needed the site in place to hit the deadline for an annual awards competition. Missing that deadline was not an option and the manpower for manual transition wasn’t available.

## The base requirements

<figure data-asset-id="ec6337c8-6d58-41ee-8039-bb5ce385ee30" data-image-id="ec6337c8-6d58-41ee-8039-bb5ce385ee30">![Photo by David Iskander on Unsplash, a female sitting down with a handbag on her lap holding a black book with the words 'THE MISSION JOURNAL' on it](https://assets-eu-01.kc-usercontent.com:443/cddb472f-6cfe-012c-a4f1-231959d72514/3e1a07eb-6ed9-4d25-82a9-a038a7e952cf/david-iskander-GTnFf_44e7o-unsplash.jpg)</figure>

Let’s start with the brief. As manual entry was off the table, I had to figure out the best option for getting legacy content into our Kontent instance. I had the following conditions and requirements:

*   It needs to be quick and easy.
*   Full custom tooling is not an option due to limited resources available.
*   There are 1000-2000 content items per content type.
*   There are 7 or 8 content types with different structures.
*   The data are not in a nice, structured format.
*   Data are in CSV files exported from the legacy CMS.

## Where do we start?

<figure data-asset-id="14d33bf2-d463-4388-9d48-c65e04c25c6f" data-image-id="14d33bf2-d463-4388-9d48-c65e04c25c6f">![Photo by Victoriano Izquierdo on Unsplash, a bearded man looking at refrigerated drinks](https://assets-eu-01.kc-usercontent.com:443/cddb472f-6cfe-012c-a4f1-231959d72514/11da4932-3d83-4a9e-819b-f4696bc21791/victoriano-izquierdo-JG35CpZLfVs-unsplash.jpg)</figure>

First, I always consider revisiting the content within the legacy CMS. A re-platform brings the opportunity to reimagine the digital offering, streamline the content and remove any unused and unnecessary items. I would heavily advise building out your Content Strategy before building the new website, carefully constructing a flexible and future-proof content architecture, roadmap, and plan.

My first place to start was the overview page of [Kontent documentation for Importing content](https://docs.kontent.ai/tutorials/set-up-kontent/import-content/overview) that covers a lot of the considerations you would need to take on board when selecting the right import process for you. I broke down the options we had into:

*   Manual content entry by the client
*   Manual content entry by the agency
*   Using Kontent CLI
*   Using Google Sheets add-on
*   Using Management API
*   Using Migration tool built by Milan Lund

Next, I’ll explain the options and their (dis)advantages.

### Manual content entry by the client

Yep, I know this had already been ruled out but in the interests of completeness, I threw this back on the table.

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No additional resource required on the agency side.
<br />
+ Opportunity to introduce content management training early on and with real-life content.
<br />
+ We can cleanse the data as they are entered.
<br />
+ No additional development/coding required.

</td>

<td>

- Client needs to have a dedicated resource / team to make this happen.
<br />
- It’s very time intensive.
<br />
- Big risk of manual errors and inconsistency between pages due to human error.

</td>

</tr>

</tbody>

</table>

The disadvantages presented a real threat of not meeting the client’s deadline.

### Manual content entry by the agency

A similar approach to the previous one although this time we’re shifting the burden of work onto the agency.

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No additional resource required on the client side.
<br />
+ We can cleanse the data as they are entered.
<br />
+ No additional development/coding required.
<br />
+ Zero stress for client – they hand the process off to the agency.

</td>

<td>

- Agency needs to have a dedicated resource / team to make this happen.
<br />
- It’s very time intensive.
<br />
- Big risk of manual errors and inconsistency between pages due to human error.

</td>

</tr>

</tbody>

</table>

A similar set of disadvantages to the client handling the manual entry. Shifting it to the agency doesn’t necessarily solve the problem as they too have a finite number of resources and have the same time pressures. So, this was off the table as well.

### Using Kontent CLI to migrate content

Kontent has several [Migration Tools](https://docs.kontent.ai/tutorials/set-up-kontent/import-content/overview#a-migration-tools). However, not all of them support the desired import process from the legacy CMS. The first suitable candidate was the Kontent CLI, a command line tool that runs migration scripts. It supports both content types and content items as part of the migration into a Kontent project via the [Management API](https://docs.kontent.ai/reference/management-api-v2).

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No need to dedicate resource to early content management training.
<br />
+ Zero stress for client – they hand the process off to the agency.
<br />
+ Reduced risk of errors and inconsistencies between pages.
<br />
+ Code structure changes can be handled in code, which is quick.

</td>

<td>

- Agency needs to have a dedicated resource / team to make this happen.
<br />
- Need to train developers as not all of them have experience with TypeScript.
<br />
- Hard to reliably cleanse the data.
<br />
- Need to create a lot of custom code (CSV file reader, script for each content type, exceptions, etc)
<br />
- Complicated error handling during the import process with the large amount of content.

</td>

</tr>

</tbody>

</table>

Overall, there was a good chance we would have hit the deadline but my gut instinct was that this was a sledgehammer to crack a nut. It felt too heavyweight to solve the problem we had and if it went wrong, we wouldn’t be able to course-correct in time.

### Using Google Sheets add-on to migrate the content

The Google Sheets add-on ingests a few settings and then imports the content from the sheet into Kontent. If you want to read more about this, check out [this blog post by Eric Dugre](https://kontent.ai/blog/migrating-content-from-spreadsheets).

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No need to dedicate resource to early content management training.
<br />
+ Zero stress for client – they hand the process off to the agency.
<br />
+ Ideal for bulk imports.
<br />
+ Reduced risk of errors and inconsistencies between pages.
<br />
+ Code structure changes can be handled in the sheet.
<br />
+ We’re working with CSV files in Google Sheets which is feasible also for non-technical staff.
<br />
+ No additional development/coding required.
<br />
+ Possible to make mapping corrections

</td>

<td>

- Not possible to cleanse the data automatically, it needs to be done manually.
<br />
- Uncertainty over whether the approach had been battle-tested with such a large migration.
<br />
- Uncertainty over the performance.

</td>

</tr>

</tbody>

</table>

So far, so good. Yes, there were some concerns, but this approach was ticking a lot of boxes and gave us a great chance of meeting the deadline with time to spare.

### Using Management API to migrate the content

This approach would have allowed us to utilise the powerful [Management API](https://docs.kontent.ai/reference/management-api-v2) and create the content items via code. It has a similar approach to the Kontent CLI option above.

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No need to dedicate resource to early content management training.
<br />
+ Zero stress for client – they hand the process off to the agency.
<br />
+ Reduced risk of errors and inconsistencies between pages.
<br />
+ Code structure changes can be handled in code, which is quick.
<br />
+ Officially recommended approach for large imports with varying types of content
<br />
+ Workload can be distributed among developers

</td>

<td>

- Agency needs to have a dedicated resource / team to make this happen.
<br />
- Need to train developers on the Management API.
<br />
- Hard to reliably cleanse the data.
<br />
- Complicated error handling during the import process with the large amount of content.
<br />
- Uncertainty over the development time required.

</td>

</tr>

</tbody>

</table>

On paper this was the recommended approach and surely the winner. However, I was concerned about not meeting the project deadline.

Using Migration Tool built by Milan Lund

I also looked into the [Migration Tool](https://github.com/MilanLund/migration-tool) created by [Milan Lund](https://www.milanlund.com/home), where this tool allows for either a JSON or CSV option to import into the project.

<table>

<tbody>

<tr>

<td>Pros</td>

<td>Cons</td>

</tr>

<tr>

<td>

+ No need to dedicate resource to early content management training.
<br />
+ Zero stress for client – they hand the process off to the agency.
<br />
+ Ideal for bulk imports.
<br />
+ Reduced risk of errors and inconsistencies between pages.

</td>

<td>

- Agency needs to have a dedicated resource / team to make this happen.
<br />
- At the time of my investigation, the CSV import process didn’t work well.
<br />
- Unclear error log outputs.
<br />
- Hard to reliably cleanse the data.
<br />
- Complicated error handling during the import process with the large amount of content.
<br />
- Uncertainty over whether the approach had been battle-tested with such a large migration.
<br />
- Concerns over the available support.

</td>

</tr>

</tbody>

</table>

It’s a handy tool but there are multiple concerns about the performance and support.

## Making the right choice

<figure data-asset-id="51e4ebc3-8b08-4a1b-9ea3-3b671b24d97a" data-image-id="51e4ebc3-8b08-4a1b-9ea3-3b671b24d97a">![Photo by Jake Ingle on Unsplash, a man standing on top on a hill with his arms in the air, wearing a rucksack, baseball hat and shorts. ](https://assets-eu-01.kc-usercontent.com:443/cddb472f-6cfe-012c-a4f1-231959d72514/fd53176b-d145-4467-a678-411d77bd6cb1/jake-ingle-w_78KOJiih4-unsplash.jpg)</figure>

I made the decision to opt for the Google Sheets add-on. There was very little time needed to get accustomed to it and I was confident it would be easy to get it working and see results. As we had very little time to invest in building something for the import process, it felt like the perfect tool for us. Yet, like all import processes, it wasn't all plain sailing. We stumbled upon these challenges:

### Rich text format

Our initial challenge was to create a PoC to demonstrate how we could import 50-100 content items. Straight away we ran into an issue with Rich Text content. The export process from the legacy CMS didn't provide the content in a valid HTML format – essentially some missing closing HTML tags and invalid HTML markup. This was fixed on the export side with a few manual tweaks to the CSV.

### Performance and batch processing

We only tried a sample of 20 items as an initial test and it was failing due to the requests being made. This was a big concern. If 20 is failing, what about 1000-2000 items? I reached out to the Kontent Support team and the conversation was picked up by Eric Dugre, the author of the Google Sheets add-on. He investigated the issue promptly and addressed it by increasing the batch processing and going further to also improve the general usability of the tool itself. Both of that helped us a lot as the performance posed the biggest issue for us.

_Note: Some of the adjustments required approval from Google – it is still a Google Sheets add-on. Even though the add-on author’s reaction was prompt, this was something we needed to factor into our timings._

### Random GUID generated

Then, we looked at how to link content items together. For that, each content item should have a unique identifier, but that wasn’t our case. We had to generate a GUID for every item ourselves right within Google Sheets. This is the formula we used:

```
Public Function CreateGUID(Prefix as String) As String  
 Do While Len(CreateGUID) < 32  
   If Len(CreateGUID) = 16 Then  
     '17th character holds version information  
     CreateGUID = CreateGUID & Hex$(8 + CInt(Rnd * 3))  
   End If

   CreateGUID = CreateGUID & Hex$(CInt(Rnd * 15))  
 Loop  
 CreateGUID = Prefix + Mid(CreateGUID, 1, 8) & "-" & Mid(CreateGUID, 9, 4) & "-" & Mid(CreateGUID, 13, 4) & "-" & Mid(CreateGUID, 17, 4) & "-" & Mid(CreateGUID, 21, 12)  
End Function
```
_Note: You can create this in Excel, within Tools -> Macro -> Visual Basic Editor and create the above function._

This will allow you to generate random GUIDs for any row that uses 'CreateGUID('news_id_')'. I put an additional 'prefix' parameter to the function to be able to identify the appropriate content item and can link it to another one. It’s good to keep related content items within the same Excel worksheet as then you can create an Excel Forumla to bring the reference ID into the linked content item.

Once this all was in place, we ran the different imports into the Kontent project. Then the client made the necessary last-minute amends and final touches to the content and we didn’t really experience any other issues. Mission accomplished.

## In conclusion…

<figure data-asset-id="3c1272e7-94d5-42a4-b63b-21d2014fa526" data-image-id="3c1272e7-94d5-42a4-b63b-21d2014fa526">![Photo by Ian Stauffer on Unsplash, a man sitting on some large rocks with one arm in the air surrounded by clouds](https://assets-eu-01.kc-usercontent.com:443/cddb472f-6cfe-012c-a4f1-231959d72514/c7739fff-5059-46f7-b79a-adb4735bf11d/ian-stauffer-bH7kZ0yazB0-unsplash.jpg)</figure>

I introduced six ways to migrate content to Kontent and explained the pros and cons of each approach. I hope my adventures in content migration will help you should you come across a situation like this. In our case, the Google Sheets add-on was the best approach. It allowed us to hit the deadline way in advance which was a massive success for us and the client.

And, once more for those in the back, my recommendation when moving to a new CMS is to always have a good content strategy in place. Consider revisiting the content you already have and streamlining it in the process.

If you need any additional advice on my adventures going through the different content migration options, then don’t hesitate to get in touch with me via [email](mailto:ilesh.m@mmtdigital.co.uk), [Twitter](https://twitter.com/IleshMistry), or just pop a question on the [Kontent Discord](https://discord.gg/nBKaHAFq4N).