Settings
Blockstudio includes a powerful settings API, that allows setting options via a blockstudio.json file inside your theme folder and/or filters. Additionally, allowed users are able to change the settings visually inside the admin area.
Via JSON
If a blockstudio.json file is present inside your theme folder, it will be used to set the default options for the current site. A JSON schema is available to validate the file and help with autocompletion when used in an IDE.
The file is optional. Without it, Blockstudio uses settings saved in the admin area on top of its built-in defaults. Adding, changing, or removing the file is detected automatically, so no cache clear or manual reload is required.
The following properties are available:
{
"$schema": "https://blockstudio.dev/schema/blockstudio",
"users": {
"ids": [],
"roles": []
},
"assets": {
"enqueue": true,
"reset": {
"enabled": false,
"fullWidth": []
},
"minify": {
"css": false,
"js": false
},
"process": {
"scss": false
}
},
"cache": {
"enabled": true,
"path": "blockstudio/cache"
},
"themeDefaults": {
"titleTag": false,
"suppressDirectoryUpdates": false
},
"performance": {
"profile": "compat",
"wordpress": {
"headNoise": false,
"embeds": false,
"xmlrpc": false,
"editor": false,
"frontendAssets": false,
"media": false,
"heartbeat": false
},
"preload": {
"links": "off"
},
"media": {
"lazy": false,
"skeleton": false,
"metadata": false,
"rootMargin": "300px"
},
"measurement": {
"enabled": false,
"queryMonitor": false,
"headers": false,
"timings": false
}
},
"content": {
"enabled": false,
"id": "default",
"path": "content",
"includePageSyncManaged": false,
"authors": "ignore",
"postTypes": [],
"meta": {
"include": [],
"exclude": ["_edit_lock", "_edit_last", "_wp_old_slug"],
"references": {}
},
"taxonomies": [],
"media": "manifest"
},
"editor": {
"formatOnSave": false,
"assets": [],
"markup": false
},
"tailwind": {
"enabled": false,
"config": "",
"output": "inline"
},
"blockTags": {
"enabled": false,
"allow": [],
"deny": [],
"prefixes": {}
},
"ui": {
"enabled": false
},
"blockEditor": {
"disableLoading": false,
"enhance": false,
"cssClasses": [],
"cssVariables": [],
"blocks": {
"allow": [],
"deny": [],
"directory": true,
"categories": {
"allow": [],
"deny": [],
"rename": {},
"order": []
},
"styles": {
"deny": {}
},
"legacyWidgets": {
"hide": []
}
},
"patterns": {
"core": true,
"remote": true,
"theme": true,
"blockstudio": true,
"categories": {
"allow": [],
"deny": [],
"rename": {},
"order": []
}
},
"media": {
"openverse": true,
"imageSizes": {
"allow": [],
"deny": []
}
}
},
"dev": {
"grab": {
"enabled": false
},
"perf": false,
"canvas": {
"enabled": false,
"adminBar": true
}
},
"githooks": {
"commit": false
},
"phpstan": {
"preset": "base",
"configuration": "",
"roots": ["."],
"excludePaths": [],
"maxFiles": 10000
},
"ai": {
"enableContextGeneration": false
}
}
Via Filters
Alternatively you can use the blockstudio/settings/${setting} filter to set options via PHP for more flexibility.
add_filter('blockstudio/settings/assets/enqueue', '__return_false');
add_filter('blockstudio/settings/editor/formatOnSave', '__return_true');
add_filter('blockstudio/settings/ui/enabled', '__return_true');
add_filter('blockstudio/settings/block_editor/patterns/remote', '__return_false');
Options set via the blockstudio/settings/${setting} filter will override the ones set via the blockstudio.json file. Both methods can be used together.
Runtime values also expose blockstudio/performance/${setting} filters and one
final blockstudio/performance/config filter. The latter must return a valid
configuration object.
How the sources layer
Every source is loaded and merged, lowest priority first:
- Built-in defaults
- Settings saved through the admin UI (the
blockstudio_settingsoption) blockstudio.jsonin the themeblockstudio/settings/*filters
blockstudio.json overrides only the keys it declares. It used to replace the
saved settings entirely, so an unrelated admin-saved value stopped applying the
moment the file appeared; it now sits on top of them. The flip side: a stale
value saved through the admin UI keeps applying until the file declares that
key or the saved value is removed. When a setting behaves differently from what
the file says, check the saved layer with wp bs settings or
Settings::get_raw(), which returns only what the active JSON or options
source explicitly declared.
Reading settings from PHP
Blockstudio\Settings loads the active source, reports malformed JSON, and
automatically reloads when blockstudio.json changes:
use Blockstudio\Settings;
$enabled = Settings::get_bool('performance/media/lazy');
$margin = Settings::get_string('performance/media/rootMargin', '300px');
$roles = Settings::get_array('users/roles');
$ttl = Settings::get_int('performance/staticPrerender/ttl', 86400);
foreach (Settings::errors() as $error) {
error_log($error);
}
Use Settings::get_raw() when an integration needs only values explicitly
declared by the active JSON or options source. Settings::fingerprint() returns
a deterministic effective-settings identity. Long-running processes can call
Settings::reload() explicitly; normal access invalidates automatically.
The resolved performance profile is available through
Blockstudio\Runtime_Settings::current(). It supports slash or dot paths:
use Blockstudio\Runtime_Settings;
$runtime = Runtime_Settings::current();
if ($runtime->enabled('measurement/queryMonitor')) {
$hash = $runtime->hash();
}
Available Settings
users
| Option | Type | Default | Description |
|---|---|---|---|
ids |
array | [] |
User IDs with editor access |
roles |
array | [] |
User roles with editor access |
assets
| Option | Type | Default | Description |
|---|---|---|---|
enqueue |
boolean | true |
Auto-enqueue block assets |
reset.enabled |
boolean | false |
Remove core block styles and apply the editor utility reset |
reset.fullWidth |
array | [] |
Post types that use the full-width editor layout |
minify.css |
boolean | false |
Minify CSS output |
minify.js |
boolean | false |
Minify JS output |
process.scss |
boolean | false |
Process SCSS files |
output |
string | source |
Where compiled assets are written: source or cache |
output defaults to source, which writes a _dist directory beside each
block. Set it to cache to write compiled assets under the Blockstudio cache
directory instead, so the block source tree stays clean and deployable from an
immutable checkout. Sources Blockstudio cannot write to already redirect to the
cache regardless of this setting.
With reset.enabled active, Blockstudio also copies sanitized frontend
body_class values into the editor canvas. Use
blockstudio/editor/canvas/body_class to adjust the editor-only class list.
cache
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | true |
Enable Blockstudio file-backed caches |
path |
string | "blockstudio/cache" |
Cache path, relative to WP_CONTENT_DIR or absolute |
By default cache files are written to wp-content/blockstudio/cache, outside
the uploads directory. A relative path is resolved from WP_CONTENT_DIR; an
absolute path is used directly. This supports hosts that provide a dedicated
writable cache volume.
When enabled, Blockstudio uses this one root for build payloads, prebuilt block registration data, resolved editor assets, Tailwind CSS, render documents, island fragments, static prerenders, graph indexes, queues, and diagnostics. Each object is isolated by network, site, complete runtime identity, and scope. Runtime identities cover Blockstudio, settings, WordPress, PHP, the active theme, active plugins, logical discovery sources, host context, and explicit dependency hashes supplied by the owning operation.
The blockstudio/settings/cache/path setting filter changes the configured
value. For deployment-specific path resolution, blockstudio/cache/dir filters
the resolved base directory:
add_filter('blockstudio/cache/dir', function (string $directory): string {
return WP_CONTENT_DIR . '/cache/blockstudio';
});
Hosts with a tenant identity that differs from WordPress network/blog IDs can
filter blockstudio/cache/site_key. The result is sanitized and used only as a
directory segment. blockstudio/cache/context remains the correct place for a
serializable runtime variant that must alter object identities.
themeDefaults
| Option | Type | Default | Description |
|---|---|---|---|
titleTag |
boolean | false |
Enable WordPress title-tag theme support |
suppressDirectoryUpdates |
boolean | false |
Remove active child and parent themes from directory update results |
Patterns continue to use the existing Blockstudio\Patterns API; these
defaults do not introduce alternate page or pattern facades.
performance
The compat profile leaves generic WordPress behavior unchanged. speed and
strict enable the same opt-in frontend defaults; every child setting can
override its profile value.
Opt-in settings are registration gates. When an optional feature is false,
Blockstudio does not attach that feature’s frontend, admin, editor, REST, or
scheduled callbacks. Disabling Early Serve or scheduled warming after using it
performs its owned cleanup once; later requests remain inert.
| Option | Type | Compat default | Speed/strict default | Description |
|---|---|---|---|---|
profile |
string | "compat" |
— | compat, speed, or strict |
wordpress.headNoise |
boolean | false |
true |
Remove generic head discovery and emoji output |
wordpress.embeds |
boolean | false |
true |
Remove oEmbed discovery and host scripts |
wordpress.xmlrpc |
boolean | false |
true |
Disable XML-RPC and pingbacks |
wordpress.editor |
boolean | false |
true |
Disable remote editor discovery surfaces |
wordpress.frontendAssets |
boolean | false |
true |
Remove generic core frontend assets |
wordpress.media |
boolean | false |
true |
Apply image output defaults |
wordpress.heartbeat |
boolean | false |
true |
Throttle Heartbeat outside editors |
preload.links |
string | "off" |
"intent" |
Prefetch same-origin documents after user intent |
media.lazy |
boolean | false |
true |
Use Blockstudio’s image loader |
media.skeleton |
boolean | false |
true |
Show the built-in loading skeleton |
media.metadata |
boolean | false |
true |
Declare use of assets/media.json |
media.rootMargin |
string | "300px" |
"300px" |
Lazy-loader intersection margin |
measurement.enabled |
boolean | false |
false |
Enable runtime measurement APIs |
measurement.queryMonitor |
boolean | false |
false |
Include queries taking at least 50ms |
measurement.headers |
boolean | false |
false |
Send profile and config hash headers |
measurement.timings |
boolean | false |
false |
Send the elapsed runtime header |
staticPrerender.enabled |
boolean | false |
false |
Enable anonymous-safe HTML caching |
staticPrerender.ttl |
integer | 86400 |
86400 |
Maximum cached document age in seconds |
staticPrerender.invalidate |
string | "signature" |
"signature" |
Use signature or incremental graph identity |
staticPrerender.earlyServe |
boolean | false |
false |
Serve safe hits before WordPress boots |
staticPrerender.serveLoggedIn |
boolean | false |
false |
Permit users to consume, never author, cache hits |
staticPrerender.dynamicPaths |
array | [] |
[] |
Path prefixes that must remain dynamic |
staticPrerender.warm.enabled |
boolean | false |
false |
Enable the durable scheduled warm queue |
staticPrerender.warm.interval |
integer | 3600 |
3600 |
Warm interval in seconds |
staticPrerender.warm.concurrency |
integer | 2 |
2 |
Maximum jobs processed by one warm pass |
staticPrerender.warm.transport |
string | "http" |
"http" |
Use http or a host-provided internal renderer |
Static prerendering remains disabled unless explicitly enabled. A disabled
master switch registers no prerender request hooks, and disabled earlyServe
and warm.enabled switches register no admin or cron hooks. Signature mode uses
a cheap activated identity on ordinary requests. Graph mode is intended for
explicit builds: it records per-page source dependencies so changing one page
does not invalidate unrelated documents. See
Static Prerendering for warming,
deployment, early serving, and safety details.
Measurements are available programmatically:
use Blockstudio\Performance_Measurement;
$snapshot = Performance_Measurement::snapshot();
When headers are enabled, Blockstudio sends
X-Blockstudio-Performance-Profile,
X-Blockstudio-Performance-Config, and optionally
X-Blockstudio-Performance-Time. The
blockstudio/performance/measurement_enabled action receives the resolved
runtime settings.
The media options drive bs_media_image(), the assets/media.json
manifest, and the frontend lazy loader. See Media
for the helper, the manifest builder, and the loader behaviour.
content
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Enable Content Sync configuration |
id |
string | "default" |
Content-set namespace stored on synced entities |
path |
string | "content" |
Theme-relative content file directory |
includePageSyncManaged |
boolean | false |
Include Page Sync managed posts without owning their body |
authors |
string | "ignore" |
Author handling (ignore or existing-user login) |
postTypes |
array | [] |
Allowlisted post types |
meta.include |
array | [] |
Glob patterns for meta keys to sync |
meta.exclude |
array | ["_edit_lock", "_edit_last", "_wp_old_slug"] |
Glob patterns for meta keys to exclude |
meta.references |
object | {} |
Declared meta references rewritten between IDs and UIDs |
taxonomies |
array | [] |
Allowlisted registered taxonomies for terms and relationships |
media |
string | "manifest" |
Attachment reference behavior (manifest or none) |
Content Sync is managed through wp bs content and projects allowlisted posts,
postmeta, and declared references to portable files. See
Content Sync for the workflow and file
format.
editor
| Option | Type | Default | Description |
|---|---|---|---|
formatOnSave |
boolean | false |
Format block.json on save |
assets |
array | [] |
Additional assets to load in editor |
markup |
boolean | false |
Enable markup editing |
tailwind
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Enable Tailwind CSS compilation |
config |
string | "" |
Tailwind v4 CSS-first configuration |
See Tailwind CSS for compilation behaviour and the CSS-first configuration format.
blockTags
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Enable page-level bs: tag rendering in post content and widget areas |
allow |
array | [] |
Allowlist of block name patterns; supports fnmatch() wildcards |
deny |
array | [] |
Denylist of block name patterns; takes precedence over allow |
prefixes |
object | {} |
Prefix to namespace shorthands, each value a namespace or ordered array |
Template-level tag rendering is always active; these options control page-level replacement. See Rendering for the tag syntax and resolution rules.
ui
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Register the bundled bsui/* UI components and app/* demo apps |
blockEditor
| Option | Type | Default | Description |
|---|---|---|---|
disableLoading |
boolean | false |
Disable block loading in editor |
enhance |
boolean | false |
Enable Blockstudio editor hover and selection affordances |
cssClasses |
array | [] |
Stylesheet URLs to extract CSS classes from for the classes field autocomplete |
cssVariables |
array | [] |
Stylesheet URLs to extract CSS variables from for the code field autocomplete |
blockEditor.blocks
Use blockEditor.blocks for project-wide block inserter policy. allow and deny accept block names and wildcard patterns such as core/*.
{
"blockEditor": {
"blocks": {
"allow": ["core/*", "my-theme/*"],
"deny": ["core/embed", "core/freeform"],
"directory": false,
"categories": {
"rename": {
"text": "Writing",
"design": "Layout"
},
"order": ["my-theme", "text", "media"]
},
"legacyWidgets": {
"hide": ["archives", "calendar"]
}
}
}
}
blocks.styles.deny unregisters styles that were registered through WordPress’
PHP block style registry:
{
"blockEditor": {
"blocks": {
"styles": {
"deny": {
"my-theme/card": ["outline"],
"my-theme/media": ["framed"]
}
}
}
}
}
blockEditor.patterns
Use blockEditor.patterns to disable global pattern sources and to filter
pattern categories.
{
"blockEditor": {
"patterns": {
"core": false,
"remote": false,
"theme": true,
"blockstudio": true,
"categories": {
"deny": ["gallery"],
"rename": {
"featured": "Featured Layouts"
},
"order": ["featured", "buttons"]
}
}
}
}
blockEditor.media
Use blockEditor.media for global media inserter policy.
{
"blockEditor": {
"media": {
"openverse": false,
"imageSizes": {
"allow": ["thumbnail", "large"],
"deny": ["medium_large"]
}
}
}
}
dev
| Option | Type | Default | Description |
|---|---|---|---|
grab.enabled |
boolean | false |
Enable the frontend element grabber |
perf |
boolean | false |
Enable the performance profiler on every page load |
canvas.enabled |
boolean | false |
Enable the canvas |
canvas.adminBar |
boolean | true |
Show the WordPress admin bar when viewing the canvas |
githooks
| Option | Type | Default | Description |
|---|---|---|---|
commit |
boolean | false |
Generate an analysis-only pre-commit hook when blockstudio-githooks sync runs |
See the managed commit hook for what the generated hook runs and how it stays in sync.
phpstan
| Option | Type | Default | Description |
|---|---|---|---|
preset |
string | "base" |
Analysis preset when the command line does not select one: base, theme, extreme-theme, or wordpress-render |
configuration |
string | "" |
Project PHPStan configuration included alongside the preset, resolved from blockstudio.json |
roots |
array | ["."] |
Theme roots analyzed by the canonical command |
excludePaths |
array | [] |
Additional scanner exclusions relative to each configured root |
maxFiles |
integer | 10000 |
Maximum number of files inspected by the theme scanner |
These settings drive the canonical blockstudio-phpstan command. See
PHPStan for presets, layers, and adoption.
ai
| Option | Type | Default | Description |
|---|---|---|---|
enableContextGeneration |
boolean | false |
Generate a combined context file of blocks, settings, schemas, and documentation for LLM tools |
See AI Integration for the documentation index and the full generated text.
Enable and compose the bundled headless UI components introduced in Blockstudio 7.3.