The theme.json file is a central place for various WordPress theme settings. Things like color palettes, gradients, fonts, block spacing, and other global styles and default settings of the block editor are all defined in this single file.
There are a few options to adjust the values defined in that file. Within the Site Editor, things defined at the theme.json level can be customized and saved in the website options table, thus decoupled from the theme.json file itself.
There’s also a built-in tool in WordPress core that can be used to generate a new block theme based on the customizations made. That’s handy if one prefers building the theme “live” rather than from the IDE point of view.
In both cases, however, a connection with the original theme is lost, at least partially in the first and fully in the second. That’s not always a problem; sometimes, it’s expected and desired. But what if we want to keep the “foundation,” the basic theme, and be able to receive its updates as soon as they are available but still modify some values of the theme.json file to meet the project’s specific needs?
How to filter the theme.json data with PHP
Four new filters were introduced in WordPress 6.1 (released on November 2, 2022) that can be used specifically for that purpose. These filters’ scope varies depending on which data layer is to be modified:
wp_theme_json_data_default
is for filtering the default data provided by WordPress,wp_theme_json_data_blocks
is for filtering the data provided by blocks,wp_theme_json_data_theme
is for filtering the theme data,wp_theme_json_data_user
filters the other user-generated data (from the Site Editor).
All of these hooks are defined in the WP_Theme_JSON_Resolver
class and are passing the WP_Theme_JSON_Data
object as a first argument; this object can be used in a custom callback function to update the underlying data.
Filtering default theme.json file data
The first hook on the list allows filtering default theme.json data, as provided by WordPress. These include various Block Editor settings (like whether or not to show the “appearance tools,” the core duotone, gradients, and shadows configuration, common spacing and typography configuration, etc.
Let’s assume you want to modify the default “black” color – it is set to #000000
in WordPress core, but most modern websites rarely use “pure black” color for text or other elements. Let’s say we want to change it to #111111
, but rather than defining the custom color, we still want to refer to it as core “black.”
That’s where the wp_theme_json_data_default
filter comes in handy:
This filter above will modify the --wp--preset--color--black
CSS variable value from #000000
to #111111
. Note: if you’re updating a single element of an array of elements, you must provide a whole array to the update_with
method, not only the single updated value. Otherwise, only the provided value will be used, and the rest will be lost.
This behavior, however, could be used for another purpose – removing default values that are not used and needed. By default, WordPress core provides many colors and gradients, which you might not want to see on your website for many reasons. Using the same hook, you can get rid of them:
All the remaining elements of the theme.json structure will remain unchanged, so you don’t need to worry about passing the whole theme.json data into the update_with
method.
One more thing to note: the version
key should reflect the theme.json file version. You can find which version your theme uses by inspecting the theme.json file, which is usually located in the theme’s root directory. That’s required to ensure that settings will be merged correctly and to maintain required backward and forward compatibility.
Filtering the theme-related data
In this following example, I’d like to filter the “Extra Extra Large” (xx-large) font size defined in the Twenty Twenty Four theme, which is currently set as fluid between 2.5rem
and 3.27rem
. I want to ensure it will always be set to 4rem
. In this case, I’ll use the wp_theme_json_data_theme
hook:
Depending on a project’s needs, any required business logic can be applied inside that filter. Rather than displaying the default value of the site’s background color as defined in a theme, you might want to display a “random” background color on every render (because why not?). In this case, it would be as simple as:
How to filter the theme.json data with JavaScript
WordPress 6.2 (released on March 29, 2023) introduced a new JS filter (blockEditor.useSetting.before
), which allows engineers to modify the theme.json settings before the Block Editor is rendered. This filter allows to modify the block settings depending on the user role, other blocks used on a page, post type, and any other data available in the Block Editor context.
With this filter, you can modify the settings and block configuration in the Block Editor context; these changes will not apply on the website’s front-end – so the use cases for this approach are quite different.
If you’re interested more about this topic, please check the “further reading” section below for recommended sources and articles.
Conclusion
WordPress hooks mentioned in this article give the engineers much control over the theme.json file contents. That might be useful in some cases, like where a project specifics are to allow users some level of freedom, but still, there should be some validation and protection in place; where certain things should be removed to reduce the size of a CSS rendered on the front-end (front-end performance improvements); or, where some things of a chosen theme should be modified, without detaching the rest of the settings.
But this will not always be the best choice; sometimes, it’s better to modify the theme.json directly (if it’s a fully custom theme) or to build/export a new theme based on applied modifications. It all depends on the specific needs of a project. But it’s good to have more options!
Further reading
If you’d like to find out more about this topic, below are the resources I found helpful when researching this topic for the first time:
- https://make.wordpress.org/core/2022/10/10/filters-for-theme-json-data/
- https://developer.wordpress.org/news/2023/07/how-to-modify-theme-json-data-using-server-side-filters/
- https://make.wordpress.org/core/2023/02/28/custom-settings-wordpress-6-2/
- https://developer.wordpress.org/block-editor/how-to-guides/curating-the-editor-experience/#limiting-interface-options-with-client-side-filters
- https://github.com/WordPress/wordpress-develop/blob/7f0b94069d40e1766a453d77542a533f44fb008f/src/wp-includes/class-wp-theme-json-resolver.php#L539-L601