Ship to the Chrome Web Store
Copy the tool to Live, build the store copy of your extension, and publish it.
Shipping moves a tool from Test to Live and puts the Live build of your extension on the Chrome Web Store. Buyers then pay with real cards, on your own Stripe account.
This guide covers the first release and every update after it. It starts where the Quickstart ends: a tool on Test, an extension wired to it, a test purchase made.
On Live, the tool's Overview shows these steps until its first customer, each ticked as it happens: Stripe, the prices, a copy with the Live key, the store listing. Its header says Not selling yet while something stops a sale.
Before you begin
- The tool works on Test: its Free plan, plans and features are set under Pricing, and a test purchase unlocked the extension.
- Your code gates what you sell with
gate(), and answers a refusal withshowPaywall(). See Gate your extension. - A Chrome Web Store developer account. Registering costs a one-time fee, paid to Google.
- Your business's details for Stripe's onboarding: on Live, Toolaby makes a Stripe account for your workspace (step 1).
- The command line signed in on Live:
npx -y toolaby@latest login --live.
1. Connect Stripe on Live
Open the dashboard at toolaby.app/dev. Your first visit to Live asks for a workspace name: give the same name as on Test. Copy to Live copies into the Live workspace of that name.
Under Configure → Payments, select Connect. Toolaby makes a Stripe account for the workspace, with its own Stripe Dashboard, and opens Stripe's onboarding. The account's country starts as the United States; set yours in the onboarding. Connect does not attach a Stripe account you already have.
When it worked, Configure → Payments shows Connected. Until then, Copy to Live creates the tool but not its plans.
2. Copy the tool to Live
On Test, open the tool's Set up page and select Copy to Live, at its foot.
Toolaby creates the tool on Live with the same tool id, its name, line, description and icon, its Free plan, its features, its plans (each a Price on your live Stripe account), its Versions settings, the extension's identity and its store listing address. Buyers, customers, members, API keys and webhook endpoints are per side, and are not copied.
Live copies for the account you signed in to Test with, and only into a workspace where you are an owner or an admin. More than an hour after that sign-in, it asks you to confirm: select Confirm with Live, then Copy to Live again.
When it worked, the page says On Live, shows your live key, and links to the tool on Live with Open it on Live.
Copy again whenever Test has something new. Live is never copied back to Test.
3. Wire the store build
In your extension's folder:
npx -y toolaby@latest wire <tool-id> --live --forceThe command writes the Live tool key (tk_live_…) into toolaby.config.js and replaces the Test address in the manifest with your workspace's Live address, under externally_connectable. Your own code is not touched.
A WXT or CRXJS project takes the address from the key at build time; there is nothing to change in its config. A Plasmo project's package.json names the address itself: replace its manifest with the lines the command prints. See Frameworks.
4. Build and pack
Build as you always do: npm run build, or nothing for an extension without a build step. Then:
npx -y toolaby@latest packpack finds the built extension — this folder, .output/chrome-mv3, dist, build/chrome-mv3-prod or build — and writes <name>-<version>.zip. It leaves the manifest's key out of the zip, and it stops with the reason when the build:
| Stops on | Why |
|---|---|
a tk_test_ or tk_dev_ key inside | The extension would sell on Test, with test cards. Run step 3, build again. |
localhost in the manifest | A store build must not reach a server on the buyer's machine. |
Toolaby's address missing from externally_connectable | Sign-in and the purchase could not reach the extension. Run step 3. |
a host under toolaby.app that no key in the build names | The build would carry an address it never talks to, such as your Test address. Under host_permissions, Chrome would also ask buyers for it at install. Take it out of host_permissions and externally_connectable; step 3 takes out your Test address. |
a manifest version Chrome would not take | Chrome takes one to four numbers separated by dots, like 1.2.0. |
| a file the manifest names that would be left out as private | Chrome would not load the zip. Take the private part out of that file, or pack with --allow-private if it is meant to ship. |
a public folder that is a link into .git, or a build whose top is a git repository | The zip would carry the repository's history, index and logs. Point the build at its output folder. |
A host permission for Toolaby's own address does not stop it, and pack says it is there: Toolaby needs none. Where the version in the store lacks it, Chrome would switch this update off until each user approves it, so take it out with npx -y toolaby@latest upgrade <tool-id> --live.
See pack for the options.
5. Upload
In the Chrome Web Store Developer Dashboard:
- A new item: select New item and upload the zip. Fill in the store listing. On the Privacy tab, declare what your extension collects; for Toolaby's part, a signed-in buyer's email address (Personally identifiable information) and the sign-in credential kept on the device (Authentication information). Card details never reach the extension: payment happens on Stripe's page.
- An update: open the item, then Package → Upload new package.
Submit for review. Review takes from a few hours to several days. While an item is in review, it takes no other package.
The store refuses a manifest key in a new item's first package, and in an update any key but the item's own. pack leaves it out for that reason. The store keeps the id it gave the item.
6. Tell Toolaby where the store copy is
After the first upload the item has an id, and its listing has an address even before it is public. On Live, open the tool's Settings and paste the listing's address under Store → Chrome Web Store listing.
Toolaby now accepts your tool key from the store copy. Your unpacked copy, loaded from your folder, keeps the key the wiring gave it and its own id; Toolaby accepts that one too. From then on it refuses any other extension. See Test and Live.
To give every copy the store's id instead, copy the item's public key (Package → View public key, the text between the BEGIN and END lines, on one line) into your manifest's key, then run npx -y toolaby@latest wire <tool-id> --force --adopt-key on Test and npx -y toolaby@latest wire <tool-id> --live --force --adopt-key on Live. Toolaby adopts it as the extension's identity. Copies with the old key are then no longer the tool's.
7. Check the store copy
When the item is published, install it from its listing.
- Open the extension. Its tool's Set up page on Live says Checked in.
- Make a purchase with a real card. The extension unlocks, and the buyer appears on the tool's Customers page.
- Refund it in your Stripe Dashboard. The licence is revoked, and the extension locks at its next check.
8. Ship an update
- Raise
versionin the manifest. The store refuses a package whose version is not higher than the published one. - Build, and run
npx -y toolaby@latest pack. - Upload it as a new package (step 5).
Your Test tool key stays in your working copy only while you develop: before you pack, the key must be Live (step 3). To go back to Test afterwards, run npx -y toolaby@latest wire <tool-id> --force.
To stop copies older than a version from running, set a minimum under the tool's Versions. See Versions.
Also on Microsoft Edge
Edge runs Chrome extensions, and its store, Microsoft Edge Add-ons, has a search of its own and no limit on how many extensions you publish.
- Register for the Microsoft Edge program in Partner Center. It is free.
- Upload the zip
packmade, as a new extension. Edge's review asks that its name and description not say Chrome. - Edge gives the extension an id of its own, which Partner Center shows once the package is uploaded. Before you submit it for review, paste its listing address, or the id, under Store → Microsoft Edge Add-ons listing on Live, or run
npx -y toolaby@latest tool update <tool-id> --live --edge-url <listing address>.
Toolaby then accepts your tool key from the Edge copy as from the Chrome one, a purchase made in Edge reaches the Edge copy, and a buyer in Edge is sent to the Edge listing. Edge installs from the Chrome Web Store too, so a tool on Chrome's store alone still sends Edge users there.