Configuration
Every snippet has a snippet.json that declares where and when its files
load, so the files themselves hold only the code. Edit it in the editor like
any other file, or through Snippet configuration in the
workspace, which writes the same file into the draft;
save to apply either.
Minimal setup
The smallest valid configuration is an empty object:
{}
With it, every PHP file runs on init outside wp-admin, and every CSS, SCSS
and JavaScript file loads on the front end.
snippet.json must be strict JSON holding an object. A trailing comma, a
comment or a top-level array makes it invalid, and an invalid snippet does not
run at all: the file tree marks it Snippet (invalid snippet.json), the
configuration dialog asks you to fix the file first, and WP-CLI lists it as
disabled.
The configuration dialog writes only the fields you change, each in the form
snippet.json already holds it, so a key saved as one string stays one
string while it holds one value. Its Contexts and Environments cards
offer a switch per context and per environment type, with
any other stored value kept as a switch of its own, and Tags takes one tag
per line.
Metadata
| Key | Type | Meaning |
|---|---|---|
name |
string | The snippet’s display name, used by the export dialog and by WP-CLI. Defaults to the folder name. |
description |
string | What the snippet does. |
version |
string | A version such as 1.0.0, used as the exported plugin’s version. |
tags |
array | Labels for your own organisation. |
export |
object | author, uri and textDomain for the header of an exported plugin. |
Whether it runs
| Key | Type | Meaning |
|---|---|---|
enabled |
boolean | false keeps the snippet without running it. Omitted means enabled. The Enable snippet switch writes it. |
environments |
array | The environment types the snippet runs in, compared with wp_get_environment_type(): local, development, staging or production. Omitted or empty means every environment. |
schedule |
object | A time window, described below. |
Schedule
schedule limits a snippet to a period and, within it, to recurring times. It
has no field in the configuration dialog, so write it in snippet.json:
{
"schedule": {
"timezone": "Europe/Berlin",
"start": "2026-11-27 00:00",
"end": "2026-12-01 23:59",
"recurring": {
"type": "weekly",
"days": ["friday", "saturday"],
"start_time": "09:00",
"end_time": "18:00"
}
}
}
timezoneis a PHP timezone name; without it, or when it is invalid, times are UTC.startandendare date and time strings PHP can read. Beforestartor afterendthe snippet does not run; an unreadable value is ignored.recurring.typeisdaily,weekly,monthlyortime_range.dailyandtime_rangerun betweenstart_timeandend_time(HH:MMorH:MM, both required); a window whose end comes before its start, such as22:00to02:00, runs across midnight.weeklyalso takesdaysas weekday names, andmonthlytakesdaysas days of the month ([1, 15]). An unknown type is ignored.- A schedule, or a part of it, that is not shaped as above is ignored like an unreadable value; it never stops the site.
Where it runs
context (string or array) is where the files load. The default is
frontend, which the sleekByte/snippets/defaults/context filter changes.
| Context | PHP files run | CSS, SCSS and JavaScript load |
|---|---|---|
frontend |
on every request outside wp-admin, which includes REST, cron and WP-CLI | on the front end (wp_enqueue_scripts) |
admin |
in wp-admin outside the block editor, including admin-ajax.php requests |
in wp-admin (admin_enqueue_scripts) |
block-editor |
on block editor screens | in the block editor (enqueue_block_editor_assets) |
Byte tells the block editor apart from the rest of wp-admin through the
current admin screen. Before current_screen there is none, so on an earlier
hook such as init it treats every post.php?post=<id>&action=edit request
as the block editor and no other; give admin and block-editor PHP files a
hook from current_screen on when the difference matters.
hook (string) is the WordPress action PHP files run on. The default is
init, which the sleekByte/snippets/defaults/hook filter changes; CSS, SCSS
and JavaScript files ignore hook. Byte registers snippet files during
after_setup_theme, so muplugins_loaded, plugins_loaded, setup_theme and
after_setup_theme itself never run a file, and the configuration dialog and
WP-CLI refuse them.
| Hook | When it fires |
|---|---|
init |
on every request, once WordPress has loaded |
wp |
after the main query, on the front end only |
template_redirect |
on the front end, before the template is chosen |
wp_head, wp_footer |
while the front-end page is printed |
admin_init |
at the start of every wp-admin request |
current_screen |
in wp-admin, once the admin screen is known |
Conditions
conditions decides on each request whether the files load. It is a list
of groups: the snippet loads when any group matches, and a group matches when
all of its conditions do.
{
"hook": "wp",
"conditions": [
[
{
"parameter": "userRole",
"operator": "equals",
"value": "administrator"
},
{ "parameter": "isSingle", "operator": "equals", "value": true }
],
[
{
"parameter": "postType",
"operator": "equals",
"value": ["post", "page"]
}
]
]
}
Each condition has a parameter, an operator (default equals), a value
and an optional negate, which reverses the result. The configuration
dialog’s Conditions card edits the same groups.
When conditions are checked
A condition reads WordPress’s state at the moment it is checked, and a value WordPress has not worked out yet reads as empty or false, so the condition fails and the file is skipped without an error.
- PHP files are checked when their
hookfires. - CSS, SCSS and JavaScript files with conditions are checked on the hook
that enqueues their context:
wp_enqueue_scripts,admin_enqueue_scriptsorenqueue_block_editor_assets. The main query and the admin screen are known by then, so every parameter works for them.
| Parameters | Known from | Hook for PHP files |
|---|---|---|
userId, userRole, isUserLoggedIn, isAdmin, isAjax, isCustomizePreview, isNetworkAdmin, currentTime, currentDate, dayOfWeek, timeOfDay, deviceType, browserName, browserVersion, operatingSystem, isMobile, isTablet, isDesktop, requestUri, queryString, httpMethod, userAgent, referer, ipAddress, currentBlogId, isMultisite, isMainSite, option:, themeMod: |
init |
any, including the default init |
isSingle, isPage, isHome, isFrontPage, isCategory, isTag, isArchive, isSearch, is404, isAttachment, isFeed, isPreview, isEmbed, postId, postType, postStatus, postParent, postAuthor, pageTemplate, meta: |
the main query, front end only | wp or a later front-end hook such as template_redirect, wp_head or wp_footer |
currentScreen |
the admin screen, wp-admin only | current_screen or a later admin hook, with "context": ["admin"] |
isRest |
a REST request being served | rest_api_init |
currentLanguage |
your multilingual plugin | init for the site locale; wp or later when WPML or Polylang provides it |
On archive pages the post parameters read the first post of the main query,
such as the first product of the shop page; combine them with isSingle or
isPage to target single views.
Parameters
Every parameter a condition can test. Label is its name in the
Conditions card, Type decides which operators the card
offers for it, and Example is a value it can be compared with.
| Parameter | Label | Type | Value | Example |
|---|---|---|---|---|
userId |
User ID | number |
the current user’s ID, 0 when logged out; the card picks it from the site’s users, where Current user saves "currentUser", whoever is signed in |
1 |
userRole |
User role | string |
the current user’s first role, picked from the site’s roles | "editor" |
isUserLoggedIn |
User logged in | boolean |
whether a user is logged in | true |
postId |
Post ID | number |
the current post’s ID | 42 |
postType |
Post type | string |
the current post’s type, picked from the post types | "product" |
postStatus |
Post status | string |
the current post’s status, picked from the statuses | "publish" |
postParent |
Post parent | number |
the current post’s parent ID, 0 without one | 12 |
postAuthor |
Post author | number |
the current post’s author ID, picked like userId |
"currentUser" |
pageTemplate |
Page template | string |
the current post’s page template file, empty for the default template | "templates/full-width.php" |
isSingle |
Single | boolean |
is_single() |
true |
isPage |
Page | boolean |
is_page() |
true |
isHome |
Home | boolean |
is_home(), the posts page |
true |
isFrontPage |
Front page | boolean |
is_front_page() |
true |
isCategory |
Category | boolean |
is_category() |
true |
isTag |
Tag | boolean |
is_tag() |
true |
isArchive |
Archive | boolean |
is_archive() |
true |
isSearch |
Search | boolean |
is_search() |
true |
is404 |
Not found | boolean |
is_404() |
true |
isAttachment |
Attachment | boolean |
is_attachment() |
true |
isAdmin |
Admin area | boolean |
is_admin(), whether the request is in wp-admin |
true |
isAjax |
Ajax request | boolean |
wp_doing_ajax(), whether it is an AJAX request |
true |
isRest |
REST request | boolean |
whether it is a REST request | true |
isFeed |
Feed | boolean |
is_feed() |
true |
isPreview |
Preview | boolean |
is_preview(), a post preview |
true |
isCustomizePreview |
Customizer preview | boolean |
is_customize_preview(), the Customizer preview |
true |
isEmbed |
Embed | boolean |
is_embed() |
true |
currentScreen |
Current screen | string |
the admin screen ID, such as dashboard, or empty before the screen is known and outside wp-admin |
"edit-post" |
currentTime |
Current time | time |
the site’s time as HH:MM |
"14:30" |
currentDate |
Current date | date |
the site’s date as YYYY-MM-DD |
"2026-12-24" |
dayOfWeek |
Day of week | number |
the day of the week, 0 (Sunday) to 6 (Saturday) |
[1, 2, 3, 4, 5] |
timeOfDay |
Time of day | number |
the hour, 0 to 23 | 9 |
deviceType |
Device type | string |
mobile, tablet or desktop |
"mobile" |
browserName |
Browser name | string |
edge, opera, samsung, firefox, chrome, safari, internet-explorer or unknown |
"firefox" |
browserVersion |
Browser version | string |
the browser’s version, such as 126.0.0.0, or unknown |
"126." with startsWith |
operatingSystem |
Operating system | string |
ios, windows-10, windows-8.1, windows-8, windows-7, windows, macos-catalina, macos-mojave, macos, android, linux or unknown |
"macos" with startsWith |
isMobile |
Mobile | boolean |
whether deviceType is mobile |
true |
isTablet |
Tablet | boolean |
whether deviceType is tablet |
true |
isDesktop |
Desktop | boolean |
whether deviceType is desktop |
true |
requestUri |
Request URI | string |
the requested path with its query string | "/shop/" with startsWith |
queryString |
Query string | string |
the query string, without the ? |
"utm_source=newsletter" with contains |
httpMethod |
HTTP method | string |
the request method, such as GET or POST |
"POST" |
userAgent |
User agent | string |
the browser’s user agent string | "Googlebot" with contains |
referer |
Referrer | string |
the referring address, empty without one | "https://www.google.com/" with startsWith |
ipAddress |
IP address | string |
the visitor’s IP address, as described below | "203.0.113.7" |
currentBlogId |
Current site ID | number |
the current site’s ID | 2 |
isMultisite |
Multisite | boolean |
whether WordPress runs a network | true |
isMainSite |
Main site | boolean |
whether this is the network’s main site | true |
isNetworkAdmin |
Network admin | boolean |
whether the request is in the network admin | true |
currentLanguage |
Current language | string |
the language code from WPML or Polylang, such as en, otherwise the site locale, such as en_US |
"de" |
option:<name> |
none | any | the value of the WordPress option <name> |
option:blog_public with "1" |
meta:<key> |
none | any | the current post’s meta value <key> |
meta:featured with "yes" |
themeMod:<name> |
none | any | the theme modification <name> |
themeMod:header_layout with "wide" |
The card offers currentBlogId, isMainSite and isNetworkAdmin only on a
multisite network. option:, meta: and themeMod: take the name after the
colon; they are not in the card’s list, so write them in snippet.json, and
they compare whatever value WordPress stores.
The device, browser and system values come from the user agent string, which
browsers simplify: Windows 11 reports windows-10 and current Macs report
macos-catalina, so match the family with startsWith, such as windows or
macos. Current Edge, Opera and Samsung Internet report edge, opera and
samsung, and Chrome, Firefox and Edge on iOS report chrome, firefox and
edge.
By default ipAddress is the direct connection address. Behind a trusted
reverse proxy that overwrites forwarded headers, define the constant in
wp-config.php:
define('SLEEK_BYTE_TRUSTED_PROXY', true);
Byte then uses the first of CF-Connecting-IP, Client-IP and
X-Forwarded-For that is present, taking the first address of a list. Byte
checks only that the constant is defined, whatever its value. Do not define it
where visitors can send those headers directly, because they can be forged.
Operators
The Conditions card offers the operators of the parameter’s type, under these
labels; a parameter without a type, such as option:<name>, gets those of
string:
| Type | Operators |
|---|---|
boolean |
equals (Equals) |
number |
equals (Equals), greaterThan (Greater than), greaterThanOrEqual (Greater than or equal), lessThan (Less than), lessThanOrEqual (Less than or equal) |
date, time |
equals (Equals), greaterThan (After), greaterThanOrEqual (On or after), lessThan (Before), lessThanOrEqual (On or before) |
string |
equals (Equals), contains (Contains), startsWith (Starts with), endsWith (Ends with), lengthEquals (Length equals), lengthGreaterThan (Length greater than), lengthGreaterThanOrEqual (Length greater than or equal), lengthLessThan (Length less than), lengthLessThanOrEqual (Length less than or equal), wordCountEquals (Word count equals), wordCountGreaterThan (Word count greater than), wordCountGreaterThanOrEqual (Word count greater than or equal), wordCountLessThan (Word count less than), wordCountLessThanOrEqual (Word count less than or equal) |
In snippet.json any operator works with any parameter, compared as follows;
an unknown operator does not match:
| Operators | Compare |
|---|---|
equals |
equality; with a list on either side, whether any item matches, compared as text |
contains, startsWith, endsWith |
text containing, starting with or ending with the value |
greaterThan, greaterThanOrEqual, lessThan, lessThanOrEqual |
numbers, such as the hour of timeOfDay, and dates and times in their fixed formats, such as currentTime after "09:00" |
lengthEquals, lengthGreaterThan, lengthGreaterThanOrEqual, lengthLessThan, lengthLessThanOrEqual |
the length of a text |
wordCountEquals, wordCountGreaterThan, wordCountGreaterThanOrEqual, wordCountLessThan, wordCountLessThanOrEqual |
the number of words in a text |
Weekdays during business hours:
{
"conditions": [
[
{
"parameter": "timeOfDay",
"operator": "greaterThanOrEqual",
"value": 9
},
{ "parameter": "timeOfDay", "operator": "lessThan", "value": 17 },
{
"parameter": "dayOfWeek",
"operator": "equals",
"value": [1, 2, 3, 4, 5]
}
]
]
}
Everyone except subscribers:
{
"conditions": [
[
{
"parameter": "userRole",
"operator": "equals",
"value": "subscriber",
"negate": true
}
]
]
}
External assets
assets loads stylesheets and scripts from other hosts, keyed by the
WordPress handle they register under. They load in the snippet’s contexts,
before the snippet’s own files, and follow the snippet’s conditions.
{
"assets": {
"alpinejs": {
"url": "https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js",
"version": "3",
"dependencies": [],
"local": true
}
}
}
| Key | Meaning |
|---|---|
url |
The asset’s address. A path ending in .css is a stylesheet; anything else is a script. |
version |
The version WordPress appends to the address. |
dependencies |
Handles that must load first. |
module |
true loads a script as a JavaScript module and adds it to the page’s import map under its handle. |
local |
true serves a copy from uploads/sleek-byte-assets instead of the remote address. Byte downloads it the first time a request needs it and keeps the remote address while the download fails. |
The configuration dialog’s Assets card edits the same list, and its download
button fetches a copy straight away through Actions_downloadAsset, which
accepts only public HTTP and HTTPS addresses and files up to 5 MB.
Per-file options
files maps a file’s path inside the snippet to options that override the
snippet’s for that file. The configuration dialog’s Files card lists every
file of the snippet.
{
"context": ["frontend"],
"files": {
"admin/settings.php": { "context": ["admin"], "hook": "admin_init" },
"assets/admin.css": { "context": ["admin"] },
"assets/app.js": { "dependencies": ["jquery"], "module": true }
}
}
| Key | Meaning |
|---|---|
context |
Replaces the snippet’s contexts for this file. |
hook |
Replaces the snippet’s hook, for PHP files only. |
dependencies |
Handles of scripts or stylesheets that must load first; see Files. |
module |
true loads a JavaScript file as a module. |
conditions |
Replaces the snippet’s conditions for this file. |
A file’s conditions replace the snippet’s rather than adding to them. To require both, repeat the snippet’s conditions inside each of the file’s groups.
{
"hook": "wp",
"conditions": [
[
{ "parameter": "postType", "operator": "equals", "value": "product" },
{ "parameter": "isSingle", "operator": "equals", "value": true }
]
],
"files": {
"product/gallery.php": {},
"checkout/fields.php": {
"conditions": [
[
{
"parameter": "requestUri",
"operator": "contains",
"value": "checkout"
}
]
]
}
}
}
product/gallery.php loads on single product pages and runs on wp, because
postType and isSingle need the main query. checkout/fields.php carries its
own condition, so it loads on addresses that contain checkout instead.