¿Cómo construir una extensión Chrome que comparta el backend de tu SaaS?
No construyendo un segundo backend. Una extensión MV3 no puede depender de cookies HttpOnly, así que se autentica con claves API de workspace: la extensión llama a la API REST versionada de la app (/api/v1) con una clave con scope ligada a exactamente un workspace, reutilizando el mismo modelo de auth, el mismo scoping de tenant y la misma base Postgres que la app web. El scaffold MV3 de supastack — popup, página de opciones, worker en segundo plano, manifiesto de mínimos privilegios — está cableado exactamente así.
La trampa: construir un segundo backend sin darte cuenta
La historia habitual: tu SaaS necesita una extensión compañera para capturar páginas, recortar contenido o anotar la web. Seis meses después mantienes dos sistemas de auth (cookies para la web, algo artesanal para la extensión), una API paralela que la extensión sí puede llamar y una capa de sync que alinea dos almacenes de datos que deberían ser uno.
Nada de eso hace falta. La extensión es solo un cliente más de tu producto existente — necesita una credencial que pueda conservar y una API diseñada para acceso programático. El error es lanzarse a construir un backend nuevo en vez de usar las claves API de workspace y la superficie REST versionada que un SaaS serio ya tiene.
Lo que Manifest V3 permite de verdad
MV3 sustituyó las background pages por service workers de vida corta y empuja a las extensiones hacia el mínimo privilegio. En la práctica: no puedes depender de estado en memoria persistente; no debes rascar cookies para reutilizar sesiones (las HttpOnly son inalcanzables de todos modos); y cada permiso de host es una pregunta en la revisión de la web store.
La respuesta limpia es lo que la plataforma ya da: una credencial con scope en chrome.storage.local y llamadas HTTPS al origen de tu app — pedidas como permisos de host opcionales en el setup, no en la instalación.
El scaffold MV3 de supastack: lo que ya viene cableado
apps/extension de supastack es un compañero Manifest V3 deliberadamente pequeño y sin framework — «guardar página en el workspace» — que muestra todo el patrón de punta a punta. Guarda el título, la URL y el texto seleccionado de la pestaña activa como content entry del workspace vía la API REST versionada POST /api/v1/content-entries.
El auth usa una clave API de workspace (sk_…) creada en Settings → Developers: la clave está ligada a exactamente un workspace, así que el vínculo es en sí mismo la selección de workspace — nunca puede escribir en otro sitio. La página de opciones persiste la URL de la app y la clave en chrome.storage.local, pide acceso solo a ese origen y verifica la conexión 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 persistenceMínimo privilegio por defecto
El scaffold solo trae el conjunto mínimo de permisos que el trabajo necesita — importante para la revisión de la store y la confianza del usuario:
- Sin
tabs, sin<all_urls>, sin cookies/webRequest/declarativeNetRequest — un scaffold que declara honestamente lo que no necesita.
| Permiso | Para qué |
|---|---|
| activeTab | Leer título/URL de la página actual solo al invocarse |
| scripting | Leer el texto seleccionado en la pestaña invocada |
| contextMenus | Registrar la entrada «guardar» del clic derecho |
| storage | Persistir URL de la app, clave API y workspace en caché |
| optional_host_permissions | El origen de la app se pide en el setup — cero acceso a sitios al instalar |
Del scaffold al compañero de tu producto
Rebrandear es renombrar el manifest.json; la parte interesante es extender — y sigue dentro del mismo patrón: nuevos tipos de captura llaman a nuevos endpoints /api/v1 con la misma clave, y el @supastack/api-sdk tipado generado del documento OpenAPI de la app mantiene las formas de request exactas.
Como la extensión lee y escribe por la misma API con scoping de tenant que cualquier otro cliente, las páginas guardadas caen en las mismas líneas Postgres que lista el dashboard web — una base de datos, un modelo de auth, scoping por workspaceId aplicado en un solo lugar. Sin segundo backend, sin sync, sin drift. Compara niveles en la página de precios.
| Enfoque DIY de segundo backend | Scaffold MV3 de supastack | |
|---|---|---|
| Auth | Sistema de tokens artesanal junto a cookies | Claves API de workspace — mismo modelo de auth que la web |
| API | Endpoints nuevos inventados para la extensión | /api/v1 versionada + SDK tipado desde OpenAPI |
| Datos | Segundo almacén + lógica de sync | Mismas líneas Postgres, con scope de workspace |
| Permisos | Acceso amplio por comodidad | Manifiesto de mínimos privilegios, amigable en revisión |
FAQ: SaaS + extensión Chrome sobre un backend
Preguntas que hacen los desarrolladores antes de lanzar un compañero de extensión:
- ¿Por qué una clave API en vez de la cookie de sesión del usuario?, Las cookies HttpOnly son invisibles al JS de la extensión por diseño y los service workers MV3 viven poco — una clave
sk_…con scope enchrome.storage.locales persistente, revocable y ligada a un workspace, incapaz de escribir fuera. - ¿La extensión funciona en Firefox?, MV3 soporta la misma superficie; el código usa un shim de namespace
browser ?? chromey se desarrolla Chromium-first, así que Firefox es un port, no una reescritura. - ¿Está lista para la store nada más instalar?, Es un scaffold de patrón de producción, no una sumisión a la store — renombrarás el manifiesto, añadirás tu lógica de captura y escribirás el listing. La parte difícil (auth, API, scoping de tenant) ya está hecha.
- ¿Qué nivel incluye la extensión?, El Full Bundle de $299 entrega las cinco superficies — dos motores web, Expo, Tauri y el scaffold de extensión — en un repo.