Come si costruisce un'estensione Chrome che condivide il backend del tuo SaaS?
Non costruendo un secondo backend. Un'estensione MV3 non può affidarsi ai cookie HttpOnly, quindi si autentica con chiavi API workspace: l'estensione chiama l'API REST versionata dell'app (/api/v1) con una chiave con scope legata a esattamente un workspace, riusando lo stesso modello di auth, lo stesso scoping di tenant e lo stesso database Postgres dell'app web. Lo scaffold MV3 di supastack — popup, pagina opzioni, worker in background, manifesto a privilegi minimi — è cablato esattamente così.
La trappola: costruire un secondo backend senza accorgersene
La storia solita: il tuo SaaS ha bisogno di un'estensione companion per catturare pagine, clippare contenuti o annotare il web. Sei mesi dopo mantieni due sistemi di auth (cookie per il web, qualcosa di artigianale per l'estensione), un'API parallela che l'estensione riesce davvero a chiamare e un livello di sync che tiene allineati due archivi dati che dovrebbero essere uno solo.
Niente di tutto questo è necessario. L'estensione è solo un client in più del tuo prodotto esistente — le serve una credenziale che può conservare e un'API pensata per l'accesso programmatico. L'errore è allungare la mano verso un backend nuovo invece di usare le chiavi API workspace e la superficie REST versionata che un SaaS serio possiede già.
Cosa permette davvero Manifest V3
MV3 ha sostituito le background page con service worker a vita breve e spinge le estensioni verso il privilegio minimo. In pratica: niente stato in memoria persistente; niente raspamento di cookie per riusare sessioni (i cookie HttpOnly sono comunque irraggiungibili); e ogni host permission è una domanda nella revisione del web store.
La risposta pulita è ciò che la piattaforma offre già: una credenziale con scope in chrome.storage.local e chiamate HTTPS verso l'origin della tua app — richieste come host permission opzionali al momento del setup, non dell'installazione.
Lo scaffold MV3 di supastack: cosa è già cablato
apps/extension di supastack è un companion Manifest V3 deliberatamente piccolo e senza framework — «salva la pagina nel workspace» — che mostra l'intero pattern end-to-end. Salva titolo, URL e testo selezionato della scheda attiva come content entry del workspace tramite l'API REST versionata POST /api/v1/content-entries.
L'auth usa una chiave API workspace (sk_…) creata in Settings → Developers: la chiave è legata a esattamente un workspace, quindi il legame stesso è la selezione del workspace — non può mai scrivere altrove. La pagina opzioni persiste URL dell'app e chiave in chrome.storage.local, chiede accesso solo a quell'origin e verifica la connessione con 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 persistencePrivilegio minimo di default
Lo scaffold include solo il set minimo di permessi che il lavoro richiede — importante per la revisione dello store e la fiducia degli utenti:
- Niente
tabs, niente<all_urls>, niente cookies/webRequest/declarativeNetRequest — uno scaffold che dichiara onestamente ciò di cui non ha bisogno.
| Permesso | Per cosa |
|---|---|
| activeTab | Leggere titolo/URL della pagina corrente solo all'invocazione |
| scripting | Leggere il testo selezionato nella scheda invocata |
| contextMenus | Registrare la voce «salva» del tasto destro |
| storage | Persistere URL app, chiave API e workspace in cache |
| optional_host_permissions | L'origin dell'app si chiede al setup — zero accesso ai siti all'installazione |
Dallo scaffold al companion del tuo prodotto
Il rebrand è rinominare il manifest.json; l'estensione è la parte interessante — e resta dentro lo stesso pattern: nuovi tipi di cattura chiamano nuovi endpoint /api/v1 con la stessa chiave, e il @supastack/api-sdk tipizzato generato dal documento OpenAPI dell'app mantiene oneste le forme delle richieste.
Poiché l'estensione legge e scrive tramite la stessa API con scoping di tenant di ogni altro client, le pagine salvate cadono nelle stesse righe Postgres che la dashboard web elenca — un database, un modello di auth, scoping workspaceId imposto in un solo punto. Niente secondo backend, niente sync, niente drift. Confronta i livelli nella pagina dei prezzi.
| Approccio secondo backend fai-da-te | Scaffold MV3 di supastack | |
|---|---|---|
| Auth | Sistema di token artigianale accanto ai cookie | Chiavi API workspace — stesso modello di auth del web |
| API | Nuovi endpoint inventati per l'estensione | /api/v1 versionata + SDK tipizzato da OpenAPI |
| Dati | Secondo store + logica di sync | Stesse righe Postgres, scope workspace |
| Permessi | Accesso ampio per comodità | Manifesto a privilegi minimi, amico della revisione |
FAQ: SaaS + estensione Chrome su un solo backend
Le domande che gli sviluppatori fanno prima di rilasciare un companion a estensione:
- Perché una chiave API invece del cookie di sessione dell'utente?, I cookie HttpOnly sono invisibili al JS dell'estensione per design e i service worker MV3 sono a vita breve — una chiave
sk_…con scope inchrome.storage.localè persistente, revocabile e legata a un workspace, quindi incapace di scrivere fuori. - L'estensione funziona su Firefox?, MV3 supporta la stessa superficie; il codice usa uno shim di namespace
browser ?? chromeed è sviluppato Chromium-first, quindi Firefox è un port, non una riscrittura. - È pronta per lo store appena installata?, È uno scaffold di pattern di produzione, non una submission allo store — rinominerai il manifesto, aggiungerai la tua logica di cattura e scriverai il listing. La parte difficile (auth, API, scoping di tenant) è fatta.
- Quale livello include l'estensione?, Il Full Bundle da $299 consegna tutte e cinque le superfici — due motori web, Expo, Tauri e lo scaffold di estensione — in un repo.