Internal URLs

Firefox and other Gecko applications use several URL schemes (protocols) for internal or “special” resources.

The main ones are:

There are other special protocols like moz-icon and various places URLs, but at the moment they are not covered here.

moz-src URLs

URLs look like: moz-src:///browser/components/BrowserGlue.sys.mjs.

Note that there is no “host” component (nothing between the second and third slash). In future we may support non-empty hosts with specific meanings. For now, always use a triple slash.

Everything after this is the full source path of the file you are referencing.

Of course this is an abstraction: the URL will only work if the file is actually packaged.

Packaging

To package a file for use via moz-src, include it in a moz.build file inside a MOZ_SRC_FILES instruction.

All files are packaged in the toolkit omni.ja file. Internally, the URL is translated into a jar:file URL into the toolkit (gre) omni.ja file.

Security considerations

Only privileged (system principal / “chrome” privileged) code can load or link to moz-src URLs.

The intention is that in future we make it possible to have more fine-grained restrictions for moz-src URLs with non-empty “host” portions (e.g. moz-src://about/ for content only accessible to about: pages), but this has not yet been implemented.

resource URLs

URLs look like resource://mapping/optional/path/components/file.txt.

Here, mapping is an arbitrary identifier chosen elsewhere. There are 3 builtin mappings of note:

  • gre (“Gecko Runtime Environment”) for some of the content inside the “toolkit” omni.ja file

  • app, for some of the content inside the “browser” (or other application-specific) omni.ja file.

  • android, on Android, for APK contents.

The app mapping is the default, which means that if you use a resource URL without a host component (resource:///whatever), it is equivalent to the app URL: resource://app/whatever.

Each mapping is resolved to a URL in the resource URL protocol handler, after which any subsequent path/file components are resolved relative to that URL.

Additional mappings can be added via a chrome.manifest instruction. Builtin extensions make use of this, as do some components.

Packaging

The builtin app and gre mappings, as well as any additional mappings from jar.mn files and other non-extension parts of the build, always resolve into the app-specific and toolkit omni.ja file, respectively.

To package files for access via resource URLs, use jar manifest file instructions to package files into the mapped directory inside omni.ja .

Security considerations

By default resource URLs cannot be accessed by web content and are restricted to privileged (system principal / “chrome” privileged) code. However, you can register a resource mapping with contentaccessible=yes in order to “holepunch” this restriction. Note that this means everything packaged under that path becomes linkable and loadable by all web content. With few exceptions (like user agent stylesheets), that is not what you want.

Unfortunately more fine-grained restrictions are not available for resource URLs.

chrome URLs

chrome URLs take one of three forms:

  • chrome://browser/content/browser.xhtml

  • chrome://browser/skin/browser.css

  • chrome://browser/locale/browser.properties

The first (“host”) component after chrome:// is the package name. Common ones are browser (for front-end Desktop Firefox files) and global (for content used by Gecko/toolkit code), but different parts of the codebase can and do register their own packages.

The second component after chrome://{packagename}/ is always one of content, skin or locale, known as “providers”. They cater to JS and HTML (content), style information (skin) and old-style .properties localization files (locale).

Any path portions after the provider are relative paths to where that particular package & provider combination is pointing.

More information is available in the build system’s chrome registration docs.

Packaging

To package files for access via chrome URLs, use jar manifest file instructions to package files into the mapped directory inside omni.ja .

Depending on how and where the chrome is registered, the files are typically packaged into either the app or toolkit omni.ja file, though it is possible to use chrome URLs inside builtin extensions as well.

Security considerations

By default chrome URLs cannot be accessed by web content and are restricted to privileged (system principal / “chrome” privileged) code. However, you can register a chrome content mapping with contentaccessible=yes in order to “holepunch” this restriction. Note that this means everything packaged under the content, skin and locale packages for that identifier becomes linkable and loadable by all web content. Please do not use this functionality going forward.

Unfortunately more fine-grained restrictions are not available for chrome URLs.