Migrations are in most cases performed poorly. The reason is that companies treat their IT ecosystem as a commodity rather than asset. The portofolio should be maintained and nurtured to keep in good shape.

This post is about website migration from Wordpress to Hugo but it is applicable for any kind of IT system migration of a small or medium business.

Why migrations are so critical?

Website migration can happen for multiple reasons:

  • Current costs too high or pricing changes
  • Current system is not suitable for current needs
  • Legislation (cookies etc)
  • Users start appreciating other features than before (eg. privacy)

The cost of migration is typically so high, that it requires multiple factors before planning one makes sense. Migrations are always - I repeat - always time consuming efforts.

At the same time migrations are great transition points to fix issues that have been pendig for years.

In business environment there is never enough time to do what it is needed to keep things working in long run. Because most businesses are lacking focus, most of the systems are used occasionally but none of them are treated as strategic asset.

That’s why migrations to better technologies are always left to the very last moment. Usually the system is already falling apart. The need is then urgent and the result will be another poorly designed system.

Even though, people don’t realize that having any business software is useless if there is not process. A CRM is a good example. It makes the existing sales process easier.

In my opinion businesses should define their critical systems and nurture them constantly. Most importantly the data model should be in a good shape and somewhat manageable. The next migration is always waiting behind the door.

The migration process from Wordpress to Hugo

This was roughly my website migration process from Wordpress to Hugo:

  1. Start experimenting Hugo with dummy content
  2. Create migration scripts to convert Wordpress data to Hugo format
  3. Experiment Hugo with the actual posts and content
  4. Answer to many surprising questions:
    • How I host my Hugo site?
    • Architecting the deployment process for Hugo site
    • How to migrate domain hosting and preserve the apex domain (eg mikaelahonen.com)
    • What is the difference between domain registrar and domaing hosting?
    • How to implement contact forms in Hugo?
    • Choosing a transactional email service
    • Should I host my emails in the old web hosting?
  5. Run the validated migration script
  6. Publish the new site!

The technical work to migrate data and content to new platform was not the most difficult part. As you can see in the bullet 4, I faced many tricky questions that were not anticipated.

Transferring domain for Hugo website

To avoid downtime during the website migration, maybe the biggest effort was in domain transfer. I needed to understand at detailed level how domain registation, DNS, apex domains and other domain records work. Everything related to domains were just one big monolith in the old web hotel.

Also some Hugo hosting providers had specific requirements for apex domain (eg. mikaelahonen.com). The advantage of Vercel was that A domain record could be directly pointed to a static IP address but still allowed efficient content delivery from the nearest data center.

Here was my process for domain transfer:

  1. Change domain registrar to domainhotelli.fi without interruption
    • Get transfer code from the old CPanel
    • Create domainhotelli.fi account and enter the code
    • Use the name servers of the old WP web hotel
  2. Add the domain records to cloudflare DNS management
  3. Hugo website ready for publishing in Vercel
    • Change name servers to xxxx.ns.cloudflare.com in domainhotelli.fi

What should be save when migrating

Data is lost in all migrations. It never makes sense to move 100% of assets as it would be too much work for the last 10%.

For example I did not save url redirects for Wordpress tags. From Google Analytics it seemed that there was practically no external linking to them.

Automated migration script from WordPress to Hugo

Most rookie level migrations are done manually.

One day you start moving data and logic to the new system little by little. Soon you notice that a few months have gone by. The old system has received some updates, users have added there new data and many parts needs to be done again.

This was the situation with one of my Pipedrive customers. My suggestion was to start all over again.

The longer the migration takes the more the new and the old systems will drift apart from the original state. A well designed migration script can mitigate this problem. When something changes in the source system, only small changes are needed in the script instead of manually doing it all over.

Here is the description of my migration processs. Each of them had zero or more related Python scripts.

Fetch source data. I had written instructions to run a few SQL queries in Wordpress database and export redirects from the Wordpress plugin. So this stage was semi manual but took only a few minutes and the process is still systematic. I used a smaller subset of the full data to test before the actual migration.

Prepare source data. In this stage I read the source data in and processed it to a format that is easier to use in the next steps. For example WordPress translations and taxonomies were stored in a difficult format so it made sense to clean those a bit. The output was a few well formatted data files.

Create entities for the new system. This stage consists of multiple scripts to create the files needed in Hugo. I had one script for posts, one for each taxonomy and one for images. The image script scaled the images to maximum dimensions of 1080x1920.

Move files to Hugo. The final part was to move the processed Hugo compatible files to my local Hugo repository automatically. The script removed the old files from the Hugo repo first.

Running all migration scripts took a few seconds for the text content. With image processing it was a bit over a minute. I could simulate the whole migration process tens or hundreds of times before the final decision.

Imagine spending 4 weeks to this manually and then realizing you made a mistake…

Which tasks can be done after the Hugo migration?

Some tasks must be done before the launch of the new website. And some of them can be done later when the site is already live.

It is generally more reliable to include as many tasks as possible to the automated migration scripts pre-launch. The downside is that the migration gets more complex and the benefits of the new shiny website are moved further to the future.

I completed some pre-launch tasks that were definitely not necessary. For example I shortened some of the post urls based on manually written mapping table.

Because my migration script was well designed it was possible to do these functionalities with low effort. In a busy business project I would have just left these actions out of the scope.

Summary of the migration from Wordpress to Hugo

Overall, I was really happy about outcome of the website migration. Planning was an intense process, but there were zero surprises in the end.

Once I decided to switch the traffic from old Wordpress instance to the Hugo site, it was live in 15 minutes.

When it comes to website migrations - or any migration - plan it properly!