"Every host pattern in your manifest is a square mile of internet you're asking permission to touch. Lesson 3 is the syntax, the install prompt cost, and how to design ClipDeck for the maximum reach with the minimum scary warning."
URL Match Pattern Syntax
A match pattern is three parts: scheme, host, path. Joined with :// and /:
<scheme>://<host>/<path>
Examples:
https://github.com/*— github.com root and all paths, HTTPS only.https://*.github.com/*— github.com AND any subdomain (gist.github.com, api.github.com, ...).https://github.com/anthropics/*— only repositories under the anthropics org.*://*/*— any scheme except those Chrome restricts (chrome://, etc.), any host, any path. Equivalent to<all_urls>minus a few edge cases.<all_urls>— the explicit wildcard. Matches HTTP, HTTPS, FTP, file:.
Rules:
- Scheme:
http,https,file,ftp, or*.chrome://andchrome-extension://are never matchable from a regular extension. - Host: literal, OR
*alone (any host), OR*.prefix (subdomain wildcard). Wildcards in the middle of the host (foo*.example.com) are not allowed. - Path: literal characters and
*wildcard. Path must be present; use/*for "any path."
The Install Warning Ladder
Chrome's prompt scales with how broad your hosts are:
- One specific host (
https://github.com/*) → "Read and change your data on github.com." - A subdomain wildcard (
https://*.github.com/*) → "Read and change your data on sites in the github.com domain." - Several specific hosts (
https://github.com/*,https://gitlab.com/*) → "Read and change your data on github.com and gitlab.com." Chrome lists them up to a small limit, then collapses. <all_urls>or*://*/*→ the loud "Read and change all your data on all websites."
The drop in user trust between "three hosts" and "all websites" is steep. Cluster your hosts narrowly when you can, and reserve <all_urls> for the case where you really do need to work everywhere.
The Chrome 'Runtime Host Permissions' Twist
Since around Chrome 70, users can change site access for any installed extension via the puzzle-piece menu or chrome://extensions: "On click," "On <specific site>," or "On all sites." Even if your manifest declares host_permissions: ["<all_urls>"], the user might restrict you to "On click" only — making your extension behave like an activeTab one.
Implication: your code can't assume manifest-declared host permission is the runtime state. Use chrome.permissions.contains when it matters, or design every host-touching feature to be resilient to denial (you get back a 'Cannot access contents of the page' error from scripting calls; catch it and explain).
The Content-Script Match Pattern
Content scripts have their own matches array under content_scripts. It uses the same syntax but is a separate grant from host_permissions:
host_permissionsgrants you the right to programmatically inject (chrome.scripting), fetch, and observe requests.content_scripts.matchesdeclares static, automatic injection on every page load.
Chrome unions the two for warning purposes: host_permissions: ["<all_urls>"] OR content_scripts.matches: ["<all_urls>"] trigger the same scary warning. If you want narrower hosts, narrow both fields together.
ClipDeck's Choice
ClipDeck v0.9 has content_scripts.matches: ["<all_urls>"] because the floating button and selection capture should work on any page the user visits. Two ways to soften the warning:
- Drop the always-on content script entirely. Use
activeTab+ programmaticchrome.scripting.executeScripton toolbar click or hotkey. Cost: no floating button on every page, only after user invokes. Benefit: no install warning, much friendlier. - Keep the content script but explicitly exclude sensitive hosts. Keeps the broad reach, signals to the user that some categories are off-limits. The warning is unchanged, but the trust signal is stronger.
ClipDeck v1 takes the second path because the floating button is part of the discovery story. v2 might add a per-user toggle to switch to activeTab-only mode for the privacy-minded crowd.
<all_urls> is the loudest line in any prompt — earn it. The user can downgrade your hosts at runtime; design for that.