Abstract

This is a work in progress! For the latest updates from the Web Applications (WebApps) Working Group possibly including important bug fixes, please look at the draft on GitHub.

This specification defines a manifest, which provides developers with a centralized place to put metadata about a web application. This includes, amongst other things, the ability to specify the name of the web application, links to icons, as well as the preferred URL at which the web application should open when it is launched by the user.

With this metadata, user agents can provide, for example, enhanced bookmarking capabilities such as being able to add a web application to the homescreen of a device - as well as the various icons needed to effectively integrate with an OS's task switcher and system preferences. The specification also defines an API to enable bookmarking from within a document, as well as a means to check if an application is running in a special mode called "standalone".

This specification also defines the manifest link type, which provides a declarative means for a web document to be associated with a manifest.

Status of This Document

This is a work in progress! This specification is for review and not for implementation! For the latest updates, including important bug fixes, please look at the draft on GitHub instead.

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

Implementors should be aware that this specification is not stable. Implementors who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation phase should join the aforementioned mailing lists and take part in the discussions.

This document was published by the Web Applications (WebApps) Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webapps@w3.org (subscribe, archives). All comments are welcome. You can also File a bug.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

1. Usage Examples

This section shows how the expected usage of the various features provided by this specification.

1.1 Example manifest

This section is non-normative.

The following shows a typical manifest.

Example 1: typical manifest
{
  "name": "Example",
  "url": "/start.html",
  "mode": "standalone",
  "icons": [{
      "src": "icon/lowres",
      "density": "1",
      "width": "64",
      "type": "image/webp"
    }, {
      "src": "icon/hd",
      "density": "2",
      "width": "64"
  }]
}

1.2 Example of linking to manifest

Example of using a link element to associate a website with a manifest. The example also shows how HTML fallbacks, such as "application-name", can be used to support legacy user agents that don't implement this specification.

Example 2: linking to a manifest
<!doctype html>
<html>
<head>
<title>The Best News - international</title>

<!-- link to bookmark metadata -->
<link rel="manifest" href="add_to_homescreen.json">

<!-- fallback metadata for legacy browsers -->
<meta name="application-name" content="Best News!">
<link rel="shortcut icon" src="favicon.ico">
</head>
...

1.3 Example of using the API

Check if the application is running in standalone mode.

Example 3: detecting standalone mode
<script>
if("standalone" in navigator && navigator.standalone){
   //Do standalone specific stuff...
   document.documentElement.classList.add("standalone");
}
</script>

1.4 Request adding to homescreen

Let the user bookmark the application through clicking a button.

Example 4: requesting to bookmark a web app
<script>
var installButton = document.querySelector("#install");

//Bookmarking only works if initiated by user interaction
installButton.addEventListener("click", function(e){
   navigator.requestBookmark("path/to/bookmark.json")
   .then(thankUser, stopBuggingUser);
});
</script>

<button id="install">
  Bookmark <b>Awesome App!</b>
</button>

2. Use cases and requirements

This document attempts to address the Use Cases and Requirements for Installable Web Apps.

3. manifest

A manifest is a [JSON] document that consists of a top-level object that can contain zero or more members, some of which contain other objects. Each of the members, as well as how their values are processes, are defined below.

Algorithms in this specification use the conventions described in [ECMASCRIPT], such as the use of steps and sub-steps, and so on. The parseFloat method, ToString, HasOwnProperty, [[GetOwnProperty]], and ToBoolean abstract operations, and the Type(x) notation referenced in this section are defined in [ECMASCRIPT]. Processing also relies on various algorithms defined in [HTML], [FETCH], and [URL].

As the manifest format is a [JSON] document, this specification relies on the types defined in [JSON] specification: namely object, array, number, and string. Strict type checking is not enforced by this specification. Instead, each member's definition specifies the steps required to process a particular member.

When an algorithm asks the user agent to issue a developer warning, the user agent MAY report the conformance violation to the developer in a user-agent-specific manner (e.g., show the problem in the error console), or MAY ignore the error and do nothing

In the algorithms, to ignore means that the user agent MUST act as if the developer had not declared the particular member in the manifest document.

3.1 name member

The name is a string that represents the name of the application as is usually displayed to the user (e.g., amongst a list of other applications, or as a label underneath an icon).

The steps for processing the name of an application is given by the following algorithm. The algorithm takes a manifest as an argument. It returns either undefined, a string, or an error.

  1. If HasOwnProperty(manifest, "name") returns false, then return undefined.
  2. Let value be the result of calling the [[GetOwnProperty]] internal method of manifest with argument "name".
  3. If Type(value) is not "string", return an error.
  4. Strip leading and trailing whitespace from result.
  5. Return the result.

3.2 dont-share-cookies-and-stuff member

Issue 1

Yes, this needs to be renamed. Possible candidates: "isolated" or "isolated-security-origin", "independent"

The dont-share-cookies-and-stuff member is a boolean that allows a developer to request that the user agent treat this web application as independent from the one in the web browser. Effectively, this means that cookies, storage, and permissions are not shared with the origin from which the application was bookmarked. The value of this member is only applicable to applications whose mode of operation is standalone.

The steps for processing the dont-share-cookies-and-stuff member is given by the following algorithm:

  1. Let value be the result of calling the [[GetOwnProperty]] internal method of manifest with argument "dont-share-cookies-and-stuff".
  2. Let result be the result of calling ToBoolean(value).
  3. Return the result.

3.3 url member

The url member is the URL that is loaded when the application is launched. When it's missing from the manifest, the UA loads the URL from the manifest was fetched.

The steps for processing the url member are given by the following algorithm. The algorithm returns a URL.

  1. If HasOwnProperty(manifest, "url") returns false, then return undefined.
  2. Let value be the result of calling the [[GetOwnProperty]] internal method of the manifest with argument "url".
  3. Let manifest URL be the URL from which the manifest was fetched from.
  4. If value is undefined or Type(value) is not "string":
    1. Let result be manifest URL.
  5. Otherwise:
    1. Parse value, using manifest URL as the base URL, and let result be the result.
  6. Return result.

3.4 icons member

The icons is a list of icon objects that represents a set of icons that the application can make use.

The steps for processing the icons member are given by the following algorithm. The algorithm returns a list of icons, which can be empty, or undefined.

  1. If HasOwnProperty(manifest, key) returns false, then return undefined.
  2. Let icons be an empty list.
  3. Let manifest URL be the URL from which the manifest was fetched from.
  4. Let value be the result of calling the [[GetOwnProperty]] internal method of manifest with argument "icons".
  5. If value is an array, then for each potential icon in the array:
    1. Let src be the result of running the steps for processing the src member of an icon. If the result is an error, stop processing this potential icon and move to the next potential icon in value, if any.
    2. Let type be the result of running the steps for processing the type member of an icon.
    3. If type is not a valid MIME type or the value of type is not a supported icon format, then stop processing this potential icon and move to the next potential icon, if any.
    4. Let width be the result of running the steps for processing the dimensions of an icon with "width" as the argument.
    5. Let height be the result of running the steps for processing the dimensions of an icon with "height" as the argument.
    6. Otherwise, let icon be an object.
  6. return icons.

3.5 orientation member

Issue 2

This is issue 74 on GitHub. We are looking for feedback!

Orientation of an application is dependent on the media features of the display. For example an application might need to be launched in landscape on phones (in order to have sufficient display width), but prefer to be in portrait on tablets. (see Orientation section in the use cases document).

When analyzing applications across various runtimes, we've found evidence that such applications are common (e.g., basically any application on the iPhone that has an iPad counterpart will be designed to constrain to a particular orientation based on the device being used: LinkedIn, Flipboard, GoodReads, etc. will all go from portrait-primary on the iPhone to allowing "any" orientation on the iPad. A more extreme example is BBC iPlayer - which supports portrait-primary on the iPhone, but both landscape orientations on iPad. The same can be seen on Android devices. Unlike native apps, Web Apps should not target devices/OS's - they have to be device neutral.

In order to address the use cases, we currently have two proposals.

Option 1: Provide a list of orientation sets in the manifest. The user agent uses the first one with a matching media query. The order in which the orientations are listed by a developer does not imply a preference for setting the orientation - it is always left up to the user agent to pick the best orientation given, for example, how the user is holding the device. In the example below, no orientation is given for widths of 721px or above, so the default is used: allowing all orientations supported by the device.

{
    "orientations": [{
        "media": "max-width: 320px",
        "supported": ["portrait-primary", "landscape"]
    }, {
        "media": "max-width: 720px",
        "supported": ["landscape"]
    }]
}

In this example:

  • a device with a screen width of 320px or below would launch either "portrait-primary" or "landscape" with the abilty to be "flipped" depending on how the user is holding the device (and OS permitting).
  • A device with a screen width of 321px through 720px would be launched in landscape (leaving it up to the UA to pick either landscape-primary or landscape-secondary, while allowing "flippability"),
  • A device with a screen width of 721px and above would start in any orientation chosen by the UA (ideally, one that matches how the user is holding the device).

Option 2: The second proposal is to remove orientation from the manifest and use CSS @viewport instead [css-device-adapt]. This would mean::

<head>
<style>
  /*set it by default to portrait primary for small screens */
  @media (max-width: 320px) {
      @viewport {
          orientation: portrait-primary, landscape;
      }
  }
  
  /*Tablet, switch to landscape only*/
  @media (max-width: 720px) {
      @viewport {
          orientation: landscape;
      }
  }
  
  /* 
    similarly on screens with a width of 721px or more, 
    all orientations are allowed 
   */
</style>
</head>

Problem with using @viewport at the moment is that the specification is progressing a bit slowly and no one has implemented the "orientation" descriptor. It also lacks definitions for "-primary" and "-secondary" contraints, which are important for various applications, and doesn't currently allow providing multiple allowed orientations - hopefully the CSS Device Adaption spec can align with the Screen Orientation spec.

3.6 mode member

The mode member represents that mode of operation in which the web application will be launched. When the developer omits the value, the user agent assumes the value "bookmark".

The mode of operation in which a web application can be launched include:

standalone
Once launched, the Web application appears indistinguishable from a native application by allowing the OS to treat it as equivalent to a native application.
bookmark
When launched, the user agent open the URL is normal (e.g., opens a new tab, or a new window, or whatever it commonly does when instructed to open a bookmark).

Standalone mode can also be displayed in the following view modes:

A valid application mode is one that conforms to the following [ABNF]:

  mode = "bookmark" / "standalone" ["-" presentation]
  presentation = "fullscreen"

The steps for processing the mode member of an icon are given by the following algorithm. The algorithm returns a string.

  1. Let value be the result of calling the [[GetOwnProperty]] internal method of manifest passing "mode" as the argument.
  2. Let result be "bookmark".
  3. Strip leading and trailing whitespace from value.
  4. If value is a valid application mode, set result to value.
  5. Return result.

3.7 Processing the manifest

The steps for fetching a manifest are given by the following algorithm. It takes a url URL as an argument. It returns either a response (which may be in error).

  1. Let response be the result of fetching the manifest from url.
  2. Return response.

The steps to processing a manifest are given by the following algorithm. The algorithm takes a text string as an argument.

  1. Let manifest be the result of invoking the parse function of the JSON object defined in [ECMASCRIPT] with text as its only argument. If parsing throws an error, return the error and terminate this algorithm.
  2. Let name be the result of running the steps for processing the name member. If the returned value is undefined or an error:
    1. Set name to be an implementation specific string that can serve as a suitable name for the web application. For example, if the manifest was obtained from a link element, and the document has a meta element whose name attribute matches "application-name", then the user agent could use the value of that meta element's content attribute as a fallback. Otherwise, then the document's title can be used. Alternatively, the user could be prompted to provide a custom name using as a place holder.
  3. Let mode be the result of running the steps for processing the mode member. If processing returns an error, report the error, and set mode to "bookmark".
  4. Let orientation be the result of running the steps for processing the orientation member.
  5. Let url be the result of running the steps for processing the url member.
  6. Let icons be the result of running the steps for processing the icons member.
  7. Optionally, ignore all other members.
  8. Return response.

3.8 Linking to a manifest

The manifest keyword can be used with a [HTML] link element. This keyword creates an external resource link.

Link type Effect on... Brief description
link a and area
manifest External Resource not allowed Imports or links to a manifest.

The default media type for resources associated with the manifest link type is application/manifest+json.

In cases where more than one link element with a manifest link type appears in a document, the user agent MUST use the first inserted link element and ignore all subsequent link elements with a manifest link type (even if the first element was in error).

The appropriate time to fetch the manifest is when the external resource link is created or when its element is inserted into a document, whichever happens last. However, a user agent MAY opt to delay fetching a manifest until after the document and its other resources have loaded (i.e., to not delay the availability of content and scripts required by the document).

Certain error conditions can result in a manifest being treated as an invalid manifest. An invalid manifest is one that is deemed to be non-conforming in such a way that it would not be possible for the user agent to continue processing (e.g., it can't be parsed by the JSON parser because of a syntax error, it could be fetched from the network). In such a case, issue a developer warning. In either case, when a step results in an invalid manifest the user agent MUST abort whatever step or sub-step caused the condition.

To fetch a manifest, as user agent MUST:

  1. If the link element lacks a href attribute, abort this algorithm.
  2. Run the steps for fetching a manifest, with the value of href attribute as the url, and let response be the response.
  3. If response's type is "error", treat this as an invalid manifest.
  4. Otherwise, let manifest be the result of running the steps for processing a manifest.
  5. If manifest results in an error, treat this as an invalid manifest.
  6. Otherwise, in a user agent specific manner, and when the end-user so desires, provide a means for the end-user to view the relevant contents of the manifest; and provide a means for the end-user to create a bookmark based on that information.

3.9 Proprietary extensions to the manifest

This section is non-normative.

Although proprietary extensions are undesirable, they can't realistically be avoided. As such, the RECOMMENDED way to add proprietary extension is to use a vendor prefix.

This following is an example of two hypothetical vendor extensions.

Example 5: vendor extensions
{
  ...
  "webkit-fancyfeature": "some/url/img",
  "moz-awesome-thing": { ... }
  ...
}

4. Launching a standalone web application

When an application is launched:

  1. If the web application has a required orientation, run the steps for selecting the orientation.

5. Icon object and its members

Each icon object represents an icon for an application suitable to use at some dimensions and screen density.

5.1 density member

The density member of an icon is the device pixel density for which this icon was designed. The device pixel density is expressed as the number of dots per 'px' unit (equivalent to a dppx as defined in [css3-values]). The value is a positive number greater than 0. If the developer ommits the value, the user agent assumes the value 1.

The steps for processing a density of an icon are given by the following algorithm. The algorithm thanks an icon object as an argument and returns a positive number.

  1. Let value be the result of calling the [[GetOwnProperty]] internal method of icon passing "density" as the argument.
  2. Let result be the result of parseFloat(value);
  3. If result is NaN, +0, −0, +∞, or −∞, or less than 0, return 1.
  4. Return result.

5.2 width and height members

The width and height members represent the natural width of the icon in pixels. Their corresponding value is a positive number greater than 0.

The steps for processing a dimension of an icon are given by the following algorithm. The algorithm takes an icon and a key ('width" or "height") as an argument. The algorithm returns a positive number, undefined, or an error.

  1. If HasOwnProperty(icon, key) returns false, then return undefined.
  2. Let value be the result of calling the [[GetOwnProperty]] internal method of icon passing key as the argument.
  3. Let result be the result of parseFloat(value);
  4. If result is NaN, +0, −0, +∞, or −∞, or less than 0, return undefined.
  5. Return result.

5.3 src member

The src member of an icon is a URL from which the icon can be fetched.

The steps for processing the src member of an icon are given by the following algorithm. The algorithm takes a icon object as an argument and returns a URL or undefined.

  1. If HasOwnProperty(icon, "src") returns false, then return undefined.
  2. Let value be the result of calling the [[GetOwnProperty]] internal method of icon passing "src" as the argument.
  3. Let manifest URL be the URL from which the manifest was fetched from.
  4. Parse value, using manifest URL as the base URL, and let result be the result.
  5. return result.

5.4 type member

The type member of an icon is a hint as to the media type of the icon. The purpose of this member is to allow a user agent can ignore icons of media types it does not support.

The steps for processing the type member of an icon are given by the following algorithm. The algorithm takes an icon object as an argument, and returns either string or undefined.

  1. If HasOwnProperty(manifest,"type") returns false, then return undefined.
  2. Let value be the result of calling the [[GetOwnProperty]] internal method of potential icon passing "type" as the argument.
  3. If type(potential src) is not "string", return an error.
  4. Strip leading and trailing whitespace from result.
  5. return result.

6. Extensions to the Navigator object

partial interface Navigator {
    readonly    attribute Boolean standalone;
    Promise requestBookmark (optional DOMString url);
};

6.1 Attributes

standalone of type Boolean, readonly
The standalone attribute provides a means for a developer to check if the application is running in standalone mode. When getting, the user agent MUST returns true if the application is running as standalone. Return false otherwise.

6.2 Methods

requestBookmark
When invoked, the user agent MUST run the steps to request to add bookmark.
Parameter Type Nullable Optional Description
url DOMString
Return type: Promise

The steps to request to add bookmark are given by the following algorithm. The algorithm runs asynchronously and returns a Promise.

  1. Let promise be a new Promise object and resolver its associated resolver.
  2. Return promise and run the remaining steps asynchronously.
  3. If this method was not invoked as a result of explicit user action, then:
    1. Let error be a new DOMException whose name is "SecurityError".
    2. Run resolver's internal reject algorithm with error as value and terminate this algorithm.
  4. If the document's mode of operation is "standalone":
    1. Let error be a new DOMException whose name is "NotSupported".
    2. Run resolver's internal reject algorithm with error as value and terminate this algorithm.
  5. Run the steps for fetching a manifest. If the response's type is "error":
    1. Let exception name be "NetworkError".
    2. If the response's termination reason is end user abort, set exception name to "AbortError".
    3. If the response's termination reason is timeout, set exception name to "TimeoutError".
    4. Let error be a new DOMException whose name is exception name.
    5. Run resolver's internal reject algorithm with error as value and terminate this algorithm.
  6. Let boomark info be result of the steps for processing a manifest, with response's body as the argument.
  7. If boomark info is an error:
    1. Run resolver's internal reject algorithm with error as value and terminate this algorithm.
  8. Present bookmark info to the end user. If the end-user rejects the request to add the bookmark:
    1. Let error be a new DOMException whose name is "AbortError".
    2. Run resolver's internal reject algorithm with error as value and terminate this algorithm.
  9. Run resolver's internal fulfill algorithm with undefined as value.

7. Media type reregistration

This section contains the required text for MIME media type registration with IANA.

The media type for a manifests is application/manifest+json.

If the protocol over which the manifest is transferred supports the [MIME-TYPES] specification (e.g. HTTP), it is RECOMMENDED that the manifest be labeled with the media type for a manifests.

Type name:
application
Subtype name:
manifest+json
Required parameters:
N/A
Optional parameters:
N/A
Encoding considerations:
Same as for application/json
Security considerations:

As the manifest format is JSON and will commonly be encoded using [UNICODE], the security considerations described in [JSON] and [UNICODE-SECURITY] apply. In addition, implementors need to impose their own implementation-specific limits on the values of otherwise unconstrained member types, e.g. to prevent denial of service attacks, to guard against running out of memory, or to work around platform-specific limitations.

Web applications will generally contain ECMAScript, HTML, CSS files, and other media, which are executed in a sand-boxed environment. As such, implementors need to be aware of the security implications for the types they support. Specifically, implementors need to consider the security implications outlined in the [CSS-MIME] specification, the [ECMAScript-MIME] specification, and the [HTML] specification.

As web applications can contain content that is able to simultaneously interact with the local device and a remote host, implementors need to consider the privacy implications resulting from exposing private information to a remote host. Mitigation and in-depth defensive measures are an implementation responsibility and not prescribed by this specification. However, in designing these measures, implementors are advised to enable user awareness of information sharing, and to provide easy access to interfaces that enable revocation of permissions.

As this specification allows for the declaration of URLs within certain members of a manifest, implementors need to consider the security considerations discussed in the [URL] specification. Implementations intending to display IRIs and IDNA addresses found in the manifest are strongly encouraged to follow the security advice given in [UNICODE-SECURITY].

Applications that use this media type:
Web browsers
Additional information:
Magic number(s):
N/A
File extension(s):
.json, .manifest
Macintosh file type code(s):
TEXT
Person & email address to contact for further information:
The Web Applications (WebApps) Working Group can be contacted at public-webapps@w3.org.
Intended usage:
COMMON
Restrictions on usage:
none
Author:
W3C's Web Applications (WebApps) Working Group.
Change controller:
W3C.

8. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this specification are to be interpreted as described in [RFC2119].

There is only one class of product that can claim conformance to this specification: a user agent.

A. Acknowledgments

This document reuses text from the WHATWG [HTML] specification as permitted by the license of that specification. The [HTML] specification is edited by Ian Hickson.

B. References

B.1 Normative references

[ABNF]
D. Crocker; P. Overell. Augmented BNF for Syntax Specifications: ABNF. January 2008. STD. URL: http://www.ietf.org/rfc/rfc5234.txt
[CSS-MIME]
H. Lie; B. Bos; C. Lilley. The text/css Media Type. 1 March 1998. Informational. URL: http://www.ietf.org/rfc/rfc2318.txt
[ECMASCRIPT]
ECMA-262 ECMAScript Language Specification, Edition 6. Draft. URL: http://people.mozilla.org/~jorendorff/es6-draft.html
[ECMAScript-MIME]
B. Hoehrmann. Scripting Media Types. 4 January 2006. Informational. URL: http://tools.ietf.org/html/rfc4329
[FETCH]
Anne van Kesteren. Fetch. Living Standard. URL: http://fetch.spec.whatwg.org/
[HTML]
Ian Hickson. HTML. Living Standard. URL: http://www.whatwg.org/specs/web-apps/current-work/
[JSON]
D. Crockford. The application/json Media Type for JavaScript Object Notation (JSON) (RFC 4627). July 2006. RFC. URL: http://www.ietf.org/rfc/rfc4627.txt
[MIME-TYPES]
N. Freed; N. Borenstein. Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types (RFC 2046). November 1996. RFC. URL: http://www.ietf.org/rfc/rfc2046.txt
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Internet RFC 2119. URL: http://www.ietf.org/rfc/rfc2119.txt
[UNICODE]
The Unicode Standard. URL: http://www.unicode.org/versions/latest/
[UNICODE-SECURITY]
Mark Davis; Michel Suignard. Unicode Security Considerations. URL: http://www.unicode.org/reports/tr36/
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: http://url.spec.whatwg.org/
[css3-values]
Håkon Wium Lie; Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 30 July 2013. W3C Candidate Recommendation. URL: http://www.w3.org/TR/css3-values/

B.2 Informative references

[css-device-adapt]
Rune Lillesveen. CSS Device Adaptation. 15 September 2011. W3C Working Draft. URL: http://www.w3.org/TR/css-device-adapt/