WP Manifestindependent plugin directory
manifest / builders / elementor-css-regenerator

Elementor CSS Regenerator WP Registry grade B. Medium-severity findings · 2 findingsWP RegistryMedium-severity findings · 2 findingsOpen the reportB #3 in Page Builder Addons

Regenerates Elementor CSS files on demand.

★ 14stars
601release downloads
≈120active sites
1.1.0latest · 1mo ago

Install

Download elementor-css-regenerator-1.1.0.zip From the 1.1.0 release on GitHub, Sep 1, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/robwent/elementor-css-regenerator/releases/download/1.1.0/elementor-css-regenerator-1.1.0.zip
Updates itself. It ships its own updater, so new versions appear under Dashboard → Updates.

Requires: WordPress 5.0+, Elementor, PHP 7.4+

The Problem

When Elementor updates or when you manually clear Elementor's CSS cache, all generated CSS files in /wp-content/uploads/elementor/css/ are deleted. This creates a critical issue with cached pages:

  1. Cached pages still reference the old CSS files (e.g., post-71783.css?ver=1760646381)
  2. Files don't exist anymore - they were deleted by Elementor
  3. CSS won't regenerate because users are served the cached HTML (WordPress never runs)
  4. Users see broken pages until cache expires or is manually cleared

This is especially problematic with:

  • Page caching plugins (W3 Total Cache, WP Rocket, etc.)
  • CDN caching (Cloudflare, KeyCDN, etc.)
  • Server-level caching (Varnish, Nginx FastCGI)
  • Template-based pages (one template = hundreds of cached pages affected)

The Solution

This plugin intercepts 404 requests for missing Elementor CSS files and:

  1. Detects the missing CSS file request
  2. Regenerates the file using Elementor's API
  3. Serves the file immediately to the user
  4. Caches the regenerated file for subsequent requests

Result: First visitor after cache clear gets their CSS generated on-demand. No broken pages, no manual cache clearing needed.

How It Works

Request Flow

Cached Page Loads
    ↓
References: post-71783.css?ver=1760646381
    ↓
File Doesn't Exist (404)
    ↓
Plugin Intercepts (before 404 template)
    ↓
Validates Post & Elementor Usage
    ↓
Regenerates CSS File
    ↓
Serves File with Proper Headers
    ↓
User Receives CSS (No Broken Styles!)
    ↓
Subsequent Requests: File Exists (Served by Web Server)

Technical Details

  • Hook: template_redirect (priority 1, before 404 template loads)
  • Detection: Fast strpos() check eliminates non-Elementor 404s, then minimal regex on filename only
  • Query Strings: Automatically strips cache-busting parameters like ?ver=1760646381
  • Race Conditions: Uses WordPress transients to prevent duplicate regeneration
  • Validation: Checks post exists and is built with Elementor before regenerating
  • Error Handling: Logs errors when WP_DEBUG is enabled

Supported File Types

  • post-{id}.css - Individual page/post CSS
  • loop-{id}.css - Loop template CSS (also uses Post class internally)

Installation

Method 1: ZIP Install

  1. Download the latest ZIP package from the releases page
  2. WordPress Admin > Plugins > Add New > Upload Plugin
  3. Activate the plugin

Method 2: Direct Upload

  1. Download the elementor-css-regenerator folder
  2. Upload to /wp-content/plugins/
  3. Activate via WordPress Admin > Plugins

Requirements

  • WordPress 5.0 or higher
  • Elementor (free or Pro)
  • PHP 7.4 or higher

Compatibility

Works with all caching solutions:

  • ✅ W3 Total Cache
  • ✅ WP Rocket
  • ✅ WP Super Cache
  • ✅ LiteSpeed Cache
  • ✅ Cloudflare APO
  • ✅ KeyCDN
  • ✅ Varnish
  • ✅ Nginx FastCGI Cache
  • ✅ Server-level caching

Performance Impact

  • First request: ~100-500ms delay while CSS regenerates (one-time per file)
  • Subsequent requests: Zero impact (file exists, served by web server)
  • Lock mechanism: Prevents multiple simultaneous regenerations
  • No database queries: Only runs on actual 404s for CSS files

Frequently Asked Questions

Does this replace Elementor's CSS regeneration?

No, this complements it. Elementor still handles CSS generation normally. This plugin only activates when a CSS file is missing and requested.

Will this slow down my site?

Only the first request to a missing CSS file experiences a small delay. After regeneration, files are served normally by your web server/CDN.

Do I need to clear my cache after Elementor updates?

No, that's the point! This plugin eliminates the need to clear cache after Elementor CSS clears.

What about template-based pages?

Works perfectly. When a cached page using a template is visited, both the page CSS and template CSS are regenerated on-demand.

Does this work with Elementor Pro?

Yes, works with both free and Pro versions.

What if my site uses Cloudflare?

Perfect! The plugin regenerates the file, Cloudflare caches it, and all subsequent requests are served from Cloudflare's edge network.

Troubleshooting

CSS files still returning 404

  • Verify Elementor is active and loaded
  • Check file permissions on /wp-content/uploads/elementor/css/
  • Enable WP_DEBUG and check error logs

Files regenerate but styles still broken

  • Check if your caching plugin is caching 404 responses
  • Verify .htaccess is properly configured to pass 404s to WordPress
  • Test with caching disabled to isolate the issue

Race condition errors

  • Increase the transient lock timeout in code (default: 30 seconds)
  • Check server resources (high load may cause timeouts)

Changelog

1.0.0 (2025-10-17)

  • Initial release
  • On-demand CSS regeneration for missing Elementor files
  • Support for post and loop CSS files
  • Proper HTTP 200 status headers when serving regenerated files
  • Performance optimized detection (fast strpos + minimal regex)
  • Race condition prevention with transient locks
  • Automatic query string handling
  • Validation for post existence and Elementor usage
  • Comprehensive debug logging when WP_DEBUG enabled
  • Works with all major caching solutions

License

GPL v2 or later - https://www.gnu.org/licenses/gpl-2.0.html

This plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation.

Releases

2 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
1.1.0 latest
Sep 1, 2026 1mo ago
elementor-css-regenerator-1.1.0.zip
480
Oct 17, 2025 1 year ago
elementor-css-regenerator.zip
121

Active-site estimate ≈120 comes from the median of recent superseded releases. Method.

B grade

Security

Elementor CSS Regenerator 1.1.0 · audited by WP Registry

Medium-severity findings.

2 medium
Audited release
1.1.0
Findings
2
Worst severity
medium
Content hash
4ea5d93677a090870585035b…

Findings

  • medium Unauthenticated 404 substring match force-regenerates Elementor CSS for any document

    dos

    intercept_css_404 runs on template_redirect for every unauthenticated 404. is_elementor_css_request() only requires that REQUEST_URI contains the substring '/elementor/css/' and that basename(strtok($uri,'?')) matches /^(post|loop)-(\d+)\.css$/. It does not require the URI to be wp_upload_dir()['baseurl']/elementor/css/… and regenerate_and_serve_css() never checks that the real file is missing before Post::create($id)->update(). Consequently GET /not-a-real-path/elementor/css/post-123.css (any path that makes is_404() true) regenerates document 123 even when uploads/elementor/css/post-123.css already exists, writes _elementor_css meta, and occupies a PHP worker. The per-id transient lock (elementor_css_regen_{type}_{id}, 30s) plus sleep(1) on contention only serializes one id; an attacker walks published Elementor post ids in parallel and repeats after the lock. This is the plugin's intended public handler, but the missing uploads-path and file-exists gates turn a one-shot 'missing file' repair into an unbounded CPU/IO hammer. Filename type is constrained to post|loop and id is int-cast, so this is not path traversal or arbitrary file write.

    elementor-css-regenerator.php:75-86

    Recommendation

    Resolve the expected path as wp_upload_dir()['basedir'] . '/elementor/css/' . $filename and return unless REQUEST_URI (minus query string) maps to that file. If file_exists($css_file_path), serve or return without calling $css_file->update(). Rate-limit regeneration (already have a lock; keep it until the file exists, and do not sleep() in the web request). Optionally require the request to be a direct static-file 404 under the uploads host path, not any 404 that happens to contain the substring.

  • medium CSS regeneration/serve does not check whether the requester can read the post

    information_disclosure

    After the URI parse, regenerate_and_serve_css() only calls get_post($id) (any status: draft, private, future, trash, auto-draft) and documents->get($id)->is_built_with_elementor() (the _elementor_edit_mode meta). There is no is_post_publicly_viewable(), no current_user_can('read_post', $id), and no post_password_required() check. get_doc_for_frontend($id) in Elementor core likewise does not test publish state unless a preview nonce is present. An unauthenticated visitor who can guess sequential post ids can therefore force Post::create($id)->update() for unpublished Elementor documents and receive the generated stylesheet as HTTP 200 text/css with Cache-Control: public, max-age=31536000. The CSS is not post_content, but it routinely embeds background-image / mask-image URLs and author-supplied custom CSS for embargoed pages. Elementor itself writes these files into a public uploads directory when an editor saves, so this is the on-demand generation path after a CSS flush (or when no file was ever written) rather than a full content IDOR; still, without this plugin those files would not be recreated until someone who can edit/view the document opened it.

    elementor-css-regenerator.php:132-157

    Recommendation

    Before regenerate/serve, require the current user can read the document: typically is_post_publicly_viewable($post) || current_user_can('read_post', $id), and skip post_password_required() posts for anonymous users. For Elementor library/theme-builder documents that are publish-status but not singular-viewable, allow regeneration only when the document type is one Elementor actually enqueues on the public frontend (published theme-builder locations), not drafts/private/trash. Do not send Cache-Control: public on CSS generated for non-public documents.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.