WP Shifty Documentation

Current Version: 1.1.4
Text Domain: wp-shifty

Getting Started

Activate WP Shifty

Activation doesn’t require a manual license key. Go to Tools → WP Shifty, click Activate your license, log in on musthaveplugins.com, select your subscription, then Connect.

Bought WP Shifty on wp-shifty.com before 2025? On the connect page click Connect with WP Shifty account and log in with your wp-shifty.com credentials. You don’t need a musthaveplugins.com account for this.

To move the license to another site or subscription, click the green active License status badge on the WP Shifty dashboard, confirm Would you like to disconnect license?, then connect again.

Creating and editing scenarios needs an active license, because scenarios are saved through the WP Shifty API.

Scenarios

What are scenarios?

Scenarios are collections of rules that apply when conditions are met. They can disable plugins, manage CSS/JS (disable, overwrite, lazy/async/defer), preload files, and inject HTML.

Apply and Exception conditions

Every condition has an Apply / Exception switch. The scenario card summarizes them as APPLY … IF … EXCEPT …:

  • Location conditions (Page, Post Type, Archive, Author, Search, 404 Request, URL, Admin pages, AJAX, Shop Pages, Frontpage, Frontend, Everywhere, Cronjob, CLI): the scenario runs if any of them matches.
  • Filter conditions (Query String, User, POST data, HTTP header, Cookie, User agent, Device): all of them must match too. They only narrow the locations, so always add at least one location condition, e.g. Everywhere or Frontend.
  • Exceptions: if any condition switched to Exception matches, the scenario does not run for that request.

Example: Everywhere + Exception Shop Pages disables a plugin everywhere except the WooCommerce pages (shop, cart, checkout, etc.).

How to test rules (Live Preview)

The editor shows your site in a preview frame, so you can test changes without affecting visitors. Enter or pick a URL above the preview and choose a device. Under Advanced you can set the User role (default: User not logged in), Useragent, Custom headers, POST data and Cookies for the preview request.

  • The Live tab lists the Plugins, CSS and JS loaded on the previewed page. The Editor tab holds the Disable, Inject, Preload and Load behavior rules.
  • Turn off Refresh preview automatically to make several changes, then refresh the preview once.
  • If the rule panel is greyed out and the preview shows Conditions are not matching with the preview, the previewed URL, device or user role does not meet the scenario’s conditions. Click Click here auto-configure preview, or set a matching URL, device or user role under Advanced.

Managing scenarios

All scenarios are listed on Tools → WP Shifty. Click Add new scenario to open the editor, give the scenario a name in the field at the top, then click Save & Activate or Save as draft. When you edit an existing scenario, the buttons are Save changes and Switch to draft.

  • Each scenario card has Edit, Pause / Activate, Delete and Duplicate. A duplicate is created as a draft. Deleting a scenario also deletes its overwritten and injected files.
  • Drag and drop the cards to change their order. Scenarios higher in the list are evaluated first.
  • With more than one scenario, use the SEARCH box to filter them by condition or rule.

Toolbar shortcuts

When you have permission to manage options, WP Shifty adds an admin toolbar menu with quick actions:

  • Edit matched scenarios for the current request.
  • Add rule to current page/post type/URL directly from the toolbar.

Rules

Manage plugins (Disable plugins)

Toggle plugins off per scenario in the Plugins list of the editor’s Live tab. When conditions match, the plugin won’t execute at all (not just dequeued). Always verify functionality in Live Preview.

  • Only plugins activated on the site itself can be disabled. Network-activated plugins on a multisite are not affected.
  • A plugin is removed from the active plugin list only for the matching request. If another plugin saves the active plugin list during such a request (for example, to change the plugin load order), the temporarily disabled plugins are deactivated permanently. If this happens, re-activate them and find the plugin that rewrites the list (search its code for active_plugins).

Disable resources

Disable any static resources, including inline CSS or JS. Reduces bloat by removing unneeded files. Be careful disabling JS that other scripts depend on; test interactions afterward.

Overwrite resources

Clone CSS/JS to a safe copy and edit it without touching the original. You can beautify minified sources and re-minify via WP Shifty API, and restore the original with one click.

Load behavior (async, defer, lazy)

  • Lazy (CSS, JS and inline JS): held back until the first user interaction (mousemove, click, touchstart or keydown). If the page is already scrolled when the DOM is ready, the files load immediately. Scrolling alone does not trigger loading.
  • Async (external scripts): download asynchronously and execute as soon as loaded.
  • Defer (external scripts): download asynchronously and execute after document parsing.

Preload resources

Preload critical assets like LCP images and above-the-fold CSS/JS to improve perceived performance. Pick the file or type its URL, set Preload as (style, script, font, image, video, audio, embed or document), and optionally add a Media query such as (min-width:768px) to preload it only on matching screens.

Inject HTML

Inject snippets at precise hooks: head beginning/after styles/end and footer beginning/end. Useful for critical CSS, inline scripts, or vendor tags.

Conditions

Page

Match specific page IDs.

Post type

Match the current post type.

Archive

Match archive contexts.

Author

Match author archives.

Match search results pages.

404

Match 404 (not found) requests.

URL

Match by request path (no host, no query string) with exact, partial, or regex. Regex matching is case-insensitive.

Note: the regex itself is also read as a URL path, so everything from its first ? or # is cut off. Write ^/groups/{0,1}$ instead of ^/groups/?$, and avoid (?:…) and lazy quantifiers such as .*?. To match query arguments, add a Query string condition.

Admin pages

Match specific admin screens including query arguments.

AJAX

Match AJAX actions by exact/partial/regex.

Shop pages

Match WooCommerce core pages.

Frontpage

Match the site front page URL.

Frontend

Apply only on frontend requests.

Everywhere

Apply globally to all contexts.

Query string

Match GET keys/values by exact/partial/regex.

HTTP header

Match HTTP headers (keys normalized to HTTP_*).

Match cookies by key/value with exact/partial/regex.

Post data

Match POST payload (supports regex), preserving plus signs.

User agent

Match UA by exact/partial/regex.

User

Target user roles (including Not logged in).

Device

Match desktop, phone, tablet, Android, iOS, or bots.

Cronjob

Apply for cron runs.

CLI

Apply for WP-CLI runs.

FAQ

Can I test WP Shifty before I buy?

Yes. There’s a 14-day money-back guarantee—buy risk-free and refund within 14 days if it’s not a fit.

Is WP Shifty suitable for beginners?

It’s designed to be easy, but it’s a pro tool. Basic WordPress and performance knowledge is recommended.

How can I know which resources or plugins should be disabled?

Click Lighthouse test in the editor’s Live tab, then Run mobile test or Run desktop test. It lists the render-blocking resources and the unused CSS/JS of the previewed page, which are good candidates for Disable or Load behavior rules. The test runs through the WP Shifty API, so it is not available on localhost. Then disable the candidates in Live Preview and verify the page and its interactive features.

Can I buy WP Shifty now?

Yes, purchase is available anytime; activation is a simple connect flow from the dashboard.

How is WP Shifty different from other optimization plugins?

Shifty focuses on conditional loading and selective disabling/rewiring of assets and plugins with a live, scenario-based editor.

Is WP Shifty a cache plugin?

No. It’s not a cache; it controls what loads and when. You can use it alongside caching plugins.

Developers

Actions

  • wp_shifty_match — Fired when at least one scenario should run.
  • wpshifty_collect_resource (type, src, node) — Collected each matching CSS/JS (file or inline).
  • wpshifty_disable_resource (type, src) — A resource was removed.
  • wpshifty_overwrite_resource (type, original, new) — A resource was replaced.
  • wpshifty_lazyload_resource (type, src) — A resource was marked for lazy loading.
  • wpshifty_plugin_disabled (plugin) — A plugin was disabled by a scenario.

Filters

  • wp_shifty_dom (html) — Final HTML just before output buffering ends.
  • wp_shifty_current_user_role (role) — The role the User condition checks for a logged-in visitor. WP Shifty reads it from the login cookie before WordPress loads the current user.

Note: WP Shifty evaluates scenarios while plugins are being loaded (its MU loader loads it early). wp_shifty_match, wpshifty_plugin_disabled and wp_shifty_current_user_role therefore run before regular plugins and the theme. Hook them from an MU plugin whose file name sorts before __wps-loader.php, e.g. wp-content/mu-plugins/__a-shifty-hooks.php.

DOM placeholders

WP Shifty uses HTML comment placeholders to inject content or scripts at render time:

  • <!--[if wpshifty]>WP_SHIFTY_HEAD_BEGINNING<![endif]-->
  • <!--[if wpshifty]>WP_SHIFTY_HEAD_AFTER_STYLES<![endif]-->
  • <!--[if wpshifty]>WP_SHIFTY_HEAD_END<![endif]-->
  • <!--[if wpshifty]>WP_SHIFTY_FOOTER_BEGINING<![endif]-->
  • <!--[if wpshifty]>WP_SHIFTY_FOOTER_END<![endif]-->
  • <!--[if wpshifty]>WP_SHIFTY_PRELOAD<![endif]--> — replaced by generated <link rel="preload"> tags.
  • <!--[if wpshifty]>WP_SHIFTY_LAZY<![endif]--> — replaced with the lazy helper script when needed.

Safeguards

Disable switch (?noshifty)

Append ?noshifty=1 to any URL to bypass WP Shifty entirely for that request. No scenarios are evaluated, no plugins are disabled, and no DOM/post-processing happens. This is ideal for troubleshooting or quick A/B checks.

https://example.com/shop?ref=ad
https://example.com/shop?ref=ad&noshifty=1

Note: The parameter is only used by Shifty; it does not affect WordPress routing.

JSON bypass

When a response is sent with a Content-Type: application/json header (REST API, wp_send_json() admin-ajax responses), WP Shifty returns the payload unchanged and skips all HTML DOM manipulation.

  • Detection relies only on that header. A JSON response sent as text/plain or text/html is processed like an HTML page and can be corrupted. Keep such endpoints out of the scenario with an Exception condition (Query string, AJAX or URL).
  • Plugin rules still apply. If a scenario matches a REST or AJAX request, the plugins it disables are not loaded for that request.

Per-resource skip

Add data-skip-shifty to a <script>, <style>, or <link rel="stylesheet"> tag to exclude it from Shifty’s HTML processing (disable/overwrite/lazy/async/defer).

<script src="/js/critical.js" data-skip-shifty></script>
<link rel="stylesheet" href="/css/critical.css" data-skip-shifty>

Note: a Disable rule also removes matching enqueued files (wp_enqueue_script / wp_enqueue_style) before their tags are printed, so the attribute cannot protect them. Make the rule more specific instead (Exact match or a tighter Regex).

MU Loader and plugin disabling

For plugin deactivation to work reliably, WP Shifty installs an MU loader file wp-content/mu-plugins/__wps-loader.php. If it cannot be created, an exception is raised and disabling plugins will not work. Ensure the MU plugins directory is writable.

Deactivation and uninstall

When you click Deactivate on the Plugins screen, WP Shifty asks Would you like to keep settings after uninstall WP Shifty?

  • Yes: scenarios and settings stay in the database after you delete the plugin, ready for a reinstall.
  • No: deleting the plugin drops the scenarios table and removes all wp-shifty* options.

Deactivating alone never deletes anything. Deleting the plugin always removes the MU loader (__wps-loader.php). Overwritten and injected files in wp-content/uploads/wp-shifty/ stay in place.

Resource matching details

  • Match modes: exact, partial, regex.
  • Versioning: file URLs are normalized to include versions; matching respects ver args.
  • Inline resources: Exact match uses a hash of the whole tag (whitespace ignored). If the inline code changes, for example because of nonces, per-user data or a plugin update, the hash changes and the rule stops matching. For dynamic inline CSS/JS, use Partial or Regex match on a distinctive part of the tag, such as its id attribute.
  • Preload: disabled resources are skipped; if a source was overwritten, preload uses the overwritten URL.
  • Skip processing: add data-skip-shifty attribute to a tag to exclude it from Shifty’s HTML processing. It does not stop a Disable rule from dequeuing an enqueued file (see Per-resource skip).

Examples:

// URL exact
/products/sale

// URL partial (matches /products/sale and /products/sale/summer)
/products/sale

// URL regex (matches any year under /archive/)
^/archive/20[0-9]{2}/$

// Inline resource matching
// Exact match: hash of the whole tag (whitespace ignored), changes with the inline code
// Partial / Regex: tested against the tag's full HTML, e.g. id="my-inline-css"

Evaluation & Priority

  • Scenario order: active scenarios are loaded by priority DESC, id ASC.
  • Preview: when editing, the preview scenario is applied in isolation and won’t be loaded with other actives; an empty preview shows a placeholder and a special CLI view is available via ?wpshifty-cli=1.
  • Execution flow: when any scenario matches, output buffering is started early and HTML is post-processed to apply rules; scripts/styles are dequeued via wp_print_* / admin_print_* hooks.
  • Toolbar context: matched scenario IDs are exposed for quick edit links.

Changelog

1.2.0 – 2026-10-08

  • [FIX] Overwriting a JS file removed the script from the page instead of loading the new file
  • [FIX] Activating or deactivating any plugin (WP Shifty included) deactivated the plugins that a scenario disables on the Plugins screen
  • [FIX] PHP 8 fatal error on the dashboard and in the editor when a scenario has a Search condition
  • [FIX] Requests of logged-out visitors to admin-post.php (used by some front-end forms) were redirected to the WP Shifty settings page
  • [FIX] Previewing with a user role other than Administrator left the Live panel of the editor empty
  • [FIX] Preview: lazy loaded scripts are listed with their address and marked as lazy loaded
  • [FIX] Preview test values of regex conditions now match character ranges (eg [a-z]) and longer repetitions (eg {10,20})
  • [FIX] The dashboard no longer waits up to 30 seconds (or fails) when the license server can’t be reached: the license status shows “unreachable” and the scenarios stay available
  • [FIX] Dashboard summary: partial and regex rules no longer cause a PHP warning, and load behavior (async, defer, lazy) rules are listed instead of “No rule set”
  • [FIX] Condition summary now shows OR between conditions and between exceptions, matching how they are evaluated
  • [FIX] Drag and drop ordering on the dashboard (jQuery UI Sortable was not loaded)
  • [FIX] “Add rule to current post type” in the admin bar now creates the post type condition
  • [FIX] Plugin icons in the dashboard summary
  • [FIX] Duplicating a scenario without overwrite rules no longer causes PHP warnings, and duplicating a scenario that was deleted in the meantime no longer leaves a broken entry
  • [FIX] Multisite uninstall now cleans up each site’s own table and options
  • [FIX] Zero-byte resources now show “0 Bytes” instead of “unknown”
  • [FIX] More reliable handling of unexpected responses from the API
  • [FIX] Minor bugfixes

1.1.4 – 2026-07-02

  • [IMPROVE] Updated device detection library for better recognition of newer devices and bots
  • [IMPROVE] PHP 8.x compatibility (removed deprecation notices and undefined index/offset warnings)
  • [FIX] URL condition matching for URLs containing encoded commas, colons and semicolons
  • [FIX] Regex user agent condition was not evaluated correctly
  • [FIX] More reliable parsing of custom request headers
  • [SECURITY] Minor security improvement

1.1.3 – 2026-03-05

  • [FIX] PHP warnings in WP-CLI/cron environment when URL conditions are evaluated

1.1.2 – 2025-04-08

  • [FIX] Minor Bugfixes

1.1.1 – 2025-03-18

  • [NEW] 404 Request condition
  • [NEW] Edit matching rules from topbar
  • [FIX] Minor Bugfixes

1.1 – 2024-11-06

  • [IMPROVE] Must-Have Plugins license management added
  • [FIX] Minor Bugfixes

1.0.14 – 2024-09-30

  • [NEW] Rule order can be changed
  • [NEW] Rules can be named
  • [IMPROVE] Minor improvements

1.0.13 – 2024-04-29

  • [FIX] Rule editor bug with Admin pages

1.0.12 – 2024-03-25

  • [FIX] PHP Compatibility fix

1.0.11 – 2024-02-29

  • [FIX] PHP Compatibility fix

1.0.10 – 2024-02-12

  • [FIX] PHP Compatibility fix

1.0.9 – 2023-12-11

  • [FIX] Minor bugfixes
  • [IMPROVE] Regular Expression Support for Post Data Condition

1.0.8 – 2023-10-25

  • [FIX] CPT category detection issues

1.0.7 – 2023-08-24

  • [FIX] Minor code improvements

1.0.6 – 2023-01-30

  • [FIX] Rank Math compatibility issue

1.0.5 – 2023-01-28

  • [FIX] Post type mismatch
  • [IMPROVE] Hide preview data for non-admin users

1.0.4 – 2023-01-27

  • [FIX] Minor bugfixes
  • [FIX] Custom Post Type issues

1.0.3 – 2022-07-30

  • [FIX] Minor bugfixes
  • [FIX] Not logged in user role issue in editor

1.0.2 – 2022-05-31

  • [FIX] Minor bugfixes
  • [IMPROVE] RTL compatibility

1.0.1 – 2022-04-19

  • [FIX] Minor bugfixes
  • [FIX] Firefox lazyload script issue

1.0 – 2022-03-21

  • [FIX] Minor bugfixes
  • [NEW] Duplicate scenario

0.1.14 – 2022-02-18

  • [FIX] Elementor editor issue

0.1.13 – 2022-02-18

  • [IMPROVE] Compatibility improvements
  • [IMPROVE] Better error messages if network error occured in editor
  • [FIX] Remove the unecessary lazyload option for inline styles
  • [FIX] Minor fixes

0.1.12 – 2022-02-04

  • [IMPROVE] Compatibility improvements
  • [NEW] Add comment to source

0.1.11 – 2022-01-18

  • [FIX] Minor fixes
  • [IMPROVE] Add more devices/screen sizes

0.1.10 – 2022-01-14

  • [IMPROVE] Minor improvements
  • [NEW] Check preview in new tab

0.1.9 – 2022-01-08

  • [FIX] Minor bugfixes
  • [NEW] Cronjob condition
  • [NEW] CLI condition
  • [NEW] Apply wp_shifty_match action when conditions are met

0.1.8 – 2021-12-11

  • [FIX] Fix relative URLs for overwrite CSS
  • [FIX] Fix missing size badge

0.1.7 – 2021-12-06

  • [NEW] Add Lighthouse testing
  • [NEW] Add ?noshifty mode

0.1.5 – 2021-12-05

  • [FIX] PHP warnings & errors

0.1.4 – 2021-12-04

Initial Release

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only