• Resolved George Sexton

    (@gsexton)


    I have a plugin that has navigation icons (next/previous) that are SVG icons. When smush! sees them, it creates a 1 pixel transparent gif. Evidently it can’t handle SVGs. This causes the navigations images to not show as expected.

    Could you modify your plugin to either not do anything with SVG images, or handle them correctly? I get an inquiry every month or so from someone who runs into this.

    Thanks.

Viewing 15 replies - 1 through 15 (of 15 total)
  • Hi @gsexton

    I hope you are doing well today.

    Smush does not support compression for SVG, and even with the Pro version (CDN feature), we do not support this format. The only thing that can affect this is the Lazy Load feature. Can you navigate to Smush -> Lazy Load and uncheck SVG from the Media Types section, save, and see if that helps?

    Kind Regards,
    Kris

    Thread Starter George Sexton

    (@gsexton)

    Kris,

    Thanks for responding. Smush is ATTEMPTING to compress SVGs. Perhaps this is just a coding error. Here’s an example output:

    <img decoding=”async” id=”imgNavLeftcdaily_monthview” data-year=”2025
    data-month=”6” data-direction=”-1” class=CDNavIcon
    data-src=”https://www.mycustomer.net/wp-content/plugins/connect-daily-web-calendar/images/left-arrow.svg
    alt=”Previous Month” title=”Previous Month
    src=”data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
    class=”lazyload“>

    Hi @gsexton

    As said in my previous message, Smush does not have the ability to compress SVG images. Based on your code you have shared it seems class lazyload is added to that img, which Smush supports. Can you let us know did you have already tried what was suggested in the previous post?

    Can you navigate to Smush -> Lazy Load and uncheck SVG from the Media Types section, save, and see if that helps?

    Kind Regards,
    Kris

    Thread Starter George Sexton

    (@gsexton)

    Kris,

    Let me start over. I’m a plugin vendor also. When customers use my plugin with your plugin, there’s a problem.

    Your plugin is attempting to in-line an SVG icon, and only generating a single pixel invisible GIF. Here’s an example of your output code:

    <img decoding=”async” id=”imgNavLeftcdaily_monthview” data-year=”2025
    data-month=”6” data-direction=”-1” class=CDNavIcon
    data-src=”https://www.mycustomer.net/wp-content/plugins/connect-daily-web-calendar/images/left-arrow.svg
    alt=”Previous Month” title=”Previous Month
    src=”data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
    class=”lazyload“>

    My customers then call me with complaints that my product isn’t working. This has happened at least 5 times. This isn’t a problem I can fix by changing a setting in your plugin. I need your help.

    You stated in your last post the Smush doesn’t have the ability to compress SVG images. But, as you can see from the included code snippet, it is replacing the SVG content with a GIF. I’m asking you to correct it so that it doesn’t touch them.

    Thanks

    Plugin Support Williams – WPMU DEV Support

    (@wpmudevsupport3)

    Hi @gsexton ,

    I hope you’re doing well and I’m sorry to see that you’re facing this issue.

    I’ve tried to Smush a SVG icon in my test lab, but wasn’t able to do it because, in fact, it doesn’t smush those. Could you please confirm if deactivating Smush makes a difference?

    In case it does, could you please do as mentioned by Kris and try to exclude LazyLoad or completely deactivate it from Smush > LazyLoad

    Please note that Smush doesn’t replace the SRC content, at least for the img src, this is usually handled by the theme or page builder instead, where you can choose the thumbnail. What could change the src from Smush is the CDN, which doesn’t actually support SVG.

    Totally understand the piece of HTML that you’re sharing, but please note that we need you to test what I’ve mentioned with lazyload and confirm if this made a difference.

    In case your plugin is available in the plugins repository, could you please share the URL with us so we can test it?.

    I hope to hear back from you soon.
    Best Regards,
    Williams Valerio

    Thread Starter George Sexton

    (@gsexton)

    @wpmudevsupport3 I’ll install smush tomorrow and test it.

    Plugin Support Saurabh – WPMU DEV Support

    (@wpmudev-support7)

    Hello @gsexton,

    Hope you’re doing well today!

    Sure, please let us know how it goes, also in case if you still notice the issue – please do share your plugin URL in case it is available on the WordPress.org plugin repository so that we can test it.

    Kind Regards,
    Saurabh

    Thread Starter George Sexton

    (@gsexton)

    On my demo site that has my plugin, I installed smush. I went through and did the install. The only option I changed from the default was “Compress My Full Size Images” during the wizard setup.

    After doing that, my icons are now:

    <img decoding="async" id="imgNavLeftcdaily_monthview" data-year="2025" data-month="6" data-direction="-1" class=CDNavIcon data-src="https://wpdemo.mhsoftware.com/wp-content/plugins/connect-daily-web-calendar/images/left-arrow.svg" alt="Previous Month" title="Previous Month" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="lazyload">

    If I turn off lazy loading for .svg then I get:

    <img decoding="async" data-year="2025" data-month="6" data-direction="1" class=CDNavIcon src="https://wpdemo.mhsoftware.com/wp-content/plugins/connect-daily-web-calendar/images/right-arrow.svg" alt="Next Month" title="Next Month">

    This appears to be the relevant code from your plugin:

    // File: core/lazy-load/class-lazy-load-transform.php
    // Lines ~117–123

    private function update_element_attributes_for_lazy_load( Element $element, $replace_attributes ) {
    // Move each real attribute (e.g. 'src', 'srcset', 'sizes') into data-src* versions
    $this->replace_attributes_with_data_attributes( $element, $replace_attributes );

    // Insert a tiny, blank placeholder src (keep markup valid)
    $element->add_attribute(
    new Element_Attribute( 'src', self::TEMP_SRC )
    );

    // Add the CSS class that triggers the JS/CSS lazy-loader
    $this->add_lazy_load_class( $element );
    }

    So the code above sticks in the dummy image, and evidently the code that handles lazy loading replaces the src on-demand. But that’s failing for some reason. I ran the page with the debugger turned on and I’m not seeing anything. By any chance does lazy load try to retrieve images from a compressed image directory?

    Thread Starter George Sexton

    (@gsexton)

    I’m using WordPress 2025 theme, and I’ve also tested with WordPress 2016 theme. I tried adding height/width (see below) and it’s not getting written. I see something is writing a decoding=async (not my code). So it looks like something in WordPress 6.8 is fiddling my output.

    I ran this through ChatGPT, and it pointed out something that appears pretty subtle. I’ve looked through it, and it seems plausible, so I’ll post it. ChatGPT is correct in that there’s no height/width attributes because the height and width are set on the element via CSS.

    Why SVGs fail to load

    When the PHP side transforms your <img src="…"> into a lazy element, it:

    1. Moves srcdata-src
    2. Inserts a 1 × 1 transparent GIF placeholder (src="data:image/gif;base64,…")
    3. Attempts to set explicit width and height in the style so the placeholder still takes up space

    That “set dimensions” step looks like this:

    $width  = (int) $element->get_attribute_value( 'width' );
    $height = (int) $element->get_attribute_value( 'height' );

    // Try to guess from the URL (e.g. filename-200x300.png)
    if ( empty( $width ) || empty( $height ) ) {
    list( $width, $height ) = $this->url_utils->guess_dimensions_from_image_url( $src_image_url );
    }

    // Finally, fall back to PHP’s getimagesize() for local files
    if ( empty( $width ) || empty( $height ) ) {
    $info = $this->server_utils->get_image_info( $src_image_url );
    if ( ! empty( $info['width'] ) && ! empty( $info['height'] ) ) {
    $width = $info['width'];
    $height = $info['height'];
    }
    }

    // Then it injects:
    if ( $width && $height ) {
    $element->add_or_update_attribute(
    new Element_Attribute( 'style', "width:{$width}px;height:{$height}px;{$existing_style}" )
    );
    }

    SVGs typically lack HTML width/height attributes and their URLs usually don’t encode dimensions in the filename, and PHP’s getimagesize() often cannot extract native SVG dimensions unless your environment supports it. As a result:

    • No width/height are set on the placeholder <img>
    • It collapses to 0 × 0 pixels
    • The IntersectionObserver in the JS never “sees” it enter the viewport
    • Therefore the real SVG (data-src) is never swapped in

    Summary

    • JS location: app/assets/js/smush-lazy-load.min.js (enqueued in class-lazy-load-controller.php)
    • Underlying cause for SVG: the placeholder image ends up with no dimensions (0×0), so the lazy-load script never triggers the swap back to the real SVG source. To fix, either give your SVG <img> explicit width/height, or adjust the plugin’s dimension-detection logic (e.g. parse the SVG’s viewBox) so that placeholders retain visible size.
    Thread Starter George Sexton

    (@gsexton)

    I kept investigating, and got this:

    SVGs aren’t officially treated as images
    By default WordPress only considers GIF, JPEG, PNG (and, in recent versions, WebP) as “images.” That check lives in wp_attachment_is_image() — SVGs aren’t on that list.
    When you call wp_get_attachment_image(), under the hood it uses image_downsize() to fetch URL, width and height. If wp_attachment_is_image() is false and there’s no metadata for a “full” size, image_downsize() simply returns false, which then causes the <img> generator to skip outputting any width or height attributes. developer.wordpress.org

    This explains why when I add width and height attributes to my generated output, they’re getting removed. I guess that also means I can’t work around the issue by adding the attributes.

    Plugin Support Nebu John – WPMU DEV Support

    (@wpmudevsupport14)

    Hi @gsexton,

    Can you please share the download URL of the plugin so that we can test this at our end?

    Looking forward to hearing back from you and helping you further.

    Best Regards,
    Nebu John

    Thread Starter George Sexton

    (@gsexton)

    Hi @gsexton

    Just as I thought, this is a conflict between the Smush Lazy Load SVG feature. I have passed your details to our Smush developers to take a look at this. Please keep in mind that our developers deal with more complicated issues, so it may take a little longer for a full review. Thank you for your patience while we look into this further. We will post an update here as soon as more information is available.

    Kind Regards,
    Kris

    Hi again @gsexton

    After a full review by our developers, it seems you don’t use quotation marks in your code, which is responsible for displaying those arrows. I took a quick test, which was mentioned by our developers, and it seems to do the trick.

    In you core file called “display-calendar.php” we suggest to correct in line 192:

    class=CDNavIcon

    to

    class=\"CDNavIcon\"

    and the same correction in line 199.

    With that, if Smush lazyload for SVG is enabled, the arrows display correctly.

    Kind Regards,
    Kris

    Plugin Support Nithin – WPMU DEV Support

    (@wpmudevsupport11)

    Hi @gsexton,

    Since we haven’t heard from you for a while. I’ll mark this thread as resolved for now. Please feel free to re-open this thread if you need any further assistance.

    Kind Regards,

    Nithin

Viewing 15 replies - 1 through 15 (of 15 total)

The topic ‘Incorrect Handling for SVGs’ is closed to new replies.