Browser Extension
The zero-integration shell — no code added to the target project.
The extension delivers the same capture flow as the widget without touching the target project — for trying Paintless before adopting it, and for stakeholders filing requests on deployed sites.
Install (from source)
pnpm --filter @paintless/extension buildThen load packages/extension/dist via chrome://extensions →
"Load unpacked" (enable Developer mode).
Use
Click the toolbar action on any page:
- The element picker starts — same overlay, source labels, Escape to cancel.
- The picked element is highlighted and screenshotted via
captureVisibleTab(activeTabpermission, granted by your click), so the request carries visual context. - Where the request goes depends on the site:
| Site | Behavior |
|---|---|
| Domain mapped in options | Prod mode — submit to that Paintless server with the project key |
| Anything else | Dev mode — connect to the local paintless dev host |
Project mapping (options)
Open the extension options page and map deployed domains to servers:
| Domain | Server URL | Project key |
|---|---|---|
shop.example.com | https://paintless.internal.example.com | pk_... |
Subdomains match automatically (shop.example.com matches
admin.shop.example.com). Mappings sync via chrome.storage.sync.
Widget or extension?
Both run the same core. Choose by deployment story:
- Widget — the team adopts Paintless: ships to every stakeholder, can use the host app's session, works in webviews.
- Extension — zero integration: individuals use it on any site, including ones they don't own the code for.
Permissions and privacy
The manifest asks for three permissions and no host permissions:
| Permission | Use |
|---|---|
activeTab | Run the picker and take the element screenshot on the tab whose icon you clicked, and only then |
scripting | Inject the picker on that click — nothing runs automatically |
storage | Keep your domain → server mappings |
Requests go only to the host you configured, and only when you press Send. The full statement is the Privacy Policy.
Publishing to the Chrome Web Store
Listing copy, the single-purpose statement, permission justifications and the
data disclosures live in packages/extension/store/listing.md — edit that file
rather than the dashboard, so the next submission starts from what was actually
submitted. Screenshots and the promo tile are generated:
pnpm --filter @paintless/extension store:assetsThat drives the built extension in a real Chromium profile against the playground (Playwright cannot click a toolbar action, so the screenshot build adds a localhost host permission and injects the same content script from the service worker) and renders the 440×280 tile from the project mark.
