Hoe bouw je een Chrome-extensie die de backend van je SaaS deelt?
Door geen tweede backend te bouwen. Een MV3-extensie kan niet op HttpOnly-cookies leunen, dus authenticeer je met workspace-API-keys: de extensie roept de versieerde REST-API van de app (/api/v1) aan met een gescopete key gebonden aan precies één workspace, en hergebruikt zo hetzelfde auth-model, dezelfde tenant-scoping en dezelfde Postgres-database als de web-app. supastacks MV3-scaffold — popup, optiepagina, backgroundworker, least-privilege-manifest — is precies zo bedraad.
De val: ongemerkt een tweede backend bouwen
Het gebruikelijke verhaal: je SaaS heeft een companion-extensie nodig om pagina's vast te leggen, content te clippen of het web te annoteren. Zes maanden later onderhoud je twee authsystemen (cookies voor het web, iets handgemaakts voor de extensie), een parallelle API die de extensie echt kan aanroepen, en een synchronisatielaag die twee datastores bijhoudt die eigenlijk één zouden moeten zijn.
Niets daarvan is nodig. De extensie is gewoon een client van je bestaande product — hij heeft een credential nodig die hij kan vasthouden en een API gebouwd voor programmatische toegang. De fout is naar een nieuwe backend grijpen in plaats van de workspace-API-keys en versieerde REST-surface te gebruiken die een serieuze SaaS al heeft.
Wat Manifest V3 werkelijk toestaat
MV3 verving achtergrondpagina's door kortlevende serviceworkers en duwt extensies naar least privilege. In de praktijk: geen persistent in-memory state, geen cookie-krassen voor sessiehergebruik (HttpOnly-cookies zijn sowieso onbereikbaar), en elke hostpermission is een vraag in de webstorereview.
Het schone antwoord is wat het platform al geeft: een gescopete credential in chrome.storage.local en HTTPS-calls naar de origin van je app — aangevraagd als optionele hostpermissions tijdens setup, niet bij installatie.
supastacks MV3-scaffold: wat al is bedraad
supastacks apps/extension is een bewust kleine, frameworkloze Manifest V3-companion — 'pagina opslaan in workspace' — die het hele patroon end-to-end laat zien. Hij slaat titel, URL en geselecteerde tekst van de actieve tab op als workspace-contententry via de versieerde REST-API POST /api/v1/content-entries.
Auth gebruikt een workspace-API-key (sk_…) aangemaakt onder Settings → Developers: de key is gebonden aan precies één workspace, dus de binding is zelf de workspaceselectie — hij kan nergens anders heen schrijven. De optiepagina persist app-URL en key in chrome.storage.local, vraagt alleen toegang voor die origin en verifieert connectiviteit via GET /api/v1/workspaces/current.
apps/extension/
manifest.json MV3: service worker, least-privilege permissions
src/
background.js context-menu save + badge feedback
popup.html/.js capture UI — title, URL, selection, note
options.html/.js app URL + workspace API key setup
lib/
api.mjs versioned /api/v1 client (key auth)
capture.mjs active-tab + selection capture
config.mjs chrome.storage.local persistenceLeast privilege als standaard
De scaffold bevat alleen de minimale permissieset die het werk vereist — belangrijk voor zowel storereview als gebruikersvertrouwen:
- Geen
tabs, geen<all_urls>, geen cookies/webRequest/declarativeNetRequest — een scaffold die eerlijk verklaart wat hij niet nodig heeft.
| Permissie | Waarvoor |
|---|---|
| activeTab | Titel/URL van huidige pagina alleen bij aanroep lezen |
| scripting | Geselecteerde tekst in aangeroepen tab lezen |
| contextMenus | Rechtermuisklik 'opslaan'-menu-item registreren |
| storage | App-URL, API-key en workspace-cache persisteren |
| optional_host_permissions | App-origin gevraagd tijdens setup — nul sitetoegang bij installatie |
Van scaffold naar de companion van jouw product
Rebranden is de naam in manifest.json wijzigen; uitbreiden is het interessante deel — en blijft binnen hetzelfde patroon: nieuwe capturetypen roepen nieuwe /api/v1-endpoints aan met dezelfde key, en de getypte @supastack/api-sdk gegenereerd uit het OpenAPI-document van de app houdt requestvormen eerlijk.
Omdat de extensie leest en schrijft via dezelfde tenant-gescopete API als elke andere client, landen opgeslagen pagina's in dezelfde Postgres-regels die het webdashboard toont — één database, één auth-model, workspaceId-scoping afgedwongen op precies één plek. Geen tweede backend, geen sync, geen drift. Vergelijk niveaus op de prijspagina.
| DIY tweede-backend-aanpak | supastack MV3-scaffold | |
|---|---|---|
| Auth | Handgemaakt tokensysteem naast cookies | Workspace-API-keys — zelfde auth-model als web |
| API | Nieuwe endpoints verzonnen voor extensie | Versieerde /api/v1 + OpenAPI-getypte SDK |
| Gegevens | Tweede store + synclogica | Dezelfde Postgres-regels, workspace-gescoped |
| Permissies | Brede toegang voor gemak | Least-privilege-manifest, reviewvriendelijk |
FAQ: SaaS + Chrome-extensie op één backend
Vragen die ontwikkelaars stellen voordat ze een extensiecompanion shippen:
- Waarom een API-key in plaats van de sessiecookie van de gebruiker?, HttpOnly-cookies zijn per ontwerp onzichtbaar voor extensie-JS en MV3-serviceworkers zijn kortlevend — een gescopete
sk_…-key inchrome.storage.localis persistent, herroepbaar en aan één workspace gebonden, dus kan nooit over tenants heen schrijven. - Werkt de extensie op Firefox?, MV3 ondersteunt hetzelfde surface; de code gebruikt een
browser ?? chrome-namespaceshim en wordt Chromium-first ontwikkeld — Firefox is dus een port, geen rewrite. - Is hij direct store-ready?, Het is een scaffold met productiepatronen, geen storesubmissie — je hernoemt het manifest, voegt je eigen capturelogica toe en schrijft de listingtekst. Het moeilijke deel (auth, API, tenant-scoping) is af.
- Welk niveau bevat de extensie?, De $299 Full Bundle levert alle vijf surfaces — twee web-engines, Expo, Tauri en de extensiescaffold — in één repo.