The Manifest Redirect 1

An open web app manifest contains information that a web browser needs to interact with an app. A manifest is one of the key things that distinguishes an open web app from a website. It is a JSON file with a name and description for the app, and it can also contain the origin of the app, icons, and the permissions required by the app, among other things. The browser that handles the manifest must incorporate a Web runtime. This article explains the possible contents of the manifest in detail.

The manifest file should be called manifest.webapp, and be placed in the root of your web app directory alongside your index.html file.

To self-publish an app from a page that you control, you trigger installation of the app (for example, by calling navigator.mozApps.install() from a button). When a store or marketplace publishes an app, it triggers installation of the app by providing the browser with the URL of the manifest of the hosted app.

See About app manifests for a FAQ. You can also use our manifest validator. This tool will look at your manifest and help identify errors.

Example manifest

The following is a minimal manifest. You can copy it into a text file and replace the values with your own information.

Note: Your app might need more than just a minimal manifest. See the documentation below on all manifest fields.

  "name": "My App",
  "description": "My elevator pitch goes here",
  "launch_path": "/index.html",
  "icons": {
    "128": "/img/icon-128.png"
  "developer": {
    "name": "Your name or organization",
    "url": ""
  "default_locale": "en"

Manifest fields

The following fields are allowed in the manifest. There are only three required fields for the manifest to validate: name, description and icons (with a 128px icon included). There are other fields that are required if you use certain fields. This is indicated in the documentation.

The fields in your manifest can be in any order. Fields in the manifest other than the ones given below will be ignored.


(Firefox OS only, optional) Specifies a set of Web Activities that this app supports. Each property in this field is an activity. Activity names are free-form text, and each activity is represented by an object. Here is an example activities field with one activity named share:

"activities": {
  "share": {
    "filters": {
      "type": [ "image/png", "image/gif" ]
    "href": "foo.html",
    "disposition": "window",
    "returnValue": true

The object for the share activity in the example has these properties: filters, href, disposition and returnValue. These are described in Activity handler description.


(optional) The absolute path to the application cache (AppCache) manifest. When an Open Web App is installed, the AppCache manifest will be fetched and parsed, and its static assets under the CACHE header will be cached.

"appcache_path": "/cache.manifest"


Requires Firefox OS 1.1 (optional) Adds a navigation interface at the bottom of the screen. This is a quick way to give some navigation controls to an app that doesn't provide its own back button.

The navigation area is collapsed on the left in the graphic below. If you drag it up, it looks like the right.

chrome navigation


"chrome": { "navigation": true }

Note: This option should be a last resort. Consider adding a back button to your app interface to provide the best user experience.


(optional) Specify a Content Security Policy for the app. This policy gets applied to all pages loaded in the app. See the Apps CSP page for more information.


(required when locales is present) A language tag (RFC 4646) that tells what language your manifest uses. Do not include the language tag you use here in the locales field. It is a good practice to define default_locale even if you do not use locales. The Firefox Marketplace will use it to know what language your manifest is in, so it can use the correct locale values in translated fields. If you do not define default_locale, the Marketplace has to guess the language based on the serving locale. default_locale is not used by the device that installs the app.

Example for English:

"default_locale": "en"​


(required) A human-readable description of the app (maximum length is 1024 characters).


(optional but see Note below) Information about the developer of the app. It has these properties:

  • name - The name of the developer.
  • url - The URL of a site containing more information about the app's developer. This URL is typically rendered when the user clicks on the name of the app's developer while viewing details about an app inside the dashboard (or browser).

Note: Firefox Marketplace requires all submitted apps to include a developer name to display on the app's listing.


(Firefox OS only, optional) Set this to true or false to indicate whether the runtime should launch the app in full-screen mode. Example:

"fullscreen": "true"


(required) A map of icon sizes to URIs of the icons (which may be absolute paths or data URIs). Paths beginning with / are treated as relative to the origin of the app. Icons must be square and are intended to visually represent the app. Icons should not have solid backgrounds that extend to all four corners of the icon.

For Firefox OS, icons should follow the app icon guidelines, they should not have a drop shadow, and they should be in the following sizes:

128 x 128
For display on the Firefox Marketplace
60 x 60
For the actual on-device icon; only the 128px icon is mandatory, but it is recommended to include this size as well for optimal device icon display
32 x 32, 90 x 90, 120 x 120 and 256 x 256
These icons are needed for optimal display on various other platforms your app can be installed on, such as Windows 7 and Android.

You can specify multiple icons like so:

"icons": {
  "60": "/img/icon-60.png",
  "128": "/img/icon-128.png"

Note: On the Windows 7 and Android platforms, the following app icon sizes are supported: 16 x 16, 32 x 32, 48 x 48, 64 x 64, 128 x 128 and 256 x 256.


(optional) One or more sites that are allowed to trigger installation of the app. This field is intended to be used with a paid app (an app that will be purchased) to identify the stores with which you have a commercial relationship. If you have a free app, it is recommended that you allow it to be installed from anywhere by omitting this field.

This is an array of origins in the format <scheme name> + <domain>. Example:

"installs_allowed_from": [

The array ["*"] means that installations of this app are allowed from any site. This is the default. Note that an empty array [] would disallow installation from any site, including your own.

This field can be used by receipt validators to control which stores can issue receipts for your app.

Note: Do not put a trailing slash at the end of URLs in this array. For example, this is incorrect: If you use a trailing slash, the installation will fail. There is a bug on this here.

Note: If one of your installation URLs is the Firefox Marketplace, you must include


(optional, required for packaged apps) The path within the app's origin that is loaded when the app starts. If not provided, the app's origin is treated as the launch domain URL. Read Path Handling for additional details; there are special considerations if your app isn't located at the root of its domain.

In a packaged app, this field specifies the starting point of the content local to the zip file containing the packaged app. For example, if launch_path has a value of /myApp/index.html, when the packaged app is launched it will open the file /myApp/index.html.

Caution: the launch_path value should always be a relative path from the origin of the server (or root of the ZIP file, in the case of a packaged app.) Even if your index.html file is located at the origin/root, the value should be /index.html, not just index.html.


(optional) A map of one or more locale-specific overrides of the data contained in the manifest, which UIs use to provide localized views based on the accessing device's locale. For example, if you have Italian speakers installing your app, you probably want to give them Italian UI text. Each locale entry is keyed on a language tag (RFC 4646) and contains a sparse representation of the manifest. Any field that is present in the locale field overrides the matching field in the manifest. You cannot override these fields: default_locale, locales itself, and installs_allowed_from. A manifest that overrides any of these fields is invalid. When locales is present, default_locale must also be present.

Keys for this field should be in the format of xx-YY or xx. For example, you should prefer the format pt-BR and es over alternatives like pt_br, pt_BR, or ES. The Firefox Marketplace enforces this recommendation for consistency.

Note: It is recommended that the locales keys match the actual content localization to give a hint to the user that the application will be available in their language or not. Failing to provide a perfect matching between the content localization and the locales keys will not create any technical problems but will have bad consequences with regard to the user experience and developer reputation.

Example with Spanish and Italian:

"locales": {
"es": {
  "description": "¡Acción abierta emocionante del desarrollo del Web!",
  "developer": {
    "url": ""
"it": {
  "description": "Azione aperta emozionante di sviluppo di fotoricettore!",
  "developer": {
    "url": ""


(Firefox OS only, optional) Indicates the system messages that you are allowing the app to capture. This is an array that specifies mapping between system messages and pages that will display when the messages occur. Example from a Firefox OS app:

"messages": [
  { "telephony-new-call": "/dialer/index.html#keyboard-view" },
  { "bluetooth-dialer-command": "/dialer/index.html#keyboard-view" },
  { "headset-button": "/dialer/index.html#keyboard-view" },
  { "notification": "/dialer/index.html#keyboard-view" },
  { "alarm": "/facebook/fb_sync.html" }

In this example, when the system message telephony-new-call occurs (indicating an incoming phone call), the device will display the page /dialer/index.html at the anchor #keyboard-view. This page should do something like give the user an indication of the call and provide controls to answer the call.

Note: Until bug 800431 is resolved, the specified pages must be the same as the one which registered for that message.


(required) A human-readable name for the app (maximum length is 128 characters).

Note: If you change the name of your app after distribution the name will not be updated for any existing installations.


(Android & Firefox OS only, optional) An array that defines the orientations at which the application will stay locked, even if the device orientation changes. Each entry in the array can be one of portrait, landscape, portrait-primary, landscape-primary, portrait-secondary or landscape-secondary. The options containing -primary and -secondary lock the orientation in only one device orientation, even if the device orientation changes. The options without -primary and -secondary combine both rules of primary and secondary together. The options additionally suffixed with -secondary imply a 180 degree rotation from the options without the suffix. For instance, holding the phone upside down (but still in a manner where width is less than height), implies the portrait-secondary orientation. If this field has a valid value, the runtime will not change the orientation of the view rendering the application even if the device is turned. Example:

"orientation": ["portrait","landscape-secondary"]


Requires Firefox OS 1.1 (privileged or certified apps only) Used to give an origin to a privileged or certified packaged app. You do not need this field for hosted apps, which already have an origin (the website that they are served from). One use for this field is to make it easier to give your packaged app an authentication capability like OAuth or Persona.

There is a special protocol that is internal to a packaged app, which is app://<UUID>, where <UUID> is a long string that is unique to each device that the app is installed on. This URL is not easily available to app developers at this time. The origin field enables you to replace this UUID with a single domain name that will be used by each installed app, such as app://

The domain name you use should be a domain that you control. The app probably will not be approved for the Firefox Marketplace if it is a domain like app:// and you are not Facebook.

Example (make sure you use the app:// protocol):

"origin": "app://"


(optional) The set of permissions that the app needs. The permissions control access to sensitive device APIs (WebAPIs), and an app must list every WebAPI it intends to use that requires user permission. If an app tries to use one of these APIs without a corresponding entry in the permissions field, it will fail.

Note: Most of these permissions only make sense for privileged apps or certified apps, not for hosted apps.

The permissions field is an object, with each property specifying a single permission. Each API entry must have a description property. Some APIs also require an access property. Example of the permissions field:

"permissions": {
  "contacts": {
    "description": "Required for autocompletion in the share screen",
    "access": "readcreate"
  "alarms": {
    "description": "Required to schedule notifications"
  • description - A string specifying the intent behind requesting use of this API. This property is mandatory.
  • access - A string specifying the type of access required for the permission. This property is only required for a few APIs. The possible values are readonly, readwrite, readcreate, and createonly.

There are many WebAPIS. For the full list of permissions you can use, see App permissions.


(Firefox OS only, privileged and certified apps only) A privileged or certified app might need to do external authentication. For example, the app could do Facebook OAuth authentication so it can get a person's contacts. When the authentication server is finished, it will usually redirect the app back to a URL that you control.

But a privileged or certified app does not have a valid Web URL that can be redirected to, because the app is not hosted anywhere (it is a packaged app with no public origin). So you use the redirects field to redirect a Web URL to an internal app URL.


"redirects": [
  {"from": "",
    "to": "/redirects/redirect.html"},
  {"from": "",
    "to": "/redirects/dialogs_end.html"}

The from field labels the Web URL and the to field labels the internal app URL to redirect it to. The internal app URL must be a relative URL, do not use a protocol like http:// in front of it.

The scope of the redirections that are declared by redirects is limited to the app that declares them. That makes it so that several apps can redirect the same public URL to their own local resources, and it also prevents global hijacking of public URLs by an application.

Note: The URL defined in from will only be recognized and handed over to the internal to path when it was requested via HTTP redirect (30x HTTP status header). Opening the URL without HTTP redirect will ignore the redirects setting.


(optional) The app's type, which can be web, privileged, or certified. These types of apps have different levels of access to sensitive device APIs (WebAPIs). These types are described below but for more information see Packaged apps. For more information on access to WebAPIs, see the permissions field.

  • web - A regular hosted app. This type has the least access to WebAPIs. If you do not specify the type field in the manifest, web is the default.
  • privileged - An authenticated app that has been approved by an app store such as the Firefox Marketplace. This type has greater access to WebAPIs than a web app.
  • certified - An authenticated app that is intended for critical system functions like the default dialer or the system settings app on a smartphone. It is not intended for 3rd party apps in an app store. This type of app has the highest level of access to WebAPIs.


"type": "privileged"


(optional) A string that represents the version of the manifest. The Web runtime does not use this value in any way, so this can be any value. You can add this string to the manifest and extract it to help deal with various update cases. See Updating Apps.

Path handling

All fields that hold paths in the manifest must be absolute paths (for example, /images/myicon.png), and the paths must be served from the same origin as the app.

Also, there are two ways to set launch_path:

  • If your app is stored in the root of a Web server, for example, then launch_path must be set to /.
  • Otherwise, if your app is stored in a subdirectory, for example, then launch_path must be set to /mywebapp/.

Validating a manifest

To validate a manifest, use this website:

There is also an API you can use to validate a manifest:

Serving manifests

The app manifest must be served from the same origin that the app is served from.

The manifest should be stored with a file extension of .webapp. App manifests must be served with a Content-Type header of application/x-web-app-manifest+json. This is currently not enforced by Firefox but is enforced by the Firefox Marketplace. Firefox OS only checks this if the origin of the page where the user triggers the install is different from the origin of the app itself. You don't need other headers such as Content-Security-Policy and X-UA-Compatible.

Manifests can be served over SSL to mitigate certain classes of attacks. You can also serve the manifest with HTTP compression. The manifest should not be cached.

The manifest must be in UTF-8 encoding in order for the app to be submitted to Firefox Marketplace. It is recommended that you omit the byte order mark (BOM). Other encodings can be specified with a charset parameter on the Content-Type header (i.e. Content-Type: application/x-web-app-manifest+json; charset=ISO-8859-4), although this will not be respected by the Marketplace.

User Agents when possible should meaningfully message the site identity and TLS status when prompting a user to install an app.

Serving from Apache

In your .htaccess file, you must add the following:

AddType application/x-web-app-manifest+json .webapp
Note: This assumes you're using .webapp as an extension. If you are using .json or another extension, you will have to update the code to reflect that.

If you don't have a .htaccess file, create it in the root directory of your server. If this doesn't work, your host may require you to also add AddHandler x-web-app-manifest+json .webapp.

Serving from nginx

You need to edit your mime.types file in the conf directory. This will probably be located in either /etc/nginx/ or /opt/nginx/.

You should have something similar to below. Add the last line.

types {
text/html   html htm shtml;
text/css    css;
text/xml    xml;
application/x-web-app-manifest+json   webapp;
Note: This assumes you're using .webapp as an extension. If you are using .json or another extension, you will have to update the code to reflect that.
Serving from GitHub

If you serve your manifest file from GitHub Pages, GitHub will serve it with the Content-Type header of application/x-web-app-manifest+json. You must use the .webapp file extension on your manifest file. Example: manifest.webapp.

Serving from Python

If you have Python installed, you can easily run a server from the local directory, by running Python and pasting the same:

import SimpleHTTPServer
import SocketServer
SimpleHTTPServer.SimpleHTTPRequestHandler.extensions_map['.webapp'] = 'application/x-web-app-manifest+json'
httpd = SocketServer.TCPServer(("", 3000), SimpleHTTPServer.SimpleHTTPRequestHandler)
Serving from Rack (Ruby)

In config/initializers/mime_types.rb, add:

Rack::Mime::MIME_TYPES['.webapp'] = 'application/x-web-app-manifest+json'

Updating manifests

For information on updating apps, see Updating apps.

Document Tags and Contributors

Last updated by: Sheppy,