[wp-trac] [WordPress Trac] #65098: get_site_icon_url() returns empty string even when fallback is defined, breaking wp-embed-site-icon in the_embed_site_title()

WordPress Trac noreply at wordpress.org
Sat Apr 18 19:59:48 UTC 2026


#65098: get_site_icon_url() returns empty string even when fallback is defined,
breaking wp-embed-site-icon in the_embed_site_title()
--------------------------+---------------------
 Reporter:  pontocinza    |       Owner:  (none)
     Type:  defect (bug)  |      Status:  new
 Priority:  normal        |   Milestone:  7.1
Component:  Embeds        |     Version:
 Severity:  normal        |  Resolution:
 Keywords:  needs-patch   |     Focuses:
--------------------------+---------------------
Changes (by sabernhardt):

 * keywords:   => needs-patch
 * version:  6.9.4 =>
 * milestone:  Awaiting Review => 7.1


Old description:

> In `wp-includes/embed.php`, the function `the_embed_site_title()` calls
> `get_site_icon_url()` twice, passing a fallback URL as the second
> argument:
>
>     esc_url( get_site_icon_url( 32, includes_url( 'images/w-logo-
> blue.png' ) ) ),
>     esc_url( get_site_icon_url( 64, includes_url( 'images/w-logo-
> blue.png' ) ) ),
>
> Despite a Site Icon being properly defined in Appearance → Customize →
> Site
> Identity (a 512×512px image), `get_site_icon_url()` returns an empty
> string,
> ignoring the fallback entirely. This results in a broken icon in all
> oEmbed
> cards rendered via `the_embed_site_title()`.
>
> The generated HTML is:
>
>     <img src="" srcset=" 2x" width="32" height="32" alt="" class="wp-
> embed-site-icon">
>
> Note that `src` is empty and `srcset` contains only ` 2x`, which causes
> browsers to interpret it as a relative URL request to `/embed/2x`,
> returning
> a 403 error.
>
> The WordPress logo fallback (`w-logo-blue.png`) is also never used,
> contrary
> to the documented behavior of `get_site_icon_url()`.
>
> == Steps to reproduce ==
>
> 1. Set a Site Icon in Appearance → Customize → Site Identity (512×512px
> image)
> 2. Create a post
> 3. On another page, add a Media & Text block or an Embed block pointing
> to
>    that post's URL
> 4. Visit the page — the site icon in the oEmbed card footer will be
> broken
> 5. Inspect the element: `src=""` and `srcset=" 2x"`
>
> == Expected behavior ==
>
> The site icon should display correctly, or — if unavailable — the
> WordPress
> logo fallback (`w-logo-blue.png`) should be used instead.
>
> == Actual behavior ==
>
> `get_site_icon_url()` returns an empty string regardless of the defined
> icon
> or fallback, producing a malformed `<img>` tag with empty `src` and
> `srcset`.
>
> == Workaround ==
>
> The following filter removes the broken icon from the embed footer:
>
>     add_filter('embed_site_title_html', function($site_title) {
>         return preg_replace('/<img[^>]+class="wp-embed-site-
> icon"[^>]*>/i', '', $site_title);
>     });
>
> == Environment ==
>
> - WordPress 6.9.4
> - PHP (production server)
> - Site Icon defined, 512×512px, uploaded via Customizer
> - APCu object cache active
> - Cloudflare in front of the site

New description:

 In `wp-includes/embed.php`, the function `the_embed_site_title()` calls
 `get_site_icon_url()` twice, passing a fallback URL as the second
 argument:

 {{{
     esc_url( get_site_icon_url( 32, includes_url( 'images/w-logo-blue.png'
 ) ) ),
     esc_url( get_site_icon_url( 64, includes_url( 'images/w-logo-blue.png'
 ) ) ),
 }}}

 Despite a Site Icon being properly defined in Appearance → Customize →
 Site
 Identity (a 512×512px image), `get_site_icon_url()` returns an empty
 string,
 ignoring the fallback entirely. This results in a broken icon in all
 oEmbed
 cards rendered via `the_embed_site_title()`.

 The generated HTML is:
 {{{
     <img src="" srcset=" 2x" width="32" height="32" alt="" class="wp-
 embed-site-icon">
 }}}

 Note that `src` is empty and `srcset` contains only ` 2x`, which causes
 browsers to interpret it as a relative URL request to `/embed/2x`,
 returning
 a 403 error.

 The WordPress logo fallback (`w-logo-blue.png`) is also never used,
 contrary
 to the documented behavior of `get_site_icon_url()`.

 == Steps to reproduce ==

 1. Set a Site Icon in Appearance → Customize → Site Identity (512×512px
 image)
 2. Create a post
 3. On another page, add a Media & Text block or an Embed block pointing to
    that post's URL
 4. Visit the page — the site icon in the oEmbed card footer will be broken
 5. Inspect the element: `src=""` and `srcset=" 2x"`

 == Expected behavior ==

 The site icon should display correctly, or — if unavailable — the
 WordPress
 logo fallback (`w-logo-blue.png`) should be used instead.

 == Actual behavior ==

 `get_site_icon_url()` returns an empty string regardless of the defined
 icon
 or fallback, producing a malformed `<img>` tag with empty `src` and
 `srcset`.

 == Workaround ==

 The following filter removes the broken icon from the embed footer:
 {{{
     add_filter('embed_site_title_html', function($site_title) {
         return preg_replace('/<img[^>]+class="wp-embed-site-
 icon"[^>]*>/i', '', $site_title);
     });
 }}}

 == Environment ==

 - WordPress 6.9.4
 - PHP (production server)
 - Site Icon defined, 512×512px, uploaded via Customizer
 - APCu object cache active
 - Cloudflare in front of the site

--

Comment:

 Hi and welcome to WordPress Core Trac!

 I think you might have a plugin or theme that uses the `get_site_icon_url`
 filter. I can break the site icon image in embeds by adding this to a
 custom plugin:
 {{{
 add_filter( 'get_site_icon_url', '__return_empty_string' );
 }}}

 The filter runs at the end of the `get_site_icon_url()` function, so the
 fallback WordPress logo would not override that.

 The `atom_site_icon()` and `wp_site_icon()` functions check the value
 before trying to print it, and a similar condition probably could fit
 `the_embed_site_title()`.
 {{{
 function atom_site_icon() {
         $url = get_site_icon_url( 32 );
         if ( $url ) {
                 echo '<icon>' . convert_chars( $url ) . "</icon>\n";
         }
 }
 }}}

 {{{
 function wp_site_icon() {
         if ( ! has_site_icon() && ! is_customize_preview() ) {
                 return;
         }

         $meta_tags = array();
         $icon_32   = get_site_icon_url( 32 );
         if ( empty( $icon_32 ) && is_customize_preview() ) {
                 $icon_32 = '/favicon.ico'; // Serve default favicon URL in
 customizer so element can be updated for preview.
         }
         if ( $icon_32 ) {
                 $meta_tags[] = sprintf( '<link rel="icon" href="%s"
 sizes="32x32" />', esc_url( $icon_32 ) );
         }
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/65098#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list