HTML
Build extension UIs with plain HTML entrypoints while Extension.js handles asset wiring, script/style bundling, and dev-time update behavior.
Extension.js processes HTML entrypoints from manifest fields and from the special pages/ folder.
HTML capabilities
Supported HTML entrypoints
The following manifest fields use HTML files as entrypoints:
You can also add standalone pages under 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
- HTML and referenced assets are tracked in file dependencies, so edits trigger recompilation.
- Script changes use 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.
- Manifest HTML entrypoint changes can also trigger restart-required diagnostics.
Paths and environment variables
- Relative paths are resolved from the HTML file location.
- Leading
/paths are treated as extension public-root paths. $EXTENSION_PUBLIC_*and related placeholders can be replaced in emitted HTML during compilation.
Using extra pages
Place extra files in pages/:
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.
Popup
Use a popup for fast, focused actions:
- quick status checks
- one-step commands
- small forms or toggles
Keep popups small and resilient. They are often opened and closed frequently, so avoid assuming long-lived in-memory UI state.
Options page
Use an options page when the user needs to configure durable behavior:
- account or integration settings
- feature toggles
- keyboard or workflow preferences
Pair options pages with browser storage so settings survive restarts and can be read by background or content-script code.
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 the user navigates
Side panel HTML is still just an extension page entrypoint. The difference is the surface semantics, not the build pipeline.
DevTools page
Use devtools_page when the extension provides tooling for developers:
- inspection panels
- request or DOM diagnostics
- project-specific debugging helpers
Treat this as a specialized surface. It usually needs stronger messaging patterns because it often coordinates with background logic and inspected tabs.
New tab override
Use chrome_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
That pattern works well for popup, options, side panel, devtools, and new-tab surfaces.
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.
- Pick 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.
