A non-developer's guide to migrating content from Drupal 7 to Drupal 8

29 Apr 2020

Migrating from Drupal 6 to 7 was relatively straightforward. Migrating from 7 to 8, however, is much harder - especially for a non-developer like me.

Drupal 8 has migrate functionality built in, but I did not find it met my needs. It assumes that the new site will be similar to the old one in too many ways to satisfy my use case of a fundamentally redesigned system.

I tried using drush for migration, which has some benefits. But in general it was not very intuitive for a non-developer. I did however manage to use drush to migrate 15,000 user accounts, preserving usernames and passwords.

So I was on the look out for a method of migrating content which did not require an understanding of YAML files!

The Content Import module looked promising, but in trialling it I ran into some errors which I could not debug.

So in the end I went with Feeds. This module makes it relatively easy to import data from a csv file, my preferred method.

Preparing the CSV

This is one of the biggest tasks. I exported the data form the D7 side using a data export view.

I found that date fields are best in YYYY-MM-DD format. Another tip is to export the node path, so that when the new site is ready the link to the node uses the same alias.

I found that when including a taxonomy reference field for importing to taxonomy in Drupal 8, Feeds was ok with the term name. But when importing a taxonomy term or text select list term to a select list term in Drupal 8, Feeds wanted the machine name.

One issue with CSV files is encoding, if there are special non-ASCII characters. This is most solved by saving the CSV with UTF-8 encoding, but I found on occasion that I had to run a search and replace on the csv.

Importing via Feeds

Before you can configure the feed you must of course prepare the content type to receive the data.

Once the Feeds module is enabled, you have to create a Feed Type (Structure -> feed types) for the content type you want to import. On the Settings tab, I chose 'Upload file' as the Fetcher, and CSV as the Parser. Here you also choose the Content type. It's best to set the 'Import period' to 'Off', otherwise the feed might run uninvited - which happened to me, with a duplicate import taking place! There is a sub tab for Processor settings where you can decide whether or not to update existing contents, and where you can also set a default owner (user) for all imported content.

Next you move to the Mapping. In the 'Select a target' drop down are all the fields of the content type you have specified. Select one and then choose from the 'Select a source' drop down that appears the option of 'New CSV source', then specify the column heading from your CSV file.

For text fields which are configured as formatted, you can choose the default format on import, to ensure that this happens correctly.  

Once you've finished with the mapping, the next step is to create the actual Feed (Content -> Feeds). Give the Feed a title, upload the CSV file, and then run the import. It's worth doing a test run on a file with just a few rows to see if it works.

Error reporting is pretty good, usually telling you exactly why an error in importing a node occurred. The main errors I got had to do with a referenced file not being found, or a taxonomy term not matched. 

If you need to delete any nodes imported you can do so via a delete button, and then try again once you have dealt with the errors. Alternatively you can deal with the errors and then do a fresh import if you have configured the settings to update existing nodes.

Importing multiple value fields

The add on module Feeds Tamper provides some useful functions for manipulating the data from your CSV file before import. The most useful for me was the Explode function which meant I could import multiple taxonomy terms on a node, and multiple files. Just be careful either to leave no spaces between items in a cell in your CSV, or if you have a space there then to include the space in the string separator definition for the explode plugin.

Importing files

One of the trickiest things for me was to figure out how to import files attached to nodes. Through trial and error I discovered that I had to put the actual files into the Drupal 8 files system before running the import, and in the CSV I had to put the full path to the file, e.g. http://testsite/dev/sites/default/files/filename.pdf. This then works ok.

For the import of private files, so long as the file field is configured correctly (i.e. storage to private files) the imported files are correctly placed in the /private directory, which should be above the web root.

I found the Filefield Paths module a help in assigning files from different content types to different sub directories.


I found the Feeds method worked very well, but I made plenty of mistakes along the way. So do make sure to take a backup of your database at each stage, after configuration, before import, after import, so that you can revert if you need to.

Good luck!