Directory / plugin
PagePulse
v1.0.1 · by Mahesh Thorat
Loading experiences for WordPress: page transitions, 33 CSS loaders, element, form, AJAX and WooCommerce loaders, progress bars, skeletons and an API.
About this plugin
PagePulse shows clear, good-looking feedback whenever visitors wait: while a page loads, when they follow a link, submit a form, add a product to the cart, or when your own scripts fetch data. It is built to be safe on real sites: it never delays navigation, never changes how forms submit, never leaves a page covered, and never loads files a page does not need.
PagePulse improves perceived loading. It does not make your pages load faster, and it is designed not to make them slower: no jQuery, CSS-only animations, a deferred script, and only the CSS of the loaders you use.
Loading modes
- Initial page loading – a full-screen loader from the first paint until the page is ready (DOM ready or full load). Whole site, homepage, selected post types, page IDs or URL patterns; desktop only, mobile only, or once per visit. Without JavaScript it never appears, and it always removes itself after a maximum time, even if a script fails.
- Page navigation – overlay and/or a progress bar when a visitor follows an internal link: menus, archives, pagination, search. Never for external links, downloads,
mailto:/tel:, new tabs, Ctrl/⌘-clicks, in-page anchors, the dashboard or the login page. - Element loader – a loader inside any element (overlay, inline or skeleton), from dashboard rules,
data-pagepulseattributes or the JavaScript API. - Form submissions – spinner in the submit button, overlay on the form, or full-screen, shown only after the browser accepted the submission. Contact Form 7, WPForms, Gravity Forms, Ninja Forms and WooCommerce product/cart forms are supported. Checkout, payment, login and account forms are never touched.
- AJAX requests – feedback for the requests you choose (admin-ajax.php actions, REST routes or URL patterns). Background, analytics and heartbeat requests never show anything. jQuery requests are observed through jQuery’s own events; watching
fetch()/XMLHttpRequestis opt-in. - WooCommerce – add-to-cart button spinner (classic and block buttons), variation lookups, cart updates, coupons, shipping, mini-cart removals and product filters.
- Progress indicators – top/bottom bar or corner ring. Indeterminate (or a clearly labelled estimate) when progress cannot be measured; real percentages only for measured upload/download progress.
- Skeleton placeholders –
[pagepulse_skeleton]shortcode and a Skeleton placeholder block: text, image, card, avatar, table, product, list and custom shapes, with wrapped content revealed when loading finishes. Optional shimmer placeholders for images.
Animation library
33 loaders in four groups, every one pure CSS (with a little SVG) and configurable in colour, size, speed, direction and intensity:
- Classic: circular spinner, dual ring, three dots, bouncing dots, pulse circle, rotating square, wave bars, bar loader, progress ring, orbit, ripple, minimal rotating line.
- Modern: gradient spinner, liquid fill, morphing shape, expanding rings, elastic dots, animated gradient border, glowing pulse, rotating gradient, smooth wave, minimal line.
- Brand: website logo, custom image, text shimmer, brand colours, custom SVG.
- Creative: typing, letter by letter, logo reveal, circular text, geometric, and a custom keyframes builder.
The seven transitions of PagePulse 0.1 are kept (slide top-bottom, slide bottom-top, fade, clip top/bottom, clip left/right, animated slides) plus zoom fade and none.
Dashboard
Settings PagePulse has an overview, the animation library, loading triggers, a live builder with desktop/mobile preview and contrast check, ten presets plus your own, advanced settings, tools (frontend preview, compatibility diagnostics, recent errors, export/import, restore defaults, safe mode, temporary disablement) and developer documentation. The builder and its preview load only in the dashboard.
Accessibility
- Loading states are announced through a polite live region; busy regions get
aria-busy, buttonsaria-busyandaria-disabled, progress barsrole="progressbar"with real values only. - Visitors who prefer reduced motion get a static indicator with text, a gentle fade or text only (your choice).
- Esc closes a full-screen loader; Tab dismisses the page-load overlay. Keyboard users are never trapped.
- The page-load overlay is decorative: content underneath stays available to screen readers.
Works with
Tested with WordPress 5.8, 6.1 and 7.1 on PHP 7.4 and 8.4; block and classic themes (Twenty Twenty-Five, Twenty Twenty-One, Storefront, Astra); Gutenberg, Elementor, WooCommerce (block and classic shop, classic cart), Contact Form 7, WPForms, Ninja Forms and the AJAX Loading plugin (1.1, and the 2.x event contract). The Gravity Forms integration (AJAX iframe mode) follows that plugin’s documented events. Caching and optimisation plugins are supported (see FAQ). PagePulse stays out of page-builder editing canvases (Elementor, Beaver Builder, Divi, Bricks, Oxygen).
AJAX Loading integration
When AJAX Loading is active, it loads the content and PagePulse shows the transition. PagePulse listens to AJAX Loading’s lifecycle events (wp_ajax_load_start, wp_ajax_load_complete, wp_ajax_load_error, wp_ajax_load_cancel in 2.x; History.js state changes in 1.x), keeps a single overlay (AJAX Loading’s own indicator and 1.x page dimming are not shown at the same time) and respects PagePulse’s link exclusions. Neither plugin requires the other. Turn the integration off under Loading triggers Page navigation.
For developers
window.PagePulse (no dependencies):
const h = PagePulse.show({ type: 'dots', text: 'Saving…' }); h.hide();
PagePulse.element.show('.product-container');
PagePulse.element.hide('.product-container');
PagePulse.button.show('#save', { text: 'Saving…' });
PagePulse.progress.set(60); // measured progress only
PagePulse.track(fetch(url), { target: '#results' });
Loaders are reference counted (finishing one operation never hides a loader another operation still needs) and every loader times out on its own. Data attributes (data-pagepulse, data-pagepulse-target…), DOM events (pagepulse:start/pagepulse:end in, pagepulse:show/hide/timeout… out) and PHP hooks (pagepulse_should_load, pagepulse_frontend_config, pagepulse_animations, pagepulse_presets, pagepulse_overlay_markup…) are documented on the Developers tab and in DEVELOPERS.md.
Privacy
PagePulse loads no remote files, sets no cookies and sends nothing to third parties. “Only on the first page of a visit” uses the browser’s sessionStorage. Debug mode records PagePulse’s own JavaScript errors for administrators only.
Configuration guide
- Animations – choose a loader and the overlay transition. Brand loaders use your site title, logo, an image or an SVG.
- Loading triggers – decide when PagePulse appears: initial loading (pages, devices, timing), navigation (overlay, progress bar, scope and exclusions), element rules, forms, AJAX rules, WooCommerce.
- Design – background (colour, gradient, opacity, blur), colours, size, speed, layout (full-screen, floating panel, top of page), message, logo, timing, progress indicator, reduced-motion and mobile behaviour, skeleton colours. Everything previews live; Save as preset stores a design.
- Advanced – administrators only, safe mode, debug mode, URL exclusions, custom CSS (requires the
edit_csscapability). - Tools – frontend preview, diagnostics, recent errors, export/import, restore defaults, temporary disablement.
Clear your page cache after changing settings.
Element loader
Mark an element and call the API:
<div class="product-container" data-pagepulse="true" data-pagepulse-loader="dots">…</div>
<button data-pagepulse-target=".product-container">Load more</button>
The button shows a loader on .product-container until its content changes (or the maximum time). Without code, add a rule under Loading triggers Element loading: while the page loads, after a click until the content changes or during matching AJAX requests.
Skeletons
[pagepulse_skeleton type="card" count="3" /]
[pagepulse_skeleton type="product" count="4" columns="4" until="load"]…your content…[/pagepulse_skeleton]
Types: text, image, card, avatar, table, product, list, custom. Options: count, lines, rows, columns, width, height, until (load, delay, manual), delay, max, label, class. Use the self-closing form (/]) when a page mixes standalone and wrapping skeletons. Standalone placeholders are replaced by your script (PagePulse.skeleton.replace(el, html)) or removed after max milliseconds.