Fulgur Cache
Open-source WordPress caching plugin with static cache, critical CSS, delayed JavaScript, AVIF/WebP and instant navigation. Includes a Claude-powered AI optimizer that verifies changes and automatically rolls back if performance worsens.
Install
This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.
Install straight from GitHub with WP-CLI:
wp plugin install https://github.com/jacckisback/fulgur-cache/archive/refs/heads/main.zip
Static page cache · Critical CSS · Delayed JavaScript · AVIF/WebP · Instant navigation · AI optimizer
Free and open source. No account, no license key, no “Pro” upsell.
Quick start · Features · AI optimizer · Configuration · Developers · FAQ · Français

The Fulgur dashboard in the WordPress admin (demo data).
Why Fulgur
⚡ Served before WordPressPages are stored as static HTML, pre-compressed with Brotli and gzip, and served by your web server or a tiny drop-in. No PHP execution, no database query. |
🎯 Critical CSS, no SaaSEach page gets only the CSS rules it actually uses, computed on your own server by a built-in CSS parser. No account, no quota, no third-party service. |
🧠 AI that checks its own workClaude reads your server, traffic and PageSpeed data and proposes settings. Fulgur applies them, measures again, and rolls back on its own if things get worse. |
🚀 Instant navigationSpeculation Rules prerender the next page while the visitor hovers a link. A 1 KB fallback prefetches on hover in Safari and Firefox. |
🖼️ Lighter mediaAVIF/WebP conversion, LCP image detection and preloading, native lazy-loading, YouTube facades and missing image dimensions added automatically. |
🛡️ Safe by designThree profiles, a “Test safely” preview, a risk label on every option, atomic file writes, one-click repair and a clean uninstall. |
Fulgur is Latin for lightning.
Quick start
- Download fulgur-cache.zip from the latest release.
- In WordPress, go to Plugins → Add New → Upload Plugin, install and activate.
- Pick a profile in the welcome screen. Balanced is recommended.
- Deactivate any other caching plugin (Fulgur detects 15 of them and warns you).
- Optional: open the AI Optimizer tab, connect your Anthropic API key and click Analyze and optimize my site.
With WP-CLI:
wp plugin install \
https://github.com/Jacckisback/fulgur-cache/releases/latest/download/fulgur-cache.zip \
--activate
wp fulgur profile balanced
wp fulgur preload
Requirements
| Minimum | Recommended | |
|---|---|---|
| WordPress | 6.2 | Latest version |
| PHP | 7.4 | 8.2 or later, with OPcache |
| Web server | Apache, LiteSpeed or Nginx | Apache or LiteSpeed (static rules are written automatically) |
| Permalinks | Any “pretty” structure | — |
| Optional | GD or Imagick (WebP), Imagick or PHP 8.1+ GD with AVIF (AVIF), PHP brotli extension |
An Anthropic API key for the AI optimizer |
[!NOTE] Early release. Fulgur is a young project. It is designed to fail safe (previews, backups, automatic rollback), but it has not yet been run on a wide variety of production sites. Try it on a staging copy first and open an issue if anything looks wrong.
Screenshots
One-click setup |
CSS & JavaScript |
Media |
Diagnostics |
Screenshots use demo data.
Features
Page cache
- Static HTML cache stored per host and URL, with Brotli (when the PHP
brotliextension is available) and gzip copies written next to it. - Served without PHP by
.htaccessrules on Apache/LiteSpeed (written automatically) or a copy-paste Nginx configuration; otherwise by theadvanced-cache.phpdrop-in, before WordPress loads, withETag/304 Not Modifiedsupport. - Smart purge: editing a post clears only that post, the home page, the posts page, its archive, categories, tags, author page and adjacent posts. Comments, term edits and WooCommerce stock changes are handled too. Site-wide changes (theme, menus, widgets, customizer, plugin updates, permalinks) clear everything.
- Preloading: after any purge, every public page is rebuilt in the background, most recently modified first, so visitors never hit a cold page.
- Smart bypass: logged-in users,
POSTrequests, carts, checkouts, accounts, search results, previews, password-protected posts, REST and admin URLs are never cached. Tracking parameters (utm_*,gclid,fbclid…) still get the cached page. - Atomic writes: files are written to a temporary name and renamed, so a visitor never receives a half-written page.
CSS
- Critical CSS / unused CSS removal computed per page by a PHP CSS parser (
@media,@supports,@layer,@container, CSS nesting,:is(),:not(), escaped class names such as Tailwind'smd\:flex). Unused@font-faceand@keyframesare dropped. In the test suite, a 646 KB stylesheet is reduced to the 20 KB a page actually uses. - Two modes: critical (full stylesheets load asynchronously right after rendering) and remove (full stylesheets load on the first interaction). In both modes the original
<link>tags stay in place, so the cascade order never changes. - Safelist for classes added by JavaScript (open menus, sliders, pop-ups), with sensible defaults.
- Minification of local stylesheets,
font-display: swapadded to@font-facerules, and Google Fonts hosted locally (GDPR-friendly, one connection less) or optimized withdisplay=swapand a preconnect.
JavaScript
- Defer with the original execution order preserved: inline scripts are turned into
data:URIs, and inline scripts that belong to an excluded WordPress script handle (-js-extra,-js-before,-js-after,-js-translations) stay with it. - Delay until first interaction (mouse, touch, keyboard, scroll), with an optional timeout. Delayed scripts run in their original order, then
DOMContentLoadedandloadlisteners are replayed so jQuery-ready code still works. - Separate exclusion lists for defer and delay. JSON-LD, templates, import maps and speculation rules are never touched.
Media
- WebP/AVIF conversion on upload, in bulk from the admin (with a progress bar), or on the fly for theme images. Variants are saved next to the originals (
photo.jpg.webp) and skipped when they would be heavier. Google reports WebP images 25–34% smaller than comparable JPEGs. - LCP detection: the first meaningful image at the top of the page (logos, icons and avatars are ignored) gets
fetchpriority="high"and a preload hint; the first images are never lazy-loaded. - Native lazy-loading for images and iframes, missing
width/heightadded to reduce layout shifts, and YouTube facades that load the player only on click.
Instant navigation and hints
- Speculation Rules: prefetch or prerender on hover, with exclusions for admin, carts, query strings and
nofollowlinks. On WordPress 6.8+, Fulgur configures the built-in speculative loading instead of adding a second set of rules. - Hover prefetching fallback for browsers without Speculation Rules.
Linkpreload headers for the LCP image and critical origins, which Cloudflare and compatible servers turn into 103 Early Hints.
WordPress cleanup, database, CDN
- Removes emoji scripts, embeds, Dashicons for visitors, RSD/WLW/shortlink/generator tags, jQuery Migrate (optional), XML-RPC; tunes or disables the Heartbeat API; removes WooCommerce
cart-fragmentsoutside shop pages. - Database cleanup (revisions, auto-drafts, trash, spam, expired transients, orphaned metadata, table optimization), manual or weekly.
- CDN URL rewriting for static files, and automatic Cloudflare purge (only the affected URLs when possible).
Admin experience
- Three profiles, an onboarding wizard that preloads and measures, a built-in server response test and mobile PageSpeed score.
- Test safely: preview any page with optimizations applied, without caching anything (
?fulgur_preview=1, admins only). - Admin bar menu (clear all, clear this page, preview), “Clear cache” link on posts and pages, import/export of settings.
- Diagnostics with one-click repair, conflict detection, and a dashboard of cache, preload and image stats.
- Interface in English and French; the AI optimizer answers in the admin's language.
How it works
flowchart LR
V([Visitor]) --> S{"Web server rules<br/>.htaccess / Nginx"}
S -- "cached" --> C[("Static HTML<br/>Brotli · gzip")]
S -- "otherwise" --> D{"PHP drop-in<br/>advanced-cache.php"}
D -- "HIT" --> C
D -- "MISS" --> W["WordPress<br/>+ Fulgur optimizer"]
W -- "store" --> C
- Web server. On Apache and LiteSpeed,
.htaccessrules servewp-content/cache/fulgur/<host>/<path>/index.html(or its.br/.gzcopy) directly. Nginx does the same with the provided configuration. - Drop-in. When no static rule applies,
advanced-cache.phpruns before WordPress, checks the bypass rules, negotiates Brotli/gzip and answers304 Not Modifiedwhen the browser already has the page. - Cache miss. WordPress renders the page once. Fulgur's optimizer then processes the HTML in this order: Google Fonts → CSS minification → images and iframes → critical CSS → JavaScript defer/delay → resource hints and speculation rules → CDN rewriting → HTML minification. The result is stored atomically with its compressed copies.
The AI optimizer

Recommendations waiting for approval (demo data).
The AI optimizer turns Fulgur's settings into a closed loop: measure → analyze → apply → verify → keep or roll back.
sequenceDiagram
autonumber
participant WP as Your WordPress
participant PSI as Google PageSpeed
participant AI as Claude (Anthropic API)
WP->>WP: Collect server, load and HTML metrics
WP->>PSI: Measure mobile and desktop
PSI-->>WP: Core Web Vitals and Lighthouse issues
WP->>AI: Technical report and settings reference
AI-->>WP: Diagnosis and justified changes (JSON)
WP->>WP: Validate, back up, apply your selection
WP->>PSI: Measure again
alt Score dropped, page broken or new JS errors
WP->>WP: Automatic rollback
else Same or better
WP->>WP: Keep and log to history
end
- Every change is justified. Claude is instructed to cite the measurement behind each recommendation and to rate its risk (no risk, test it, advanced). Advanced changes are unticked by default.
- Guardrails. Proposals are validated against the list of allowed settings and values. The AI can never disable the cache, touch the CDN or Cloudflare settings, or read your API keys. It only changes Fulgur settings, never your theme, plugins or content.
- Verification. After applying, Fulgur reloads the home page and, when PageSpeed is enabled, measures it again. It restores the previous settings if the page no longer renders, if the mobile score drops by more than 3 points, or if new JavaScript errors appear in the console.
- Learning from history. The last 10 runs (scores, changes, rollbacks) are sent with the next report, so a rolled-back setting isn't proposed again unchanged.
- Runs in the background through WP-Cron, step by step, so shared-hosting time limits are never hit. If WP-Cron is disabled, the admin page drives the steps itself.
- Autopilot (optional): a weekly analysis that either emails you the recommendations or applies only the no risk ones, with the same verification and rollback.
A technical report, never your content or your visitors' data:
- Server: web server software, PHP version and limits, OPcache usage, CPU cores, memory, load average, free disk space, object cache, Brotli/WebP/AVIF support, WP-Cron status, and the home page response time without and with cache.
- Load: pages served from the cache (sampled) and pages generated by WordPress over the last 7 days, average generation time, peak hour, peak memory.
- WordPress: version, locale, theme, active plugins (names and versions), number of published posts, pages and products, WooCommerce presence.
- Settings: current Fulgur settings, without CDN URL or Cloudflare credentials.
- Home page audit: HTML size, number of scripts and stylesheets, script paths, third-party domains, detected page builders, Google Fonts usage.
- PageSpeed (optional): mobile and desktop scores, Core Web Vitals, the main Lighthouse issues and the HTML snippet of the largest element, as reported by Google.
- Diagnostics and history of previous optimizations.
Requests use structured JSON output. With Claude Opus 5.5 and Sonnet 5.5, they also opt into Anthropic's server-side fallback, in case a safety classifier declines the request.
Cost. Usage is billed by Anthropic on your own API key. A typical analysis sends 8–15k tokens and receives 3–10k (including the model's reasoning). At Anthropic's published prices (checked October 2026), that is about:
| Model | Price per million tokens (input / output) | Estimated cost per analysis |
|---|---|---|
| Claude Opus 5.5 (default, most accurate) | $4 / $20 | $0.10 – $0.30 |
| Claude Sonnet 5.5 | $2 / $10 | $0.05 – $0.15 |
| Claude Haiku 5.5 | $0.10 / $0.50 | under $0.01 |
The exact token count is shown after each analysis. One analysis a week is plenty.
Setup. Paste your key in the AI Optimizer tab, or, safer, define it in wp-config.php:
define( 'FULGUR_ANTHROPIC_API_KEY', 'sk-ant-...' );
define( 'FULGUR_PSI_API_KEY', 'AIza...' ); // Optional: higher PageSpeed quota.
A PageSpeed Insights API key is free and avoids Google's anonymous rate limits. PageSpeed can only measure a site that is publicly reachable.
Profiles
Each profile applies the values below; every other setting keeps its current value. You can fine-tune anything afterwards.
| Safe | Balanced (default) | Turbo | |
|---|---|---|---|
| Page cache | ✅ | ✅ | ✅ |
| Minify HTML | ✅ | ✅ | ✅ |
| Minify CSS | — | ✅ | ✅ |
| Critical / unused CSS | off |
critical |
remove |
| Defer JavaScript | — | ✅ | ✅ |
| Delay JavaScript until interaction | — | — | ✅ |
| Lazy-load images | ✅ | ✅ | ✅ |
| Lazy-load iframes | ✅ | ✅ | ✅ |
| YouTube facade | — | ✅ | ✅ |
| WebP / AVIF | ✅ | ✅ | ✅ |
| Speculation Rules | prefetch |
prerender |
prerender |
| Google Fonts | swap |
swap |
local |
| Heartbeat API | reduce |
reduce |
disable_front |
Configuration reference
Settings are stored in the fulgur_settings option. Export and import them from Tools → Settings backup.
Cache
| Setting | Key | Default | Description |
|---|---|---|---|
| Page cache | page_cache |
on |
Serves each page as static HTML, before WordPress loads. |
| Cache lifespan (hours) | cache_lifespan |
10 |
Hours before a cached page is regenerated (0 = unlimited, smart purge is enough). |
| Compression and browser cache | browser_cache |
on |
Server compression + 1-year browser caching of static files (.htaccess). |
| Separate mobile cache | cache_mobile |
off |
Separate cache for mobile visitors. Only useful if the theme serves different HTML on mobile. |
| Cache 404 pages | cache_404 |
off |
Caches 404 pages (protects against bots). |
| URLs never cached | exclude_urls |
/cart/, /checkout/, /my-account/ … (9) |
Never cached. One pattern per line: part of a URL, a wildcard (*) or a regex (#…#). |
| Ignored URL parameters | ignored_query_params |
utm_source, utm_medium, utm_campaign … (15) |
Tracking parameters ignored when looking up the cache, so campaign links still get the cached page. |
| Cookies that disable the cache | exclude_cookies |
— | Extra cookie names (or prefixes) that bypass the cache. Login, comment and WooCommerce cart cookies are always handled. |
| Excluded user agents | exclude_user_agents |
— | User-agent substrings that bypass the cache. |
CSS & JavaScript
| Setting | Key | Default | Description |
|---|---|---|---|
| Minify HTML | minify_html |
on |
Removes comments and redundant whitespace from the HTML. |
| Minify CSS | minify_css |
on |
Minifies local stylesheets into cached copies (relative URLs rewritten). |
| font-display: swap | font_display_swap |
on |
Adds font-display:swap to @font-face rules. |
| Critical / unused CSS | css_mode |
off |
Off; critical (CSS used by the page inlined + full stylesheets loaded async, safe); remove (full stylesheets loaded only on first interaction, maximum gain, risk for elements added by JS). |
| CSS classes always kept | css_safelist |
is-, has-, active … (29) |
CSS class patterns always kept by css_mode (classes added dynamically by JS). |
| Google Fonts | google_fonts |
swap |
Off; swap (display=swap + preconnect); local (fonts hosted on the site, GDPR, one less connection). |
| Defer JavaScript | defer_js |
off |
Scripts deferred, order preserved, inline scripts turned into data URIs. |
| Scripts not deferred | defer_exclusions |
— | Patterns (URL or code) of scripts not to defer. |
| Delay JavaScript until interaction | delay_js |
off |
JavaScript runs only on first user interaction (huge TBT gain, risk for sliders/menus visible on load). |
| Force loading after (s) | delay_timeout |
0 |
Seconds before delayed scripts are forced to load (0 = interaction only). |
| Scripts loaded immediately | delay_exclusions |
fulgur-, recaptcha, cookie … (6) |
Patterns (URL or code) of scripts loaded immediately despite delay_js. |
Media
| Setting | Key | Default | Description |
|---|---|---|---|
| Lazy-load images | lazy_images |
on |
Native lazy-loading of offscreen images. |
| Top images never lazy-loaded | eager_images |
3 |
Number of above-the-fold images never lazy-loaded (the LCP image is detected and preloaded). |
| Add missing dimensions | image_dimensions |
on |
Adds missing width/height (CLS). |
| Lazy-load iframes | lazy_iframes |
on |
Native lazy-loading for iframes (maps, forms, embeds). |
| YouTube facade | youtube_facade |
on |
Thumbnail instead of the YouTube player until click. |
| WebP / AVIF | next_gen_images |
on |
WebP/AVIF conversion and serving. |
| Image format | image_format |
webp |
Webp (direct replacement) or avif ( AVIF+WebP, needs an AVIF encoder). |
| Conversion quality | image_quality |
78 |
Conversion quality 50-95. |
Preloading
| Setting | Key | Default | Description |
|---|---|---|---|
| Preload the cache | preload_cache |
on |
Rebuilds every page in the background after a purge. |
| Speculation Rules | speculation |
prerender |
Speculation Rules: off, prefetch, prerender (prerender = instant navigation but more server load). |
| Speculation trigger | speculation_eagerness |
moderate |
Conservative (on click), moderate (on hover), eager. |
| Hover prefetch (Safari / Firefox) | instant_fallback |
on |
Hover prefetch for Safari/Firefox. |
| Early Hints headers | early_hints |
on |
Preload Link headers (103 Early Hints). |
| Domains to preconnect | preconnect_domains |
— | Critical third-party domains to preconnect. |
WordPress cleanup
| Setting | Key | Default | Description |
|---|---|---|---|
| Disable emojis | disable_emojis |
on |
Removes the emoji script. |
| Disable embeds | disable_embeds |
on |
Removes the wp-embed script and oEmbed discovery links. |
| Remove Dashicons for visitors | dashicons_visitors |
on |
Removes Dashicons for visitors. |
| Clean the HTML head | clean_head |
on |
Cleans the HTML head. |
| Disable XML-RPC | disable_xmlrpc |
on |
Disables XML-RPC (careful with Jetpack / mobile app). |
| Remove jQuery Migrate | remove_jquery_migrate |
off |
Removes jQuery Migrate (risk with old plugins). |
| Heartbeat API | heartbeat |
reduce |
Heartbeat API: default, reduce (60 s), disable_front, disable. |
| WooCommerce cart-fragments | wc_cart_fragments |
on |
Removes WooCommerce cart-fragments outside shop pages. |
Database
| Setting | Key | Default | Description |
|---|---|---|---|
| Weekly database cleanup | db_auto_clean |
off |
Weekly cleanup: revisions, auto-drafts, spam and trashed comments, expired transients. |
| Revisions kept per post | db_revisions_keep |
5 |
Revisions kept per post by the cleanup. |
CDN & Cloudflare
| Setting | Key | Default | Description |
|---|---|---|---|
| CDN | cdn_enabled |
off |
Rewrites static file URLs (wp-content, wp-includes) to the CDN. |
| CDN URL | cdn_url |
— | CDN base URL, e.g. https://cdn.example.com. |
| Files excluded from the CDN | cdn_exclusions |
.php |
URL patterns never rewritten to the CDN. |
| Cloudflare API token | cloudflare_token |
— | API token with the Zone › Cache Purge permission; the Cloudflare cache is purged together with Fulgur's. |
| Cloudflare zone ID | cloudflare_zone |
— | Cloudflare zone ID of the domain. |
AI optimizer
| Setting | Key | Default | Description |
|---|---|---|---|
| AI model | ai_model |
claude-opus-5-5 |
Claude model used by the AI optimizer. |
| Autopilot | ai_auto |
off |
Off; suggest (weekly analysis, recommendations by email); auto (weekly analysis, safe changes applied, automatic rollback). |
| Include PageSpeed data | ai_psi |
on |
Adds Google PageSpeed mobile and desktop data to the report sent to Claude. |
Server setup
Apache and LiteSpeed. Nothing to do: Fulgur writes its rules at the top of .htaccess (between # BEGIN Fulgur Cache and # END Fulgur Cache) and removes them on deactivation. If .htaccess isn't writable, the cache still works through the PHP drop-in and the diagnostics tell you how to fix it.
.htaccess (default settings)
# BEGIN Fulgur Cache
<IfModule mod_mime.c>
AddType image/avif .avif
AddType image/webp .webp
AddType font/woff2 .woff2
</IfModule>
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/javascript application/json application/xml image/svg+xml font/ttf font/otf
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/css text/plain text/xml application/javascript application/json application/xml image/svg+xml
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/html "access plus 0 seconds"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
ExpiresByType image/x-icon "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType video/mp4 "access plus 1 year"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(css|js|avif|webp|jpe?g|png|gif|svg|ico|woff2?|ttf|otf|mp4|webm)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
<IfModule mod_mime.c>
AddEncoding br .br
AddEncoding gzip .gz
</IfModule>
<FilesMatch "\.html\.(br|gz)$">
<IfModule mod_headers.c>
Header set Content-Type "text/html; charset=UTF-8"
Header append Vary Accept-Encoding
</IfModule>
<IfModule mod_deflate.c>
SetEnv no-gzip 1
</IfModule>
<IfModule mod_brotli.c>
SetEnv no-brotli 1
</IfModule>
</FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} =""
RewriteCond %{REQUEST_URI} /$
RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_|wp\-postpass_|comment_author_|woocommerce_items_in_cart|wp_woocommerce_session_|edd_items_in_cart|fulgur_nocache) [NC]
RewriteCond %{REQUEST_URI} !/cart/ [NC]
RewriteCond %{REQUEST_URI} !/checkout/ [NC]
RewriteCond %{REQUEST_URI} !/my\-account/ [NC]
RewriteCond %{REQUEST_URI} !/panier/ [NC]
RewriteCond %{REQUEST_URI} !/commande/ [NC]
RewriteCond %{REQUEST_URI} !/mon\-compte/ [NC]
RewriteCond %{REQUEST_URI} !/carrito/ [NC]
RewriteCond %{REQUEST_URI} !/finalizar\-compra/ [NC]
RewriteCond %{REQUEST_URI} !/mi\-cuenta/ [NC]
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html.br" -f
RewriteRule .* "/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html.br" [L]
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} =""
RewriteCond %{REQUEST_URI} /$
RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_|wp\-postpass_|comment_author_|woocommerce_items_in_cart|wp_woocommerce_session_|edd_items_in_cart|fulgur_nocache) [NC]
RewriteCond %{REQUEST_URI} !/cart/ [NC]
RewriteCond %{REQUEST_URI} !/checkout/ [NC]
RewriteCond %{REQUEST_URI} !/my\-account/ [NC]
RewriteCond %{REQUEST_URI} !/panier/ [NC]
RewriteCond %{REQUEST_URI} !/commande/ [NC]
RewriteCond %{REQUEST_URI} !/mon\-compte/ [NC]
RewriteCond %{REQUEST_URI} !/carrito/ [NC]
RewriteCond %{REQUEST_URI} !/finalizar\-compra/ [NC]
RewriteCond %{REQUEST_URI} !/mi\-cuenta/ [NC]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html.gz" -f
RewriteRule .* "/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html.gz" [L]
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{QUERY_STRING} =""
RewriteCond %{REQUEST_URI} /$
RewriteCond %{HTTP:Cookie} !(wordpress_logged_in_|wp\-postpass_|comment_author_|woocommerce_items_in_cart|wp_woocommerce_session_|edd_items_in_cart|fulgur_nocache) [NC]
RewriteCond %{REQUEST_URI} !/cart/ [NC]
RewriteCond %{REQUEST_URI} !/checkout/ [NC]
RewriteCond %{REQUEST_URI} !/my\-account/ [NC]
RewriteCond %{REQUEST_URI} !/panier/ [NC]
RewriteCond %{REQUEST_URI} !/commande/ [NC]
RewriteCond %{REQUEST_URI} !/mon\-compte/ [NC]
RewriteCond %{REQUEST_URI} !/carrito/ [NC]
RewriteCond %{REQUEST_URI} !/finalizar\-compra/ [NC]
RewriteCond %{REQUEST_URI} !/mi\-cuenta/ [NC]
RewriteCond "%{DOCUMENT_ROOT}/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html" -f
RewriteRule .* "/wp-content/cache/fulgur/%{HTTP_HOST}%{REQUEST_URI}index.html" [L]
</IfModule>
# END Fulgur Cache
Nginx. The cache already works through the PHP drop-in. For fully static serving, add this to your server block (the same snippet, adapted to your paths, is in Tools → Nginx configuration) and reload Nginx:
# --- Fulgur Cache: static serving without PHP ---
set $fulgur_file "/wp-content/cache/fulgur/$host${uri}index.html";
set $fulgur_ok 1;
if ($request_method != GET) { set $fulgur_ok 0; }
if ($args != "") { set $fulgur_ok 0; }
if ($http_cookie ~* "(wordpress_logged_in_|wp-postpass_|comment_author_|woocommerce_items_in_cart|wp_woocommerce_session_|edd_items_in_cart|fulgur_nocache)") { set $fulgur_ok 0; }
if ($uri !~ /$) { set $fulgur_ok 0; }
if ($fulgur_ok = 0) { set $fulgur_file "/nonexistent"; }
gzip_static on; # serves index.html.gz when present
# brotli_static on; # uncomment if the ngx_brotli module is installed
location / {
try_files $fulgur_file $uri $uri/ /index.php?$args;
}
location ~* \.(css|js|avif|webp|jpe?g|png|gif|svg|ico|woff2?|ttf|mp4)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
access_log off;
}
Cloudflare. Create an API token with the Zone → Cache Purge permission, then paste it with your zone ID in the CDN tab. Fulgur purges the affected URLs on Cloudflare whenever it purges its own cache.
CDN. Enter your CDN URL (BunnyCDN, KeyCDN…) in the CDN tab: images, CSS, JavaScript and fonts from wp-content and wp-includes are rewritten to it.
WP-CLI
| Command | Description |
|---|---|
wp fulgur clear [--url=<url>] |
Clear the whole cache, or a single URL |
wp fulgur preload |
Preload every public page now, with a progress bar |
wp fulgur status |
Cache size and full diagnostics |
wp fulgur profile <safe\|balanced\|turbo> |
Apply a profile |
wp fulgur images |
Convert the whole media library to WebP/AVIF |
wp fulgur db |
Run every database cleanup task |
For developers
Filters
| Filter | Arguments | Purpose |
|---|---|---|
fulgur_is_cacheable |
bool $cacheable |
Prevent the current page from being cached |
fulgur_optimize_page |
bool $optimize |
Disable the optimizer on the current page |
fulgur_html_before / fulgur_html_after |
string $html |
Alter the HTML before or after optimization |
fulgur_purge_post_urls |
array $urls, int $post_id |
URLs purged when a post changes |
fulgur_preload_urls |
array $urls |
URLs to preload, in order |
fulgur_css_exclusions |
array $patterns |
Stylesheets never minified |
Actions: fulgur_purged_url ($url), fulgur_purged_all, fulgur_settings_updated ($new, $old), fulgur_images_converted ($count).
// Never cache the members area.
add_filter( 'fulgur_is_cacheable', function ( $cacheable ) {
return is_page( 'members' ) ? false : $cacheable;
} );
// Also refresh the shop page whenever a product changes.
add_filter( 'fulgur_purge_post_urls', function ( $urls, $post_id ) {
if ( 'product' === get_post_type( $post_id ) && function_exists( 'wc_get_page_permalink' ) ) {
$urls[] = wc_get_page_permalink( 'shop' );
}
return $urls;
}, 10, 2 );
// Preload the pricing page first.
add_filter( 'fulgur_preload_urls', function ( $urls ) {
array_unshift( $urls, home_url( '/pricing/' ) );
return $urls;
} );
HTML opt-outs: add data-fulgur-skip to a `
This README is longer than the copy stored here. Read the rest on GitHub →