Article · May 8, 2026
Shipping a Manifest V3 Chrome extension: the gates nobody mentions
Trader verification, publisher identity, the URL slug gotcha, version-bump CI. The async gates that turn a one-day project into a three-week project.
The plan was “let’s ship a Chrome extension.” It took six weeks. Not because the code was hard. Because the code was the easy part, and the async gates around shipping a published extension are not in the developer tutorials.
This post is everything I wish I had read before submitting the first time. Trader verification, publisher identity, the URL slug bug, the version-bump trap, and the post-approval UI swap nobody mentions until you have lived through it.
What “Manifest V3” actually means (and what changed from V2)
Manifest V3 (MV3) is the third generation of the Chrome extension platform. For practical purposes:
- V2 was deprecated in stages between 2022 and 2024.
- New extensions must use V3 since 2024.
- Existing V2 extensions could no longer be updated as of June 2025.
- Chrome stops loading V2 extensions entirely on the schedule posted by Google.
If you are starting fresh in 2026, V3 is the only option. The differences from V2 that matter for new builds:
- No background pages. V2 let you keep a long-running script in the background. V3 replaces that with event-driven service workers that wake up on demand and go idle when not needed. The constraint is real: any state you want to persist across “wake” cycles goes to
chrome.storage, not in-memory variables. - No remote code execution. Loading JavaScript from a URL at runtime is banned. Every line of code in your extension has to be in the bundle Google reviewed. This forces a build-time approach to dependencies.
- Declarative network APIs. Intercepting network requests in V2 was imperative (a function ran on every request). In V3 it is declarative (you publish a list of rules; the browser applies them). This is the change that broke ad blockers, which relied on the imperative API.
- More restrictive content security policy. Inline scripts in your popup HTML are banned by default. Everything is external files.
For most internal-tool extensions (the time-tracker, the dashboard helper, the SSO bridge), none of this is a real constraint. For anything that ad blockers or large extensions do, V3 is a meaningful narrowing.
Choosing the publisher identity
This is the first non-obvious gate. The Chrome Web Store asks: “publish as a Trader or a Non-Trader?”
Trader means “you are a business, your extension is part of your commercial activity.” Non-Trader means “you are a hobbyist developer, no commerce involved.”
The default is Non-Trader. The default is also usually wrong if you are publishing for a client engagement, a consulting product, or anything that touches your day job. The EU’s Digital Services Act requires the Trader declaration; misclassifying yourself is a regulatory risk.
If you declare as Trader, you also have to choose the publisher identity. Three options:
- Sole proprietorship under your personal name. Fast to register (a day in most jurisdictions). Personal liability. The publisher name on the listing is your business name.
- LLC or equivalent. Slower to register (1 to 4 weeks depending on jurisdiction). Limited liability. The publisher name is the LLC.
- An existing client’s entity. Possible if the client wants to own the publisher account. Means the extension belongs to them, not you, which has long-term consequences if the engagement ends.
I default to option 1 for solo-consultant work and option 2 if the client wants ownership. Either way, choose before you start the publisher account; switching after submission is messy and has been known to invalidate the existing listing.
Trader verification
Trader verification is what gates publication for Trader-declared accounts. Google needs to verify your legal name, contact address, and phone number match a real business entity.
What they ask for:
- A legal business name (matches what is on the entity registration).
- A physical business address (a residential address works if your sole proprietorship is registered to your home).
- A contact phone number (real number, they may test it).
- Sometimes a registration document (the certificate of formation, the tax registration, the equivalent in your jurisdiction).
What they do with it:
- Validate the documents (human review at Google).
- Run automated cross-checks against business registries.
- Publish your verified Trader information on the listing once approved.
Timeline:
- For an existing business with tax records: usually 3 to 5 business days.
- For a freshly-registered entity (new sole prop, new LLC): 1 to 2 weeks. The cross-checks against business registries take time because new registrations propagate slowly.
The trap: you cannot pre-submit verification before the entity exists. If you are setting up a new sole prop for this purpose, the order is:
- Register the entity (1 day to 4 weeks depending on jurisdiction).
- Wait for the registration to propagate to business registries (1 to 2 weeks after step 1).
- Submit Trader verification (1 to 2 weeks of Google’s review).
- Now you can submit the extension for review.
That is 3 to 8 weeks before you can submit the first extension. If your goal is “ship the extension next Friday,” plan for it or back up the project to make the math work.

The Chrome Web Store fee
A flat USD 5 one-time fee, payable when you create the developer account. It covers all your extensions, all their versions, forever. Pay it before you start submitting; the account is unusable for publishing until the fee is settled.
For an internal-tool extension on a paid engagement, this is a rounding error. Worth mentioning because the dashboard does not flag it loudly and the rejection message (“your account is not eligible to publish”) is not obvious about the cause.
Submission: the listing fields that matter
Most of the listing fields are obvious (name, description, screenshots, category). The ones that catch people:
- Permissions. Every permission you list (
storage,tabs,identity,<all_urls>) prompts the user at install and is reviewed by Google. The fewer you list, the faster review and the less scary the install screen. Audit your manifest before you submit; remove any permission you do not actively use. I have seen extensions addtabspermission for one debug call they never shipped. - Host permissions. Hosts you have access to via
fetchorchrome.cookies. Each one is a separate user-facing prompt. Use narrow patterns (https://api.yourservice.com/*) over wildcards (<all_urls>); review is faster and users are more comfortable. - Privacy policy URL. Required if you process any user data, including auth tokens. Most extensions need one. The policy can be a single page on your own site; the URL goes in the listing.
- Distribution. Public (anyone can install), Unlisted (anyone with the URL can install, but the listing does not appear in search), or Private (only specific Google Workspace domains can install). For an invite-only internal tool, Unlisted is the right call. The store URL is shareable, but the listing does not show up in search results.
The review queue and what triggers re-review
Google’s stated SLA per the Chrome Web Store review docs: 90% of submissions reviewed within 3 days. In my experience, the typical case is 1 to 3 days for first submissions and same-day-to-1-day for routine updates.
What triggers a slower review:
- New permissions in an update. Adding
tabsorstorageor a new host pattern triggers a deeper review. Plan for a week, not a day. - Permissions that the listed feature set does not obviously require. A reviewer at Google asks “why does this need
clipboardWrite?” and if the answer is not obvious from the screenshots and description, they reject and ask. - Remote code patterns flagged by static analysis. Anything that looks like dynamic
evalor remote script loading triggers a manual review. - Trader status mismatch. If your account is Non-Trader but your listing description mentions a business or pricing, the listing gets flagged for trader verification.
If you are on the slow path, the review portal does not tell you why. You wait. After three weeks with no response you can contact developer support and ask. Usually the issue is small and they tell you in the response.
Post-approval: the URL slug gotcha
Once approved, your extension has a permanent ID (a 32-character lowercase string). The dashboard gives you a listing URL. It looks like this:
https://chromewebstore.google.com/detail/your-extension-name/jmiomhhobiffkdbkogdfnhocdjgfgmab
The slug (your-extension-name) is the human-readable middle part. Google’s documentation suggests both forms are equivalent. They are not.
The slug-bearing form returns rendered HTML the moment the page loads. Browsers, RSS readers, link previewers, anything that fetches the URL can parse the title and metadata.
The slug-less form (chromewebstore.google.com/detail/jmiomhhobiffkdbkogdfnhocdjgfgmab) returns a shell page with no rendered content; the actual content loads via JavaScript after first paint. For most users in mainstream Chrome or Firefox this works. For Safari, Brave with strict shields, certain in-app browsers, and any tool that does not execute JS, the page is blank.
If you are putting the install URL in an email, an in-app CTA, a docs page, or anywhere that might be opened by a non-Chrome client, always use the slug-bearing form. The dashboard’s “copy URL” button does not always give you the slug; check before you paste.
The CTA swap nobody mentions
Before publication, you distributed the extension as a ZIP file via an internal page on your own site. Users downloaded it and side-loaded into Chrome (Developer mode → Load unpacked). The CTA on your install page was “Download ZIP.”
Once the extension is on the Web Store, the CTA changes. “Install from Chrome Web Store →” with a link to the slug-bearing URL is now the primary. The side-load path moves behind a collapsed disclosure (“Manual install for IT-managed environments”). The reasons:
- The Web Store install is one click; the side-load is six manual steps.
- The Web Store install handles updates automatically; side-load does not.
- The Web Store install includes the review badge, which is a trust signal for the end user.
This is a five-minute CTA swap on your install page. Do it the same day the extension goes live; the longer the old CTA is up, the more support requests you get from users who are still side-loading.
Version-drift discipline (pre-commit + CI)
Every update to a published Chrome extension must bump manifest.json’s version field. Forget the bump and the Web Store rejects the upload with “the version of the uploaded package is not later than the published version.” This is annoying but predictable; the trap is when a teammate ships a fix to extension/ and forgets the bump, then the next release attempt fails.
Two-layer guard:
- Pre-commit hook (locally, fast feedback): a script that checks if any file under
extension/changed in the staged diff, and if so, verifiesextension/manifest.jsonwas also changed. - GitHub Actions workflow (in CI, the gate that cannot be
--no-verifyd): the same check, on every PR that touchesextension/.
The full pattern is in the next post in this series on Chrome extension version-bump CI. The short version: both layers matter, because the local hook is for speed but only the CI gate cannot be bypassed.
Real-user dogfood as the final gate
After approval, before declaring “shipped,” install the extension from the Web Store as a non-developer user. Use a Google account that has nothing to do with the developer account. Do the install. Use the extension as if you were a real user. Verify everything works including auth, including updates.
I have seen extensions pass the Web Store review and fail the dogfood install for a stupid reason (a hardcoded localhost URL, a permission requested but not granted, an OAuth redirect URI that did not include the chrome-extension://<id>/... form). The dogfood is the catch.
For the auth setup specifically, the next post in this series covers how to build a Chrome extension popup with Supabase Auth end to end. That is the piece I built around the Web Store submission gate, and it has its own constraints (MV3 has no module system, so the SDK ships as a UMD bundle in the extension folder).
What to plan for if you are shipping in 2026
Roll up:
- Allow 3 to 8 weeks between “let’s build a Chrome extension” and “live on the Web Store” if you are setting up a new business entity for the publisher account.
- Pay the USD 5 fee as the first thing in the developer account setup.
- Submit Trader verification before you submit the extension itself; they are independent gates.
- Minimize permissions in the initial submission; every one is a review surface.
- Use the slug-bearing URL everywhere the extension is linked.
- Set up the version-bump CI gate before the second update; the first time you forget the bump is the time you wished you had it.
- Dogfood the install with a non-developer Google account before declaring “shipped.”
If you are building a Chrome extension for an internal tool and you want a second pair of eyes on the submission plan before the entity registration starts, let’s talk. The planning session is about an hour and produces a written timeline with the dependencies named, which is what you want before you start the entity-registration clock.
Frequently asked questions
What is Manifest V3 and why did Google switch from V2?
Manifest V3 is the third generation of the Chrome extension platform, mandatory for new submissions since 2024 and the only supported version for new uploads since June 2025. The switch from V2 was driven by security and performance concerns: V2 allowed long-running background pages and remote code execution, both of which made review and runtime analysis hard. V3 replaces background pages with event-driven service workers, bans remote code execution, and requires declarative APIs for network interception (which is also what made V3 controversial with ad-blocker developers).
Do I need a registered business to publish a Chrome extension?
Not strictly. You can publish as a non-Trader (a hobbyist developer) if your extension is free, has no monetization, and is not part of a business activity. The moment any of those change (you charge for it, you embed it in a paid service, you offer it through a company), you must declare as a Trader under EU Digital Services Act rules. Trader status requires verifiable legal name, contact address, and phone number. A sole proprietorship is enough; you do not need an LLC.
How long does Trader verification take in 2026?
For an established business with existing tax records, verification typically completes in a few business days once you upload the requested documents. For a new entity (a freshly registered sole proprietorship or LLC), expect 1 to 2 weeks for Google to receive, review, and confirm the identity documents. The clock starts when you submit; you cannot pre-verify before you have the entity registered. Plan the entity registration to complete at least 2 weeks before your target launch date.
Why does my Chrome Web Store URL load blank without the slug?
The Chrome Web Store has two URL forms for any listing: `chromewebstore.google.com/detail/<slug>/<id>` and `chromewebstore.google.com/detail/<id>`. The first (with the slug) loads as a normal HTML page that browsers can render without JS execution. The second (without the slug) returns JS-rendered HTML, which means some browsers (Safari, embedded WebViews, certain proxies) show a blank page. Always link the slug-bearing form. If you copy the URL from the Chrome Web Store dashboard, double-check which form you got.
Can I update the extension after it's published without a re-review?
No. Every update goes through review. Most updates that do not change permissions, host permissions, or sensitive APIs review within 1 to 3 days (Google's stated SLA is "90% of submissions reviewed within 3 days"). Updates that add new permissions or new host patterns trigger a deeper review that can take longer, sometimes 2 weeks. The fix is to minimize permissions on the initial submission and avoid adding more later.