M2 Google Preferred Source
Floating button to let visitors add the site to Google News Preferred Sources.
by Matteo Morreale · github.com/matteomorreale/m2-google-preferred-source
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/matteomorreale/m2-google-preferred-source/archive/refs/heads/main.zipReadme
M2 Google Preferred Source
A lightweight WordPress plugin that adds a floating button letting visitors add your site to their Google News Preferred Sources.
Features
- Floating pill button — collapsed as a small circular icon, expands to show a label on click/tap.
- 6 selectable positions — top/middle/bottom, left/right, chosen from a visual position picker in the admin area.
- Light/dark appearance for the button.
- Automatic or custom icon — use the official Google icon or pick your own from the Media Library.
- Custom button text — override the default label shown to visitors, or leave it blank to use the translated default.
- Multi-language interface — the admin screen and the front-end button automatically follow the WordPress installation's language. 8 languages are bundled; any other language falls back to English.
- Official Google flow under the hood — the actual "add preferred source" action is performed by Google's own
publisher.js(loaded in manual mode and triggered through its publicPREFERRED_SOURCEAPI), not a reverse-engineered call, so the flow stays correct even if Google changes its internal implementation.
Supported languages
English (default/fallback), Italian, Spanish, French, German, Portuguese, Dutch, Polish.
The active language is detected from the WordPress installation locale (get_locale()). If the site's language is not one of the 8 bundled languages, all text falls back to English.
Installation
- Copy the
m2-google-preferred-sourcefolder intowp-content/plugins/. - Activate M2 Google Preferred Source from the WordPress admin Plugins screen.
- Go to Settings → M2 Preferred Source to configure the button.
Configuration
From Settings → M2 Preferred Source you can:
- Enable or disable the button.
- Enable dark mode.
- Pick the on-screen position using the visual skeleton picker (6 zones: top/middle/bottom × left/right).
- Choose between the automatic Google icon or a custom image from the Media Library.
- Set a custom button text, or leave it empty to use the translated default for the visitor's site language.
How it works
Google's publisher.js is loaded in manual mode (preferred-sources-control="manual"): it renders no button of its own and only exposes the PREFERRED_SOURCE JavaScript API. Our compact pill button appears once that API is ready, so visitors never see a control that isn't able to act. On click, the pill expands to show its label and immediately calls preferredSource.addPreferredSource(), which opens Google's own official confirmation popup.
Because the actual action is still performed by Google's own code (just triggered through its public API instead of its embedded button), the flow keeps working even if Google changes its internal endpoints — and the visitor only ever sees our styled pill, never Google's separately-styled iframe button.
Once a visitor has added the site as a preferred source (or had already added it), the pill disappears and stays hidden on that browser — it has nothing left to do. This is detected from Google's own flow result (its web-activities result message, the return-URL fragment on mobile, or the confirmation toast it shows) and remembered in localStorage.
Changelog
1.4.0
- Reworked how Google's widget is used. Google renders its button inside a cross-origin iframe with its own styling that a plugin cannot touch, so it always looked detached from our floating pill (fully rounded, offset from the screen edge, "floating").
publisher.jsis now loaded in manual mode: Google renders no button, and our pill drives Google's official flow directly viapreferredSource.addPreferredSource(). The visitor only ever sees our own pill. - The pill now disappears for good (per browser, via
localStorage) once the visitor has added the site — or if they'd already added it. Detected from Google's flow result message, the mobile return-URL fragment, and its confirmation toast. - Removed the expand-then-swap step, the skeleton/shimmer loading state and the iframe "holder" — no longer needed.
- The wrapper no longer intercepts clicks outside the pill itself.
1.3.x (superseded by 1.4.0)
- 1.3.1–1.3.3 progressively tried to contain, clip and dock Google's embedded iframe button so it wouldn't escape or float. Manual mode in 1.4.0 removes the embedded button entirely, making all of that unnecessary.
1.3.2
- Strengthened the holder containment with
!importantand CSScontain: strict(paint/layout/size containment), since a plainoverflow: hiddenbox does not clip aposition: fixedelement painted by Google's script —containexplicitly forces such descendants to be boxed inside our holder instead of escaping to the viewport.
1.3.1
- Fixed the real Google button appearing unprompted at page load, disconnected from the floating pill. Google's own script can clear the
hiddenattribute on its button element once initialized, bypassing our controlled reveal; the button now sits inside a zero-size, clipped holder that only we expand, right after the pill's expand animation.
1.3.0
- Replaced the reverse-engineered popup flow with Google's own official
publisher.jswidget, fixing the "add preferred source" action failing/erroring for visitors. - The floating button now only appears once Google's script has loaded, and swaps to the real Google button (with a skeleton fallback) right after the local expand animation.
- Removed the now-unused "Source URL" setting, since Google's widget determines origin/source from the current page itself.
1.2.0
- Added a visual position picker (6 zones) for the floating button.
- Added a custom button text field.
- Added built-in multi-language support (8 languages + English fallback) for both the admin screen and the front-end button.
1.1.0
- Initial floating button with automatic/custom icon, dark mode and configurable source URL.
License
GPLv2 or later.
Author
Matteo Morreale