My Sites: Fall back to plain favicon when no Site Icon is present - #116
My Sites: Fall back to plain favicon when no Site Icon is present#116wprashed wants to merge 1 commit into
Conversation
When a site record has no stored Site Icon URL, attempt to load the site's default /favicon.ico before falling back to the globe icon. Fixes WordPress#114.
i-am-chitti
left a comment
There was a problem hiding this comment.
Thanks for picking it up. I gone through the changes and here are two notes. Not a maintainer here, so please read these as suggestions rather than blockers.
- 10up.com, the example in #114, is not be covered completely: its
/favicon.icoreturns an nginx 404 currently, and the real icon sits at a theme path in<link rel="shortcut icon">. It does emit anapple-touch-icon, which detect.js already accepts (L123-L125), so that row may fill in on its own after one logged-in front-end visit.
| const { origin, key } = site; | ||
| const baseUrl = site.baseUrl || origin; | ||
| const iconUrl = site.iconUrl || null; | ||
| const defaultFavicon = origin ? `${origin}/favicon.ico` : null; |
There was a problem hiding this comment.
Since origin drops the install path, two installs on one host - example.com/client1 and example.com/client2 - would both request https://example.com/favicon.ico, and a subdirectory multisite child would pick up the main site's icon. Records are keyed at the install base for that reason (#94), so would baseUrl from 73 fit better here? It's always set (site.baseUrl || origin), so the guard could go with it:
| const defaultFavicon = origin ? `${origin}/favicon.ico` : null; | |
| const defaultFavicon = `${baseUrl}/favicon.ico`; |
For subdirectory installs that mostly falls through to the globe rather than finding an icon - core registers the favicon.ico rewrite only when the install is at the domain root - though that seems kinder than showing a different site's icon.
| const baseUrl = site.baseUrl || origin; | ||
| const iconUrl = site.iconUrl || null; | ||
| const defaultFavicon = origin ? `${origin}/favicon.ico` : null; | ||
| const [activeIcon, setActiveIcon] = useState(iconUrl || defaultFavicon); |
There was a problem hiding this comment.
this copies a prop into state, and the initializer only runs once. Rows keep their instance across store updates (keyed by site.key, L44), so if a later login captures the Site Icon through upsertOnLogin, the row re-renders while activeIcon still holds the old URL. The new icon would then appear only after the popup is reopened. iconFailed behaves the same way.
A reset covers both:
useEffect(() => { setActiveIcon(iconUrl || defaultFavicon); setIconFailed(false); }, [iconUrl, defaultFavicon]);|
Thanks for the review and note, @i-am-chitti! Exactly as you pointed out, for sites with |
|
@wprashed you can also try to get the favicon directly from the browser: https://developer.chrome.com/docs/extensions/how-to/ui/favicons |
Summary
Fixes #114.
Sites recorded through
wp-adminalone, or themes that hardcode a plain favicon instead of utilizing WordPress Site Icon markup, do not have a storediconUrlin their My Sites record and previously displayed the fallback globe icon permanently.Changes
MySiteRow(src/popup/components/MySites.js), ifsite.iconUrlis not present, attempt to render the site's standard${origin}/favicon.ico.onErrorevent fires for the active icon, fallback to${origin}/favicon.ico(if attempting a custom icon) or the globe icon when no favicon can be loaded.Testing Instructions
npm testornode test/smoke.js.${origin}/favicon.icobefore falling back to the globe icon.