Secure, test, and publish

Package and publish

Prepare icons, store copy, screenshots, privacy disclosures, version updates, and a clean ZIP without development files or secrets.

Publishing to the Chrome Web Store is a ZIP upload plus a review. The review is the part that takes work. Reviewers check that the package does what the listing says, asks for no more than it needs, and discloses what it does with data.

Build the ZIP from an allowlist

The ZIP root must contain manifest.json directly. Not a page-notes/ folder with the manifest inside it. That’s the most common first rejection.

Don’t zip the repository and try to exclude things. List the files that belong in the release and copy only those:

mkdir -p dist
cp manifest.json popup.html popup.js content.js service-worker.js dist/
cp -r icons dist/
cd dist && zip -r ../page-notes-1.0.0.zip .

Then open the ZIP and read the file list. No .env, no tests, no source maps, no .git, no private key, no node_modules. Anything not on the allowlist is a mistake by definition.

Bump the version in the manifest before every upload. The store rejects a version equal to or lower than the published one.

The listing is part of the release

You need icons at 16, 48 and 128 pixels, screenshots of the real extension, a short description, and a single-purpose statement. Write what Page Notes does in one sentence. Screenshots must show features the package has, not features you plan.

The privacy section asks what data you collect and why each permission exists. For Page Notes: notes and page URLs, stored locally, never transmitted. Explain storage, activeTab, and scripting in one line each. Reviewers read these against your code.

When code, manifest, assets, or data practices change, the listing changes with them. A screenshot of an old popup is a small lie that costs you a review cycle.

After approval

An approved update doesn’t reach users instantly. Existing installs pick it up on Chrome’s update schedule. If you added permissions, Chrome disables the extension until the user accepts them. Avoid adding permissions in an update if you can.

Install the store version in a clean Chrome profile and use it. Not your dev folder, the actual artifact users get. Then upgrade a profile that has version 1.0.0 with saved notes to the new version, and check the notes are still there.

Keep the last known-good ZIP and its release notes. If the new version breaks, you re-upload the old package with a bumped version number. That’s your rollback. Large publishers can use staged rollout to a percentage of users, but it doesn’t replace testing before submission.

Now write your release checklist. Build the ZIP from the allowlist, list its contents, install it in a clean profile, upgrade from the previous version, and check permissions, saved notes, store copy, and privacy declarations one by one. Do the same list every release. It’s boring, and that’s the point.

Lesson completed