Craft CMS

Migrating a Craft 2 site to Craft 3

Profile Image Michael Small
Michael Westwood November 6th, 2020
Migrating Craft Header Mobile

Following the release of Craft CMS 3, I’m really excited to start taking advantage of all its new features like native focal points for images, and the beautiful composer-based plugin store.

I’ve been spending a bit of time updating my Craft Core to reflect the new Craft 3 structure, so all new projects will be Craft 3 ready from the start.

But what of all the projects that are currently running on Craft 2. It’s not a simple one-click update this time. I’ll run through my process and checklist of how to migrate a Craft 2 site to Craft 3 with as mild a headache as possible. Have some paracetamol nearby though.

Some of this will apply to you, some of it is specific to using my Craft Core.

Here we go.

Looking for a Craft CMS agency for your next project?

Talk to us about our Craft CMS services.

1. Make a new folder

At first I tried just creating a new git branch and doing everything in the same place, but with a new folder structure and having to switch back and forth between branches occasionally, this was a very good way to stress myself out quickly.

No no no. New directory. I went for the format {projectname}-3.

Initialise a git repo, and add your Craft 2 project as the origin.
Add Craft Core as a remote called core if that’s what you’re doing.

git init
git remote add origin [repo url]
git remote add core

Create a new craft3 branch
git checkout -b craft3

Pull in the Craft 3 stuff from the Core.
git pull core craft3

2. Install Craft

A great new thing about Craft 3 is that everything is manager with Composer. So no copying in downloaded Craft zips and having to find specific versions of Craft or a plugin if your site isn’t up to date.

Nope. Now you can install Craft and plugins with composer.

composer install

And boom. We have Craft.

3. Add your database

So now duplicate your project’s Craft 2 database. I called my new one… wait for it… {projectname}-3

Another great thing about the new way Craft 3 works is the .env file, which replaces the awkward do-we-keep-it-in-git-do-we-not /config/db.php of Craft 2.

Now we’ve got an elegant, standalone, not-in-git .env file with all your database configuration in it.

Go ahead and update that with your new Craft 3 database settings.

If you’re like me, your Craft 2 database will probably be prefixed `craft_`. Craft 3 has sacked that off by default, so remember to update your `DB_TABLE_PREFIX` to match your Craft 2 database.

Also set a security key in .env. I think this is a new thing. And I think it can be any string you want, but probably best to use a strong password generator.

Make sure your .env is gitignored.

4. Configure your web server

Craft 3 has switched from using public as it’s webroot, to using web. So go ahead and let your web server know that web is the root.

I also created a whole new site for this new shiny Craft 3 version, and I went for `{projectname}3.local` as my url.

I use Valet, so for me that looked like

cd web valet link {projectname}3

Now you should be able to head over to {projectname}3.local/admin and see a big red button asking you to update the database. If you can see it, well done all is well! If not... well I dunno. Could be anything!

I had to hit the update button twice. Don’t know why. It did something the first time, then needed to do something more the second time. But nothing seemed to go wrong.

5. We’re up and running!

Sort of. There are probably some things that will need fixing. These are some common problems I faced, but they’re specific to how I set up my Craft 2 site. You might have similar issues, so here they are.

Site URL

Craft 3 does some cool stuff with aliases. So @web will point to your site url, @webroot will point to your web folder. All very nice stuff.

However, if you hit the Visit Site button, you might find it takes you to the live URL instead of your local one. Not cool.

That’ll be something to do with how your site url was set in Craft 2, and now it’s a set path instead of an alias.

So go to Settings > Sites.

If you just had the one locale, you’ll probably have one site now, which will be called `{sitename} + {locale}`. Change the baseURL to @web. While I was here I also changed the site name and handle to a sensible site name and handle, but that’s just for my own peace of mind.

Assets aren’t loading :(

I always set my asset path and folder before to use the variables {baseURL} and {basePath}, so I didn’t need to change it per environment.

  • Craft 3 has the same idea, but you’ll need to update it manually
  • Change @baseUrl to @web
  • Change @basePath to @webroot

I have no assets!

Did you copy them over from your old project folder? I sure didn’t.

My site is blank!

True. Your templates are src are all in your old Craft 2 project.

6. Move the old site in

Copy /craft/templates from your Craft 2 site into /templates in your Craft 3 site.

Depends on your setup, but all my styles and scripts are in /src, so copy over that too.

Remember to update any task runner tasks that might point to stuff in the old Craft 2 structure.

Craft Core issues

If you’re using the Craft Core, here are the common issues when moving from the Craft 2 way to the Craft 3 way:

jsonTransforms and jsonReader are now not plugins, they’re modules. Replace any references to jsonTransformsModule and jsonReaderModule.

`templates/_partials/snippets/` no longer exists. Things are organised into a new folder `templates/_snippets` and in subfolders `css`, `js`, and `svg`. Go ahead and do a manual search and replace.

`Setting unknown property: craft\models\AssetTransform::auto` Before our Imgix config was used in regular transforms, but now Craft 3 isn’t happy about that. Which is fair enough. Remove the auto setting from templates/json/transforms.json. That’s now taken care of in config/imager.php

BTW if you want to use imgix for images, set the `CRAFTENV_TRANSFORMER` settings in the .env file.

7. It loads, it loads!

But look, all the rich text fields are blank.

Not to worry, Craft 3 has got rid of its native rich text field, and instead you can install a separate plugin like CKEditor or Redactor.

Craft 2 used Redactor, so if you install that, all your rich text fields will automatically get converted into Redactor fields.

You should have a working site now, seamlessly converted to Craft 3. But wait!

8. Deprecation errors

Craft 3 has some templating changes that you’ll need to adhere to.

If you go to Settings > Utilities > Deprecation Errors, you might see a fair few errors.

I found most of these to be my use of `.first()` needing to be replaced with `.one()`. You can preeeeeety safely do with with a search and replace.

The other most common one was Craft 3 complaining that I need to explicitly call `.all()` on all my loops. Fair enough.

I would recommend:

  1. Clear the deprecation errors.
  2. Refresh a page.
  3. Reload the errors page.
  4. Fix an error.
  5. Repeat until you’ve checked every page and there are no more errors.

It won’t be as painful as it sounds, as many of them will be the same error.

9. Done!

All good? You’ve got a working Craft 3 site with no deprecation errors?

Excellent work. Now commit. Push to the `craft3` branch. Or `develop` if you’re feeling brave.

Profile Image Michael Small
Article By

Michael likes things that are made well, built to last. He once tried his hand at woodwork but it turns out he makes websites much better.