> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Predictable path resolution

> Write paths naturally and let Extension.js normalize them to runtime-safe output. Handles manifest fields, public assets, and extension API references.

Write paths the way you naturally author them, and let Extension.js normalize them to runtime-safe output paths.

Keep runtime paths working when you move files, rename entries, or change browser targets. Extension.js rewrites supported paths across manifest fields and extension API usage. Compiled assets resolve correctly inside `dist/<browser>`.

## How it works

Path resolution runs in two places:

* **Manifest compilation pipeline**: resolves manifest-declared paths to emitted assets.
* **Path-resolve plugin for JS/TS**: rewrites static path literals passed to supported extension APIs (for example, `runtime.getURL`, `tabs.update`, `scripting.*`, `action.*`, `sidePanel.*`).

## Supported input styles

Extension.js normalizes common path inputs as follows:

| Input style                      | Example                                            | Normalized output                                                    |
| -------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------- |
| Public root (absolute)           | `/public/icons/icon.png`                           | `icons/icon.png`                                                     |
| Public root (relative)           | `public/icons/icon.png`, `./public/icons/icon.png` | `icons/icon.png`                                                     |
| Root absolute                    | `/foo/bar.js`                                      | `foo/bar.js`                                                         |
| Root special folder              | `/pages/popup.njk`                                 | `pages/popup.html`                                                   |
| Special folders                  | `pages/popup.html`, `scripts/content.tsx`          | `pages/popup.html`, `scripts/content.js`                             |
| Parent-relative from author file | `../scripts/content.ts`                            | `scripts/content.js` (when resolving to project root special folder) |

Extension mapping for `pages/` and `scripts/` includes:

* `.ts`, `.tsx`, `.js`, `.jsx` → `.js`
* `.njk`, `.nunjucks`, `.html` → `.html`
* `.scss`, `.sass`, `.less`, `.css` → `.css`

## Cases Extension.js does not rewrite

To avoid false positives, Extension.js intentionally skips these inputs:

* `http://` and `https://` URLs
* `data:` URLs
* `chrome://` URLs
* `moz-extension://` URLs
* Glob patterns (`*`, `?`, `{}`, `[]`)
* Non-static/dynamic expressions that the build cannot safely resolve

## Manifest output examples

Assuming target browser `chrome`:

| Manifest field                 | Input path                 | Output path                     |
| ------------------------------ | -------------------------- | ------------------------------- |
| `action.default_popup`         | `/src/popup.html`          | `action/index.html`             |
| `background.page`              | `/src/background.html`     | `background/index.html`         |
| `background.service_worker`    | `/src/background.ts`       | `background/service_worker.js`  |
| `browser_action.default_popup` | `/src/popup.html`          | `action/index.html`             |
| `chrome_url_overrides.newtab`  | `/src/newtab.html`         | `newtab/index.html`             |
| `content_scripts.js`           | `/src/content_script.ts`   | `content_scripts/content-0.js`  |
| `content_scripts.css`          | `/src/content_style.css`   | `content_scripts/content-0.css` |
| `devtools_page`                | `/src/devtools.html`       | `devtools/index.html`           |
| `options_ui.page`              | `/src/options.html`        | `options/index.html`            |
| `sandbox.pages`                | `/src/sandbox.html`        | `sandbox/page-0.html`           |
| `side_panel.default_path`      | `/src/sidepanel.html`      | `sidebar/index.html`            |
| `sidebar_action.default_panel` | `/src/sidebar_panel.html`  | `sidebar/index.html`            |
| `storage.managed_schema`       | `/src/storage_schema.json` | `storage/managed_schema.json`   |
| `user_scripts.api_script`      | `/src/user_script.ts`      | `user_scripts/api_script.js`    |

Not every manifest field maps to a folder with the same source name. Extension.js bases output paths on the browser-facing extension contract, not on your original authoring path.

Extension.js emits all compiled outputs under `dist/<browser>`.

## Referencing output files

For browser APIs like `chrome.runtime.getURL()`, prefer stable, output-root paths:

```javascript theme={null}
const iconUrl = chrome.runtime.getURL("/icons/icon.png");
console.log(iconUrl);
```

Output: `chrome-extension:<extension-id>/icons/icon.png`

## Diagnostics and safety checks

The resolver warns you when it cannot resolve a referenced path to a packaged asset (for example, nested `src/pages/...` or missing `public/` files after rewrite).\
Extension.js de-duplicates warnings per file transform pass to reduce noise.

## Important path rules

* Leading `/` means extension output root, not filesystem root.
* `public/...` and `/public/...` normalize to output-root assets.
* `pages/` and `scripts/` are special folders with extension mapping rules.
* Extension.js preserves absolute OS file paths instead of treating them as extension output paths.
* Extension.js skips dynamic expressions when it cannot safely determine the final packaged path.

## Best practices

* Keep `pages/`, `scripts/`, and `public/` at project root for predictable rewrites.
* Use static literals for extension API paths when possible; Extension.js may skip dynamic expressions.
* Treat `/public/...` as output-root assets and avoid source-relative assumptions at runtime.
* Validate warnings during `dev` as they usually indicate path mismatches before packaging.

## Next steps

* Learn more about [Special folders](/docs/features/special-folders).
* Learn more about [web-accessible resources](/docs/implementation-guide/web-accessible-resources).
