Build a Chrome Extension
Ship a Chrome extension with user auth, cloud storage, and payments
What You'll Build
A published Chrome extension with user authentication, cloud data storage, premium tier with Stripe payments, and a landing page for distribution.
- Working Chrome extension with popup and content scripts
- User auth and cloud storage via Supabase
- Premium features gated behind Stripe payments
- Landing page on Vercel and listing on Chrome Web Store
Prerequisites
- Node.js 18+ installed
- VS Code or Cursor installed
- A GitHub account
- JavaScript/TypeScript knowledge (intermediate)
- A Chrome browser for testing
Architecture
The Chrome extension runs locally in the browser with a popup UI, content scripts for page interaction, and a background service worker for persistent logic. Supabase handles user auth (via OAuth popup) and stores user data in Postgres. Stripe manages premium subscriptions through a checkout flow hosted on your Vercel landing page. GitHub stores the code and triggers Vercel deployments.
Scaffold extension with manifest.json and popup
~20 minSet up the Chrome extension project structure with Manifest V3, a popup UI, and the basic file scaffolding.
- Create a new project directory and open it in VS Code
- Create the
manifest.jsonfile with Manifest V3 format - this is the extension's config file - Create
popup.htmlandpopup.jsfor the extension's popup UI - Create a
styles.cssfor your popup styling - Load the extension in Chrome: go to
chrome://extensions, enable Developer Mode, click "Load unpacked", and select your project folder
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "A useful Chrome extension",
"permissions": ["storage", "activeTab"],
"action": {
"default_popup": "popup.html",
"default_icon": "icon-48.png"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.js"]
}],
"icons": {
"16": "icon-16.png",
"48": "icon-48.png",
"128": "icon-128.png"
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div id="app">
<h1>My Extension</h1>
<div id="auth-section">
<button id="login-btn">Sign In</button>
</div>
<div id="main-section" style="display:none">
<p>Welcome! Extension is active.</p>
<button id="action-btn">Do Something</button>
</div>
</div>
<script src="popup.js"></script>
</body>
</html>
// Background service worker
chrome.runtime.onInstalled.addListener(() => {
console.log('Extension installed')
})
// Listen for messages from popup or content scripts
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'GET_DATA') {
// Handle data requests
sendResponse({ status: 'ok' })
}
return true // Keep message channel open for async
})
chrome://extensions open in a pinned tab during development. Click the refresh icon on your extension after every change to reload it.Build the core feature in content and background scripts
~40 minImplement your extension's main functionality using content scripts for page interaction and the background service worker for logic.
- Create
content.js- this runs on every page the user visits and can read or modify the DOM - Use
chrome.runtime.sendMessage()in the content script to communicate with the background worker - In
background.js, handle messages and usechrome.storage.localto persist data between sessions - Build the popup UI logic in
popup.js- query the active tab and display relevant data - Test thoroughly: load the extension, visit a page, open the popup, and verify all communication works
// Content script - runs on web pages
(function() {
// Example: extract page data
const pageData = {
title: document.title,
url: global.location.href,
text: document.body.innerText.substring(0, 1000)
}
// Send data to background script
chrome.runtime.sendMessage(
{ type: 'PAGE_DATA', data: pageData },
(response) => console.log('Saved:', response)
)
})()
global.postMessage if you need to communicate with page scripts.Set up Supabase for user data and auth
~30 minAdd user authentication and cloud data storage so users can sync their extension data across devices.
- Create a Supabase project at supabase.com and grab your project URL and anon key
- Install the Supabase JS client by including it via CDN in your popup.html or bundling it
- Implement Google OAuth login in your popup - Supabase handles the OAuth flow, you just need to open the auth URL
- Create a
user_datatable in Supabase to store user-specific extension data - Enable Row Level Security so users can only access their own data
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://your-project.supabase.co'
const supabaseKey = 'your-anon-key'
export const supabase = createClient(supabaseUrl, supabaseKey)
export async function signInWithGoogle() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: chrome.identity.getRedirectURL()
}
})
return { data, error }
}
export async function saveUserData(userId, data) {
return await supabase
.from('user_data')
.upsert({ user_id: userId, ...data })
}
chrome.identity.getRedirectURL() for your OAuth redirect - Chrome provides a special URL for extension auth flows that avoids CORS issues.Create landing page on Vercel and publish to Chrome Web Store
~30 minBuild a landing page for your extension, push your code to GitHub, and submit to the Chrome Web Store.
- Create a Next.js or static landing page with: hero section, feature list, pricing, and a "Add to Chrome" CTA button
- Deploy the landing page to Vercel by connecting your GitHub repo
- Add your Stripe webhook endpoint and checkout API routes to the Vercel project
- Package your extension: zip the extension folder (excluding node_modules and .git)
- Go to the Chrome Web Store Developer Dashboard, pay the $5 registration fee, upload your zip, add screenshots and descriptions, and submit for review
# Package extension for Chrome Web Store
cd my-extension
zip -r ../my-extension.zip . -x "node_modules/*" ".git/*" "*.map"
🎉 You're Done!
A published Chrome extension with user authentication, cloud data storage, premium tier with Stripe payments, and a landing page for distribution.
Want this built for you?
Get a step-by-step checklist, setup order, and the exact config for every tool in this guide. Or let me build it for you.
Get the checklist → Want this built for you?