# Chrome Extension: Summarise Any Page with Claude

> A Manifest V3 extension: click the icon, get a 5-bullet summary of the page you are reading. Bring-your-own API key, minimal permissions.

- Category: Productivity
- Version: 1.0
- Source: https://ownlyplans.com/bhaskar/chrome-extension-page-summarizer/

## Overview

A genuinely useful first extension, and a clean introduction to calling the Claude API. You will build the popup, read page text with the activeTab permission (so the extension cannot see anything until you click it), call the Messages API from the service worker and show the result.

Costs are yours and small: you use your own Anthropic API key and pay per request.

Before you start: Chrome, Node.js 20+, an Anthropic API key and Claude Code or Cursor. About 90 minutes.

## Tech stack

- Chrome Extension
- Claude API
- TypeScript

## Build steps

### 1. Scaffold the extension

Save CLAUDE.md in an empty folder. You will load the extension unpacked from a dist folder while you build.

Prompt:

```text
Read CLAUDE.md. Create a Manifest V3 extension with Vite and TypeScript: manifest.json (name "Page Summary", action popup, background service worker, permissions activeTab + scripting + storage, host_permissions only for https://api.anthropic.com/*), popup.html with a placeholder, and a build that outputs to dist. Explain how to load it unpacked.
```

**Done when:** Chrome shows the extension and clicking its icon opens the placeholder popup.

### 2. Settings: store the API key

The user pastes their key once. It is kept in chrome.storage.local on their machine only, and the popup shows a masked version so they know it is set.

Prompt:

```text
Add an options page with one password field for the Anthropic API key, a Save button and a Remove button. Save to chrome.storage.local. In the popup, if no key is saved, show "Add your API key to start" with a button that opens the options page.
```

**Done when:** Saving a key changes the popup message; removing it brings the message back.

### 3. Read the page text

With activeTab, the extension only gets access to a tab when the user clicks the icon. Use chrome.scripting to grab readable text: prefer article or main, drop nav, footer, scripts and styles.

Prompt:

```text
When the popup opens, use chrome.scripting.executeScript on the active tab to return { title, url, text }: text from article, else main, else body, with nav/header/footer/aside/script/style removed and whitespace collapsed, capped at 12,000 characters. Handle pages where scripting is not allowed (chrome:// pages, the Web Store) with a friendly message.
```

**Done when:** On a news article the popup can log the article text; on chrome://extensions it shows the friendly message.

### 4. Call Claude from the service worker

The popup sends the page text to the service worker, which calls the Messages API with the saved key. Browser calls to the Anthropic API need the header anthropic-dangerous-direct-browser-access set to true; it is acceptable here because each user uses their own key on their own machine.

Prompt:

```text
In the service worker, handle a "summarize" message: POST to https://api.anthropic.com/v1/messages with headers x-api-key, anthropic-version 2023-06-01, content-type application/json and anthropic-dangerous-direct-browser-access true. Use a fast current Claude model (check the docs for the model ID), max_tokens 400, a system prompt asking for exactly 5 short bullet points plus a one-line "Why it matters", and the page title + text as the user message. Return the text or a readable error (401 bad key, 429 rate limit, network).
```

**Done when:** Clicking the icon on an article returns a 5-bullet summary.

### 5. Make the popup feel good

States matter more than looks here: loading, error, success. Add copy and retry so the popup is useful every time.

Prompt:

```text
Design the popup at 360px wide: page title at the top, a skeleton loader while waiting, the bullets as a list, "Why it matters" in a highlighted line, and buttons Copy (copies Markdown) and Retry. Errors show the message and a Retry button. Support dark mode with prefers-color-scheme.
```

**Done when:** Loading, success and error all look intentional, in light and dark.

### 6. Cache and cost control

Opening the popup twice on the same page should not pay twice.

Prompt:

```text
Cache summaries in chrome.storage.session keyed by URL for 30 minutes. Show "Cached" with a small Refresh link when a cached summary is shown. Also skip the call and say so when the page has less than 300 characters of text.
```

**Done when:** Reopening the popup on the same page is instant and makes no network request.

### 7. Review and package

Check permissions and key handling before you share it with anyone, then zip the dist folder.

Prompt:

```text
Review the extension against CLAUDE.md rules: list every permission and why it is needed, confirm the key is never logged or sent anywhere except api.anthropic.com, and confirm no remote code is loaded. Fix anything that fails, then add a build:zip script.
```

**Done when:** The review passes and you have a zip ready for friends or the Chrome Web Store.

## Assets

### CLAUDE.md — Project root. Cursor users: save as AGENTS.md.

```
# Project rules: page summarizer extension

## What we are building
A Chrome extension (Manifest V3). Click the toolbar icon and a popup shows a short summary of the current page,
written by Claude. The user brings their own Anthropic API key, stored only in chrome.storage.local.

## Stack
- Plain TypeScript or JavaScript, no framework. Vite is fine for bundling.
- Manifest V3: popup, a service worker (background), chrome.scripting to read the page text.

## Rules
- Permissions: only "activeTab", "scripting" and "storage". No host permissions for all sites.
- The API key never leaves the extension except in the request to api.anthropic.com. Never log it.
- Calls to the Anthropic API happen in the service worker, not in the page.
- Send at most ~12,000 characters of page text. Strip scripts, styles, nav and footer first.
- Show clear states: no key yet, loading, error with a readable message, summary.
```

### Chrome extensions docs — Manifest V3, activeTab, scripting, storage.

https://developer.chrome.com/docs/extensions

### Claude Messages API — Request format, models, errors.

https://docs.anthropic.com/en/api/messages


## Build instructions by tool

### Claude Code

Open a terminal in an empty folder, run `claude`, then paste the prompt.

```text
Build the "Chrome Extension: Summarise Any Page with Claude" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/chrome-extension-page-summarizer/.
Stack: Chrome Extension, Claude API, TypeScript.
Follow the plan's steps in order: Scaffold the extension → Settings: store the API key → Read the page text → Call Claude from the service worker → Make the popup feel good → Cache and cost control → Review and package.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Claude Code.)
```

### Cursor

Open an empty folder in Cursor, start an Agent chat, then paste the prompt.

```text
Build the "Chrome Extension: Summarise Any Page with Claude" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/chrome-extension-page-summarizer/.
Stack: Chrome Extension, Claude API, TypeScript.
Follow the plan's steps in order: Scaffold the extension → Settings: store the API key → Read the page text → Call Claude from the service worker → Make the popup feel good → Cache and cost control → Review and package.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Cursor.)
```

### Lovable

Start a new Lovable project and paste the prompt as your first message.

```text
Build the "Chrome Extension: Summarise Any Page with Claude" app from the OwnlyPlans blueprint at https://ownlyplans.com/bhaskar/chrome-extension-page-summarizer/.
Stack: Chrome Extension, Claude API, TypeScript.
Follow the plan's steps in order: Scaffold the extension → Settings: store the API key → Read the page text → Call Claude from the service worker → Make the popup feel good → Cache and cost control → Review and package.
Download the full plan (Markdown) from the link above and keep it in the project root as PLAN.md.
Ask me before adding anything not in the plan. (Prepared for Lovable.)
```

## Definition of done

- Every build step is complete and the app runs locally.
- The main user flow works end to end.
- Share your build on OwnlyPlans with a demo link, build time and tool.
