Local JSON and version control
6 min read
Local JSON mirrors your definitions to files. When a folder named wpmcf-json exists in your theme, every time you save a field group, post type, taxonomy or options page the plugin also writes it there as a small JSON file. Commit the folder to Git, deploy it with the theme, and a second site can load the changes with one click.
Turn it on
Local JSON is off until the folder exists.
- Open WPM Fields › Tools › Local JSON. The Folder line shows the path, relative to the WordPress folder, and a badge.
- If the badge says Folder missing and the plugin can create it, click Create folder. You get the toast Local JSON folder created.
- If the plugin cannot create it (the message says The plugin cannot create it here; create it with your file manager or FTP.), create a folder named
wpmcf-jsoninside your active theme, and make it writable by the web server.
The default folder is wp-content/themes/{your active theme}/wpmcf-json. With a child theme it is the child theme's folder.
Badge | Meaning |
|---|---|
Active | The folder exists and is writable. Saves are written to files. |
Folder missing | Nothing is written. |
Not writable | The folder exists but the server cannot write to it. Saving still works; you are warned and the problem is logged under Settings › Health. |
Off | A developer filter turned the save path off. |
When the plugin creates the folder it also adds index.php, .htaccess and web.config files that deny web access: definitions are only ever read from disk, never over the web. On nginx add your own deny rule for the folder.
What gets written, and when
- One file per definition, named by kind and key:
Kind | File |
|---|---|
Field group |
|
Post type |
|
Taxonomy |
|
Options page |
|
- A file is written when a definition is saved and removed when it is deleted. Creating the folder does not write files for the definitions you already have: open and save each one, or use Export once to get them all in a single file.
- Each file is a normal export document with exactly one definition, plus a
modifiedtime (Unix seconds):
{
"format": "wpmcf-export",
"version": 1,
"plugin_version": "1.0.0",
"exported_at": "2026-10-03T12:59:23+00:00",
"modified": 1791032363,
"field_groups": [ { "key": "book_details", "label": "Book details", "fields": [] } ]
}- Field groups that come from PHP code are not written to the folder.
- Other files in the folder, and file names that do not follow the patterns above (including upper-case keys), are ignored.
Load changes from files
The Local JSON tab lists files whose definitions differ from the site.
Badge | Meaning |
|---|---|
New | The definition does not exist on this site. |
Changed | It exists but the file holds a different version. |
Click Sync on one row to load that file. When more than one file is waiting, Sync all appears at the top of the card. The toast says Synced N definition(s). Any row that fails is listed below the card with its message, as in the import report. The list says Everything is in sync. when nothing is waiting.
When is a file offered?
A file is offered when its definition is missing on the site, or all of these are true:
- the file differs from what is stored on the site;
- the file is not simply the content the plugin wrote or synced itself earlier;
- for field groups and options pages, the file's
modifiedtime is newer than the site's last change. A file with nomodifiedtime passes this check.
Post types and taxonomies keep no change time, so any file that differs is offered.
This makes the site's own latest save win: if you edit a field group on the site after the file was written, the older file is not offered, and the next save overwrites it.
Syncing a file replaces the stored definition like an import with Replace existing definitions on. It does not rewrite the file, so Git sees no change.
Files that cannot be read
Broken files are listed under Some files cannot be read with the reason:
Message | Cause |
|---|---|
The file is not valid JSON. | Broken JSON. |
The file must hold exactly one definition whose key matches the file name. | Two definitions in one file, or |
The file cannot be read or is too large. | Permission problem, or over 5 MB. |
This file is not a Mass Custom Fields export. | Wrong |
A Git workflow
- Create
wpmcf-jsonin the theme on your development site and click through Create folder (or create it by hand). - Save the definitions you want to track. Commit
wpmcf-json. - Deploy the theme to staging or production.
- On that site open Tools › Local JSON and click Sync all. (Or run
wp wpmcf json sync --all, see WP-CLI.) - Work on either site and repeat. If both sites changed the same definition, merge the file in Git first; the newest
modifiedtime wins for field groups.
Keep the uid values in field group files if you rename field keys: they are what lets the importer rename columns instead of dropping and recreating them. A hand-written file without uid values is fine for fields whose keys already exist on the site: the stored uid is reused.
Syncing creates or changes tables just like saving does, so run it on staging before production for large changes.
Developer filters
Filter | Type | Default | Purpose |
|---|---|---|---|
|
|
| Where files are written. Return an empty string to turn Local JSON off. |
|
| the save path, plus the parent theme's | Folders that are read. When the same file name exists in several folders the first folder wins. |
|
|
| Force writing on or off. |
// Keep definitions in a shared plugin folder instead of the theme.
add_filter( 'wpmcf/local_json/save_path', fn () => WP_CONTENT_DIR . '/site-config/wpmcf-json' );
add_filter( 'wpmcf/local_json/load_paths', fn () => [ WP_CONTENT_DIR . '/site-config/wpmcf-json' ] );Paths shown on the Tools screen are relative to the WordPress folder. A file found only in an extra load path (for example the parent theme) is offered for sync, but saving that definition later writes the file to the save path.
Deleting a definition removes only the file in the save path. A copy in another load path is offered again as new.
Troubleshooting
Nothing is written after saving. The badge must say Active. Check the folder name (wpmcf-json), that it is inside the active theme (a child theme if one is active) and that it is writable.
"Could not write field-group-x.json to the local JSON folder." The save went through but the file did not. Check permissions, disk space and the Health tab. See Health and troubleshooting.
A file keeps coming back as Changed after I synced it. The definition is rejected. The message appears below the card after Sync.
A file I just edited is not offered. Its modified time is older than the last change on the site. Raise modified (any larger Unix time) or remove the key, or save the definition on the site to overwrite the file.
The theme was updated and my files vanished. Theme updates replace the theme folder. Use a child theme, or move the folder with the filters above.
Still stuck? Contact support