pages/ folder. Manifest fields include popup, options, side panel, new tab, and DevTools. Use pages/ for routes the manifest does not name directly. Extension.js walks each entry for scripts, styles, and linked assets. You author plain HTML and Extension.js configures everything automatically.
Template examples
new

sidebar

HTML capabilities
| Capability | What it gives you |
|---|---|
| Entrypoint discovery | Compile HTML declared in manifest and pages/ with one flow |
| Asset wiring | Bundle referenced scripts and styles from HTML tags |
| Public path handling | Keep intentional public-root assets stable |
| dev tracking | Recompile on HTML and referenced asset edits |
Supported HTML entrypoints
The following manifest fields use HTML files as entrypoints:| Manifest field | File type expected |
|---|---|
action.default_popup | .html |
background.page | .html |
chrome_url_overrides.* | .html |
devtools_page | .html |
options_ui.page / options_page | .html |
page_action.default_popup | .html |
sandbox.pages | .html |
side_panel.default_path | .html |
sidebar_action.default_panel | .html |
pages/ without expanding manifest entrypoint fields for every file.
Sample HTML entry
How Extension.js processes HTML
For each HTML entrypoint, Extension.js:- emits the HTML file into compilation
- discovers local scripts/styles/static assets from tags
- bundles scripts/styles as proper extension outputs
- patches HTML to inject compiled bundle references
- keeps public-root references (like
/icon.png) as public assets
Development behavior
- Extension.js tracks HTML and referenced assets in file dependencies, so edits trigger recompilation.
- Script changes use hot module replacement (HMR) where supported in the injected script flow.
- If the HTML script/style entry list changes (add/remove entries), Extension.js can require a dev server restart.
- Changing manifest HTML entrypoints can also trigger restart-required diagnostics.
Paths and environment variables
- Extension.js resolves relative paths from the HTML file location.
- Extension.js treats leading
/paths as extension public-root paths. - Extension.js replaces
$EXTENSION_PUBLIC_*and related placeholders in emitted HTML during compilation.
Using extra pages
Place extra files inpages/:
Common extension surfaces
Most user-facing extension surfaces that render UI are just HTML entrypoints with different manifest fields and runtime expectations. Use the surface that matches the user interaction model, then keep the HTML page itself thin.| Surface | Manifest field | Good fit |
|---|---|---|
| Popup | action.default_popup or browser_action.default_popup | short, task-focused UI opened from the toolbar |
| Options page | options_ui.page or options_page | durable settings and preferences |
| Side panel | side_panel.default_path or sidebar_action.default_panel | persistent companion UI alongside the current tab |
| DevTools page | devtools_page | debugging or inspection tools for your extension |
| New tab override | chrome_url_overrides.newtab | full-screen extension-owned browser surface |
| Sandbox page | sandbox.pages | isolated HTML when sandboxed execution is required |
Popup
Use a popup for fast, focused actions:- quick status checks
- one-step commands
- small forms or toggles
Options page
Use an options page when you need to configure durable behavior:- account or integration settings
- feature toggles
- keyboard or workflow preferences
Side panel
Use a side panel when the extension needs a persistent workspace next to the current page:- research or note-taking companions
- tab-aware assistants
- page analysis results that should stay visible while you navigate
DevTools page
Usedevtools_page when the extension provides tooling for developers:
- inspection panels
- request or DOM diagnostics
- project-specific debugging helpers
New tab override
Usechrome_url_overrides.newtab when the extension owns the whole new-tab experience.
This is usually the best fit for rich, app-like UIs where a popup would be too constrained.
Sandbox page
Use sandbox pages only when the feature truly needs the sandbox model. They are HTML entrypoints too, but they exist for a narrower set of browser-extension security and execution constraints.Surface authoring pattern
A good default structure for any HTML surface is:- keep the HTML file minimal
- mount one script entry
- import styles from that script or a linked stylesheet
- move browser API coordination into dedicated modules
Best practices
- Keep entry HTML minimal and import app code through scripts.
- Use relative paths for project assets and
/paths only for intentional public assets. - Use
pages/for additional extension pages that are not primary manifest UI entrypoints. - Treat script/link add/remove changes as structural changes that may require restart.
- Choose the surface by user interaction model first, then implement it as a thin HTML page entrypoint.
- Keep surface-specific state in storage or background coordination instead of assuming the UI page always stays mounted.
Next steps
- Understand update outcomes in dev update behavior.
- Persist settings and state with Storage.
- Coordinate UI pages with Messaging.
- Learn more about special folders.
- Continue with CSS in development.

