Originally published on ExtensionLaunch.

A Chrome extension landing page has one job: get a visitor to the store listing already convinced. Since Chrome dropped inline installation, nobody installs from your site anyway, so every block on the page should push toward that one click. Here are the six blocks that do it, plus two small scripts that make the button smarter.

The six blocks, top to bottom

  1. Outcome headline. Under ten words, describing the result the user gets, in the words your users actually use. "Save notes for every tab" beats "A tab annotation tool".
  2. One primary button. "Add to Chrome", pointing at your store listing with UTM tags. Give each button a different utm_campaign (hero, footer, pricing) so you can see which one converts.
  3. A demo above the fold. A muted, looping 10–20 second clip or animation of the extension in use, with the toolbar icon visible so people learn where it lives. Use MP4 or WebM with a poster image and compress it hard.
  4. Three benefits, each with a screenshot. Short copy, one picture per benefit. No feature dumps.
  5. Trust. Explain each permission in plain language before Chrome's install dialog does it for you. Say what data leaves the device, link the privacy policy, and show who built it. Only use proof that's real.
  6. FAQ, then the button again. Answer the questions that stall installs: Is it free? Does it work on Edge, Brave or Firefox? Does it work offline? How do I uninstall it?

On the official "Available in the Chrome Web Store" badge: you may resize it but not modify it, it must link to your listing, and it shouldn't be the page's main element. Your own styled button stays the primary CTA. Also keep Google trademarks out of your extension's name and logo.

Show the right store button per browser

Sending a Firefox user to the Chrome Web Store is a lost install. Sniff the user agent, check Firefox first, then Edge, and default to Chrome (Brave, Opera and Vivaldi land there too).

const STORES = { firefox: ['Add to Firefox', 'https://addons.mozilla.org/firefox/addon/your-addon/'], edge: ['Get it for Edge', 'https://microsoftedge.microsoft.com/addons/detail/your-addon/EDGE_ID'], chrome: ['Add to Chrome', 'https://chromewebstore.google.com/detail/your-addon/CHROME_ID'], }; const ua = navigator.userAgent; const key = /Firefox\//.test(ua) ? 'firefox' : /Edg\//.test(ua) ? 'edge' : 'chrome'; const [label, href] = STORES[key]; const link = new URL(href); link.search = new URLSearchParams({ utm_source: 'website', utm_medium: 'landing-page', utm_campaign: 'hero', }); const btn = document.querySelector('.install-button'); btn.href = link.toString(); btn.textContent = label; 

Keep the Chrome URL hard-coded in the HTML as the default href. If the script fails the button still works, and crawlers see a real link.

On phones, skip the install button entirely. Chrome for Android doesn't run Chrome Web Store extensions, so a "send me the link" email field serves those visitors better.

Show "Open" instead of "Install" to existing users

Returning users shouldn't be asked to install again. The externally_connectable manifest key lets pages on your domain message the extension directly.

"externally_connectable": { "matches": ["https://yourdomain.com/*"] } 

In the service worker, answer a ping:

chrome.runtime.onMessageExternal.addListener((msg, _sender, reply) => { if (msg?.type === 'ping') reply({ installed: true }); }); 

On the page, ping it and flag the body:

const ID = 'your-extension-id'; if (window.chrome?.runtime?.sendMessage) { try { chrome.runtime.sendMessage(ID, { type: 'ping' }, (res) => { if (!chrome.runtime.lastError && res?.installed) { document.body.classList.add('has-extension'); } }); } catch { /* not installed or not reachable */ } } 

Then swap the button text with CSS on .has-extension.

Gotcha: once you add externally_connectable without an ids list, other extensions can no longer connect to yours. If you rely on cross-extension messaging, add "ids": ["*"] or specific IDs.

SEO and measurement in five lines

  • Target the problem people search for, not your store category name.
  • Build one page per main use case instead of one page for everything.
  • Keep it fast and add a 1200×630 Open Graph image.
  • Add SoftwareApplication structured data, but don't paste your store ratings into it; Google doesn't allow ratings aggregated from other sites.
  • Opt in to Google Analytics on your store listing, tag every link with UTMs, and mark the install event as a conversion. Expect 24–48 hours before the numbers settle.

While you're at it, open a welcome page on first install and set an uninstall survey URL, so the funnel doesn't end at the store.

Key takeaways

  • Installs happen on the store, so the page's job is to send convinced visitors there, with UTM-tagged buttons.
  • Demo above the fold, three benefits, a plain-language permissions section, then FAQ.
  • Detect the browser to show the matching store, and give mobile visitors an email field instead.
  • Use externally_connectable to turn "Install" into "Open" for existing users, and mind the ids gotcha.
  • Never copy store ratings into structured data.

The original post has the full walkthrough, including the badge rules and FAQ answers: how to build a Chrome extension landing page that converts. If you want more eyes on the extension once the page is live, you can list and launch your browser extension on ExtensionLaunch.

What's the one section on your extension's landing page that moved installs the most for you?