Open sourceMIT6 packages | 7 recipes | 2 SDK methods

Add as Preferred Source Button & Popup for Google (SEO & AI Overviews) — live package demo

Google's official Preferred Sources button SDK for every major framework: live demos of the @opacedev/preferred-source-* packages, with a deeplink fallback and click instrumentation.

Rendered Preferred Sources component demo showing the Google-colours trigger, fallback explanation and package status
Genuine component-demo capture: the rendered trigger uses a deeplink fallback when Google’s external SDK cannot display a popup.

View the repo → Button generator ↗ Eligibility checker ↗

01 Variant gallery

Three variants, each in light and dark. Every card shows its copyable snippet.

google-default · light
<preferred-source-button></preferred-source-button>
google-default · dark
<preferred-source-button theme="dark"></preferred-source-button>
google-colours · light
<preferred-source-button variant="google-colours"></preferred-source-button>
google-colours · dark
<preferred-source-button variant="google-colours" theme="dark"></preferred-source-button>
neutral · light
<preferred-source-button variant="neutral"></preferred-source-button>
neutral · dark (custom properties)
<preferred-source-button variant="neutral"
  style="--ps-bg:#111; --ps-colour:#fff;"></preferred-source-button>

02 Auto mode

With mode="auto" the component places an attributed element in the light DOM and Google's SDK renders its own button into it. Google's script loads happily on unrecognised origins (localhost, GitHub Pages) yet silently paints nothing, so the component gives it render-timeout milliseconds (default 4000) after the script loads. If nothing appears it swaps to the deeplink fallback and emits ps-fallback with reason: 'no-render' — watch the event console below. That is the honest behaviour, not a fault: the box never stays empty.

<preferred-source-button mode="auto" render-timeout="4000"></preferred-source-button>

03 Deeplink fallback

When the SDK is blocked (ad blocker, consent tool, offline), every package falls back to Google's documented deeplink. If you run a content blocker, the buttons above are already showing you this state. This one is forced to the fallback URL for a specific domain:

<preferred-source-button
  href-fallback="https://www.google.com/preferences/source?q=opace.agency"></preferred-source-button>

04 Event console

Every ps-click, ps-ready and ps-fallback on this page is appended below as JSON. This is the instrumentation surface: clicks on triggers. Google's SDK has no completion callback, so no event on any page can report a finished add.

05 Source workspace and package names

npm i @opacedev/preferred-source-element

import '@opacedev/preferred-source-element/register';

06 Eligibility and limits

Eligibility. Preferred Sources works for domains and subdomains only — www.example.com and news.example.com qualify; example.com/blog does not. The site must already resolve in Google's source preferences tool.

What click instrumentation means here. Google's SDK exposes exactly two methods (init, addPreferredSource) and no completion callback or event. Nothing on the page can know whether the reader finished adding your site inside Google's popup. Every event this library emits (ps-click) measures clicks on the trigger, not confirmed additions. Treat the numbers accordingly.