Skip to main content
Login Join
Snippet · PHP

Lazy Load Images in Widget Areas Without a Plugin

Shared by Jainil Nagar · June 15, 2026 · @widget_text, dynamic_sidebar_params

2 views
Back to Snippets

This applies the loading="lazy" attribute to all images inside widget areas using a safe regex with no DOM parsing overhead.

/**
 * Add loading="lazy" to all images rendered inside WordPress widget areas.
 * Skips images that already have a loading attribute or are marked eager.
 *
 * No JavaScript, no plugin, no DOM parser — pure regex on widget HTML output.
 */

// ─── Apply to text widgets (classic widget text) ──────────────────────────────

add_filter( 'widget_text', 'wpfolks_lazy_load_widget_images', 20 );

// ─── Apply to all widget output via output buffering ─────────────────────────

add_filter( 'dynamic_sidebar_params', 'wpfolks_buffer_widget_output' );
function wpfolks_buffer_widget_output( array $params ): array {
    ob_start( 'wpfolks_lazy_load_widget_images' );
    return $params;
}

// ─── Core transformer — reusable by both hooks ───────────────────────────────

function wpfolks_lazy_load_widget_images( string $content ): string {
    if ( empty( $content ) ) return $content;

    // Match <img> tags that don't already have a loading attribute
    return preg_replace_callback(
        '/<imgb([^>]*?)>/i',
        function ( array $matches ): string {
            $tag   = $matches[0];
            $attrs = $matches[1];

            // Skip if loading attribute already present
            if ( preg_match( '/bloadings*=/i', $attrs ) ) {
                return $tag;
            }

            // Skip WordPress-generated no-lazy markers
            if ( strpos( $attrs, 'data-no-lazy' ) !== false ) {
                return $tag;
            }

            // Insert loading="lazy" before the closing >
            return '<img' . $attrs . ' loading="lazy">';
        },
        $content
    ) ?? $content;
}