Back to Blog

What Drupal Config Imports Change on Your Pages

A drush config:import can move blocks, change views and swap image styles without touching the theme. What changes, why, and how to check every page.

Yuriy Gerasymov
Yuriy Gerasymov
10 Nov 2026 · 8 min read

On most Drupal sites, every deployment ends with a configuration import. Whether it’s drush deploy or a plain drush config:import, Drupal makes the site’s active configuration match the YAML files in your repository. That’s the point of configuration management: a view, a block placement or an image style is built and reviewed on one environment and then arrives on production exactly as it was exported.

It’s also why a deployment can change what visitors see without a single line of theme code changing. The diff in the pull request reads views.view.news.yml and block.block.olivero_promo.yml. What it doesn’t show is that the news listing now has six items instead of nine, or that the promo block no longer appears on landing pages. This post covers what a configuration import changes on the page, the three ways it most often surprises a team, and how to check the pages before and after you deploy.

What a config import does on deploy

Drush’s deploy command runs these steps in order:

  1. drush updatedb
  2. drush config:import
  3. drush cache:rebuild
  4. drush deploy:hook
  5. drush cache:warm (Drupal 11.2 and later)

According to the same page, post-update functions (hook_post_update_NAME) run before configuration is imported, and Drush deploy hooks (hook_deploy_NAME) run after. So anything a deploy hook does to the site happens on top of the imported configuration.

A full import doesn’t only add and change configuration. It also removes configuration that exists on the site but not in the export. Drush’s documentation for config:import describes the --partial option as processing “only updates and new configs,” adding that with it “missing configs will not be deleted.” Without that option, they are.

Drupal’s own configuration management guide strongly recommends a database dump before each synchronisation, and a configuration import is the step where that dump earns its keep.

Configuration that changes what visitors see

Drupal treats a lot of presentation as configuration, so a lot of what’s on the page comes from those YAML files. These are the configuration objects that most often change a page when they’re imported:

ConfigurationNames look likeWhat changes on the page
Block placement and visibilityblock.block.*A block moves to another region, changes order, or appears and disappears on the pages, content types or roles its visibility rules name
Viewsviews.view.*Items per page, sort order, pager, the display format (a grid becomes a list), the fields shown and the exposed filters
Entity view displayscore.entity_view_display.*Which fields a view mode shows, in what order, with which formatter and which image style. Layout Builder default layouts are stored here too
Image stylesimage.style.*, responsive_image.styles.*Crop, size and aspect ratio of every image that uses the style
Text formatsfilter.format.*How existing body text renders: a filter change can strip tags or classes from content that hasn’t been edited
Themesystem.theme, yourtheme.settingsThe default theme, the logo and the theme’s own options
Date formatscore.date_format.*Every date shown with that format, on teasers, listings and articles
Performancesystem.performanceWhether CSS and JavaScript are aggregated, which can change the order styles load in

Two things make these changes easy to miss. First, they’re rarely confined to one page: an image style or a teaser display is used on every listing that shows that content type. Second, many of them only show up on some pages. A block visibility rule that now excludes /landing/* looks fine on the homepage, which is the page most people check after a deploy.

Three ways a config import surprises you

1. Changes made on production are reverted

Someone places a block on Live through the UI, or tweaks a view to fix something urgent. It works, and nobody exports it. On the next deployment, the full import makes production match the repository again: the view goes back to how it was, and the block placement, which isn’t in the export, is deleted.

If some configuration is meant to be edited on production, such as a site name or a webform that marketing manages, the Config Ignore module keeps it out of the import. Its project page describes it as a way to “treat configuration as if it was content.” For everything else, the fix is a habit: change it on a development environment, export it and deploy it.

2. Each environment has its own configuration

Not every environment runs the same configuration, and that’s often on purpose. Configuration Split lets you keep sets of configuration active on some environments only. Its own canonical example is the Devel module, plus a few block placements or views that exist on development but are never deployed.

Values in settings.php also differ by environment. Drupal’s configuration override system lets settings.php override any configuration value at runtime, with the highest precedence of any override, and those values don’t show in the admin interface. A common one on development and staging sites turns off aggregation:

$config['system.performance']['css']['preprocess'] = FALSE;
$config['system.performance']['js']['preprocess'] = FALSE;

drush config:get system.performance --include-overridden shows the value the site actually uses. Before you compare staging with production, check that the overrides match, or the comparison will show differences that come from the environment rather than from your change.

3. Configuration moves, content doesn’t

Configuration is deployed. Content isn’t. Nodes, taxonomy terms, custom block content, menu links created in the UI and Layout Builder layouts saved on individual nodes all live in each environment’s database. A new view display or block placement is built and reviewed against staging’s content, which may be months old, then imported into production, where the titles are longer, an image is missing and there are forty items in the listing instead of four.

Configuration can also depend on content. Acquia’s configuration management guide gives the example of a block that references a file by its UUID, and warns that if the content doesn’t exist when you import the configuration, the import will fail.

The safest staging environment for checking a configuration change is one with a recent copy of production’s database, so the imported configuration meets real content before it reaches production.

Review the YAML, then check the pages

Reviewing the configuration diff is the first step. drush config:status lists every configuration object that differs between the site and the export, and drush config:import --diff shows the changes as a diff before you confirm the import. Both tell you which configuration will change, but not which pages.

A practical routine for a deployment that includes configuration:

  1. Refresh staging from production so it has current content and production’s configuration.
  2. Deploy your branch to staging the way production gets it, with drush deploy or your host’s equivalent, so the import, the updates and the hooks all run in the same order.
  3. Work out which pages the changed configuration reaches. A block.block.* file reaches the pages its visibility rules include. A views.view.* file reaches each page display and every page that embeds one of its block displays. An image style or a core.entity_view_display.* file reaches every page that shows that content type in that view mode, which usually means listings too.
  4. Compare those pages on staging with production at a mobile and a desktop width, and look for blocks that moved or disappeared, listings that changed, and images with a new crop.
  5. Take a set of screenshots of production just before you deploy, then deploy and compare production with that set. This catches what staging couldn’t: production-only overrides, a Config Ignore list that behaves differently, and content that only exists on production.

Doing the comparison with Diffy

Diffy is ours, so this is how we’d do steps 4 and 5. Diffy works from URLs, so it needs no Drupal module and doesn’t care how the configuration got there.

  1. Create a project and import your pages from your XML sitemap. Keep one or two pages per content type and view, plus the pages with blocks that have visibility rules.
  2. Add staging as a second environment. Diffy swaps the domain in every URL, so the same page list covers both, and you compare staging with production at every breakpoint you set, from 240px to 2000px.
  3. Mark each change as expected or as a bug. A configuration change is supposed to change some pages, and marking those as expected leaves the surprises easy to see.
  4. Before the production deploy, take a set of screenshots of production, then compare the deployed site with it.

If your pull requests get their own environments, the comparison can run on every pull request instead. On Pantheon, our GitHub Actions workflow creates a Multidev for the pull request, rebuilds caches and imports configuration, compares the result with production and posts it as a GitHub check. Upsun and Tugboat have the same kind of workflow. For the rest, from logging in through /user to mocking the content of views that list the latest posts, see Drupal visual regression testing.

Frequently asked questions

Does drush config:import delete configuration?

Yes. A full import makes the site’s active configuration match the exported files, so configuration that exists on the site but not in the export is deleted. Drush’s --partial option only processes new and updated configuration and deletes nothing, and the Config Ignore module keeps the configuration you list untouched during an import.

Why does my Drupal site look different after drush cim when no code changed?

Because much of what a page looks like is configuration: block placement and visibility, views, entity view displays, image styles, text formats, theme settings and date formats. Importing a change to any of them changes the pages that use it, with no change to the theme.

Does drush deploy import configuration before or after database updates?

After. drush deploy runs updatedb, then config:import, then cache:rebuild and then deploy:hook. Post-update functions run before configuration is imported, and Drush deploy hooks run after.

How can I see what a configuration import will change?

drush config:status lists the configuration that differs between the site and the export, and drush config:import --diff shows the changes as a diff before you confirm. Both list configuration names, not pages, so compare screenshots of the affected pages as well.

Check the pages your next import touches

A configuration diff tells you what changed in the YAML. Screenshots of the pages tell you what changed for the people using the site. Before your next deployment with configuration in it, take a set of production screenshots, and compare again once the import has run.

Try Diffy free: 500 screenshots a month, no test suite required.

Related reading: Visual regression testing for Drupal · How to test a Drupal 11 upgrade · Two ways to use baseline screenshots

Related Articles

More guides on visual regression testing, QA automation, and keeping your site pixel-perfect as it changes.