Setup
Chrome blocks every extension on Chrome Web Store pages, the developer dashboard included. It decides which site is “the store” from a startup setting, so a Chrome window started with that setting pointed elsewhere lets this extension work on the dashboard. Keep it to a separate profile used only for publishing:
- Unzip the download. Start the publishing profile with the command below, open
chrome://extensions, turn on Developer mode and choose Load unpacked → the unzipped folder. - Sign in to your developer account in that window.
- Always start that window with the same command.
macOS
open -na "Google Chrome" --args --user-data-dir="$HOME/Chrome Publishing" --apps-gallery-url=https://webstore.invalid/ https://chrome.google.com/webstore/devconsoleWindows
"%ProgramFiles%\Google\Chrome\Application\chrome.exe" --user-data-dir="%USERPROFILE%\Chrome Publishing" --apps-gallery-url=https://webstore.invalid/ https://chrome.google.com/webstore/devconsoleLinux
google-chrome --user-data-dir="$HOME/.chrome-publishing" --apps-gallery-url=https://webstore.invalid/ https://chrome.google.com/webstore/devconsoleIn that window, “Add to Chrome” on the store doesn't work; install extensions from your everyday Chrome, which stays unchanged. A Chrome profile that is already running ignores startup settings, which is why the publishing one has its own folder.
Use
- Click the toolbar icon to open the side panel and choose your listing ZIP.
- Open your item's Store listing page and click Fill this page. For each other language, switch the dashboard's language and fill again.
- Open Privacy and click Fill this page.
- Anything not found gets a Copy button. Check the dashboard, then save and submit it yourself.
Screenshots are added to the ones already there; delete old ones first if you are replacing them. The data-use certifications are never ticked for you.
The listing ZIP
listing.json what goes where
descriptions/<locale>.txt one per language, plain text, ≤ 16,000 chars
images/icon-128.png 128×128 PNG
images/promo-small.png 440×280
images/promo-marquee.png optional, 1400×560
images/screenshots/1.png … 5.png 1280×800 or 640×400
images/screenshots/<locale>/… optional, per language
package/_locales/<locale>/messages.json name and short description (not typed in){
"format": "cws-listing",
"version": 1,
"itemId": "your 32-letter item ID, or null",
"storeListing": {
"defaultLocale": "en",
"category": "Developer Tools",
"descriptions": { "en": "descriptions/en.txt", "de": "descriptions/de.txt" },
"icon": "images/icon-128.png",
"screenshots": ["images/screenshots/1.png"],
"localizedScreenshots": { "de": ["images/screenshots/de/1.png"] },
"promoSmall": "images/promo-small.png",
"promoMarquee": null,
"promoVideo": null,
"homepageUrl": "https://example.com",
"supportUrl": null,
"matureContent": false
},
"privacy": {
"singlePurpose": "The extension's one job, in a sentence or two.",
"permissions": [{ "permission": "storage", "justification": "Why it's needed." }],
"remoteCode": { "uses": false, "justification": null },
"dataCollected": [],
"privacyPolicyUrl": "https://example.com/privacy"
},
"package": { "name": { "en": "Name" }, "summary": { "en": "Short description" } }
}categoryis spelled as the dashboard shows it: Communication, Developer Tools, Education, Tools, Workflow & Planning, Art & Design, Entertainment, Games, Household, Just for Fun, News & Weather, Shopping, Social Networking, Travel, Well-being, Accessibility, Functionality & UI, Privacy & Security.- Locale codes are Chrome's:
pt_BR,es_419,zh_CN. dataCollectedlists the types the extension collects from: personally identifiable information, health information, financial and payment information, authentication information, personal communications, location, web history, user activity, website content. Empty means none.nullleaves that dashboard field as it is. The name and short description come from your package's_locales, not the dashboard, so the filler doesn't type them.- Wrong image sizes are reported when the ZIP is opened, before anything is filled.
Uploading the package itself
That part Google's API does. See how to automate publishing a Chrome extension.