Understanding and using Project Config in Craft CMS
This is one of the types of articles that let's our clients have a "peek behind the curtain" about how their website really works. So while, it might get a little bit technical here and there, I will do my best to stick to plain english.
If you are a developer new to Craft CMS, I hope you find this useful for getting to grips with Craft CMS's Project Config and how to use it. And probably most importantly, how to prevent getting yourself tied up in knots when using it.
What is Project Config?
First and foremost, what is Project Config? Well, in Craft CMS's own documentation, here is how it is described:
As you make changes to system settings, Craft will record those setting values to YAML files in aCraft CMS Documentation
config/project/folder. You can then commit those files to your Git repository, just like your templates and front-end resources.
Think of Project Config as a detailed record of all the fields you have added, all the settings you have changed, all the plugins you have installed, and more. All this information is stored in YAML files, which you can download and store in your Git repository. If you are new to Git, a very basic way to think of what it does, is it keeps a history of your files and changes.
By including Project Config in your Git repo, you are able to keep track of any changes and updates you have made in your CMS settings, as well as having the ability to "roll them back" if need be. Plus, if you are working on mulptile environments, e.g. local, development, staging, and production, you can easily push these changes from one environment to another - but more on that later.
How Project Config has changed over time
Project Config was first introduced to Craft CMS at version 3.1.0, back in 15th January 2019. And it was quite a different beast to what it has become now. I'm not going to lie, if you managed to avoid using the early versions of Project Config, consider yourself very lucky indeed.
With the early versions of Project Config, everything was in one file, which in itself doesn't seem like a big deal, right? But if you were working on a website as a team - multiple people adding fields, updating instructions, installing plugins, changing CMS settings - the file could very quickly become full of conflicts. If you tried applying that broken file to your local, development, staging or production environment, it would cause the website to break! To say that it was flaky is a bit of an understatement.
However, when you look at Project Config now, it has come a long way. Firstly, it is a folder with lots of sub-folders and individual files within those sub-folders. This means everything has been broken out into individual files, which are much easier to manage. Conflicts very rarely happen now, even when people are working on a website at the same time. And if conflicts do arise, they are much easier to fix due to the nature of having many small files with very specific content, rather than one monster of a file containing everything.
There is also a lot more control within the control panel too, such as being able to review changes before applying them, and nice tools like being able to completely rebuild Project Config from the website's database.
Why use Project Config?
I've already touched on a few reasons above, but let's expand on those points now.
Being able to keep a track of updates you make to your Craft CMS build - fields, settings, plugins, etc. - is incredibly useful, especially when it comes to duplicating those changes across multiple environments. Not only does Project Config create this record, but it also enables you to automate the re-creation of those changes, rather than having to manually re-create them like we did in the past - a process that is prone for human error and can be very time intensive.
Used alongside an automated deployment, you could push your Project Config updates live alongside your file updates, making updating a website a much quicker process. Like I said before, if you were manually re-creating those fields, depending on how much needs updating, the process could be very time intensive - you might even need to take down a website while you do this, far from ideal!
You can also roll-back changes relatively easily through careful use of Project Config and your Git repo history. I've used this a few times to reinstate fields that had been deleted, that ended up needing to be re-added. Sometimes it is easier to simply re-create the field manually, but if you think of a complex Matrix field, using Project Config and your Git history can save a lot of time and headaches. But I would say to be very careful doing this. Make sure you back-up your database and files (including Project Config) first.
What is stored in Project Config?
There is a surprising amount of information about your website and its settings held within Project Config. Here is the full list from the Craft CMS docs:
- Asset volumes and named image transforms
- Category groups
- Craft and plugin schema versions
- Craft edition
- Email settings
- Fields and field groups
- Global sets (settings only, not their content)
- GraphQL schemas, and the access settings for the public schema
- Matrix block types
- Plugin editions and settings
- Routes defined in Settings → Routes
- Sections and entry types
- Sites and site groups
- System name, time zone, and status (live/offline)
- Tag groups
- User settings and user groups
Plus, plugins can store addition information in Project Config too.
Basically, anything that is stored in the database but that isn't content. For example, entry types are stored in Project Config, but not the entries themselves; the entries and their content would need to be re-created in each environment, e.g. for testing.
How to use Project Config
Before you get started, back-up everything! So make sure any changes you have made to your files are committed to your Git repo, take a back-up of your database (you can do this in Craft CMS itself under Utilities), and only then are you ready to download Project Config and commit that to your Git repo.
As in other areas of website development, Git is your friend - save Project Config to Git the same way you do your templates, then switch branches and use branch merge to duplicate changes from one environment to another, whether through FTP or an automated deployment.
But wait, there's more!
Disabling Admin Changes
It is highly recommended that you disable admin changes on your production website. This is so things like fields and other settings can't be changed on production without them first being made on the development and staging environments. Which in turn can cause you a lot of headaches trying to unpick where Project Config has went in different directions depending on the environment.
Ideally, changes in Project Config should go one direction - Local > Development > Staging > Production.
Here's what happens when you disable admin changes according to the Craft CMS docs:
When this is disabled, the Settings section will be hidden, the Craft edition and Craft/plugin versions will be locked, and the project config and Plugin Store will become read-only—though Craft and plugin licenses may still be purchased.Craft CMS documentation
You can disable admin changes on production in config/general.php by either setting allowAdminChanges to false, or using variables which automatically detect which environment you are in.
I would also recommend disabling the admin changes on your staging environment too, so that you can test the deployment onto production.
Unlike Project Config that should ideally only go from Local to Development to Staging to Production, your site content must only ever go one way and that is in the opposite direction. Your Production website should always be the source of truth when it comes to the actual content on your website. Therefore if you are duplicating your database, you should aim to never replace the production database with any of the other databases - there are actually reasons why you might want to do this but generally speaking, this is a good rule to stick by.
Rebuilding Project Config
I mentioned above that you can also rebuild your Project Config from the settings in the database. This can be very useful if you think it has become corrupted, such as conflicts arising from multiple people updating the site at once. There is an option within Utilities which enables you to do this, after which, simply download the new files and commit to your Git repo.
Downsides & Pitfalls of Project Config
I have said a few times above that resolving conflicts can be difficult, so like other development work, committing your changes to Git repo regularly, especially when working as a team, should help remove any potential conflicts in the Project Config file. But if the worst comes to the worst, I'd recommend rebuilding Project Config from the database and committing that as the new source of truth in your Git repo.
We have also found that unpicking different pieces of development work can be very difficult if those changes update Project Config. If you have 2 website updates happening at once, sending one live without the other can be very difficult, although not impossible.
Project Config can be very feckle if you fall out of sync somehow with the updates between environments. And applying the changes will make those changes happen, which could cause you a world of pain if you make updates before they are ready, or even deleting work you (or someone else) has already done. Ideally, you would complete and push live one development task before starting another. All you developers out there already know however that we don't live in an ideal world so this is not always possible.
Hence, back-ups, back-ups, back-ups. If you do need to roll back something, the more often you back-up, the less you need to re-do again.
Project Config has come along way since it first came on the scene in version 3.1.0. And while it does have its pitfalls, if you work in a very structured manner moving carefully from one environment to another, taking back-ups as you go, it is a very powerful tool.
When it comes to re-creating new sections on website, adding or changing settings, re-creating user groups and more, it is a massive time-saver that also takes out any errors that updating manually could create.
So while at times I can find myself cursing Project Config, if I'm to be honest, I don't think I would want to go back to building Craft CMS websites without it.