mozilla

Revision 457913 of Introduction to Open Web Apps

  • Revision slug: Web/Apps/Introduction_to_open_web_apps
  • Revision title: Introduction to Open Web Apps
  • Revision id: 457913
  • Created:
  • Creator: markg
  • Is current revision? No
  • Comment

Revision Content

Open Web Apps are essentially no different than standard websites or Web pages. They are built using standard open Web technologies — HTML, CSS, JavaScript, etc. — and can be accessed using a Web browser. The main differences lie in their ability to be installed on a device and work offline, and access to advanced APIs that allow interaction with device features such as the camera, address book, and other such things. In addition, they are built on open technologies as much as is possible. Where differences lie in technology implementation between platforms, efforts should be made to ensure that both are supported, through a combination of feature detection and appropriate code for different platforms, and graceful degradation.

This article is designed to act as a good starting point for anyone wishing to learn more about Open Web Apps, whether you are a developer or project manager, or have another role relevant to app development or delivery. Here we'll provide you with a light, high level overview of Open Web Apps and the disciplines involved in their creation, from planning right through to publishing. Subsequent articles will go into each discipline in much more detail, providing you with all the resources you need to build and distribute great Open Web Apps.

Advantages of Open Web Apps

Let's look at the advantages of Open Web Apps in a little more detail:

  • Local installation and offline storage: Open Web Apps can be installed on the device, and leverage APIs such as local storage and IndexedDB to provide local data storage capabilities. In addition, open Web technologies tend to have a much smaller footprint than native apps and can generally be updated atomically rather than having to install a complete new package each time there's an update. (an exception to this is packages apps, which require a whole new package when updating.) Apps are therefore less dependent on an always-on Web connection, and more useful when networks are patchy.
  • Hardware access: The metadata provided with Open Web Apps can be used to grant the application permission to privileged APIs that enable usage of device hardware features, something the Web platform has not traditionally enjoyed.
  • Breaking the walled gardens: The norm for mobile platforms tends to be be walled gardens written with proprietary technologies, so apps are locked inside their platforms. And smartphones tend to be expensive, and require credit cards for app purchases. Open Web Apps tend to be able to run on much cheaper hardware, especially in the case of Firefox OS devices where you've literally just got Firefox running on top of a lightweight Linux kernel. And they are written using open Web technologies, which is the most distributed platform around. In addition, Firefox OS devices feature payment systems where you can simply prepay for apps, or add the cost to your phone bill.
  • Open Web App stores: Following on from the previous point, you can choose to host your apps in an existing marketplace (such as the Firefox Marketplace), or host them somewhere else entirely. It's up to you. Mozilla aims to put the developer back in control of every aspect of the app experience — from easy development to distribution to direct customer relationship management. And the apps can be searched for just like any other Web-based experience.

The following video also looks at general advantages of open web apps, and developing for the Firefox OS platform:

Platforms supporting Open Web Apps

Firefox OS is Mozilla's exciting new Open Web App platform, which aims to deliver a smartphone experience to low cost handsets, and show how a mobile platform can be done in openness. But it doesn't stop there. Mozilla is offering Open Web App features like privileged APIs and manifests for standardization, and planning to roll out support for installing Open Web Apps on other platforms, like Firefox for desktop, Firefox for Android, and even other browsers.

Imagine a single app runtime that will work seamlessly across multiple platforms.

A simple example app

We have written a number of example apps to help demonstrate all the different concepts we are teaching in this series of articles; you can download them from Github, and install them (for example, on Firefox OS) from the Firefox Marketplace. The particular app we'll focus on in this article is called Location Finder — it is a very simple app that uses the Geolocation API to return the location of the device accessing the app, and then plots those coordinates on a Google Map. You can also see it running live.

Location finder is the sample app I am using to demonstrate various concepts in the Introduction to web apps article.

Most of the implementation details are not important, but we will be discussing fundamental points of interest in the sections that follow.

Planning and design

As with any Web site or page, you should think carefully about the functionality and information your project will offer to its users, and its user experience. These topics are covered in a lot more detail in our Planning your app and App layout article series.

Think responsive

One major consideration that will come into every step of the design and development process is responsive design — how will your app look and behave on different platforms? You should aim to optimize the layout and design for larger screens like desktops, medium screens like tablets, and small screens like mobile devices. But screen size is not the only consideration:

  • You may be tasked with providing an optimized layout for devices in portrait and landscape mode.
  • Some devices have higher resolution displays than others, which brings a whole host of issues. How do you ensure that images can look sharp and crisp on higher resolution screens, without file sizes becoming unacceptably high?
  • Entering data is a much more painful experience for users on mobile phones than it is for desktop users. For an acceptable experience you will likely have to provide radically different input mechanisms, for example letting users choose from preset options or popular choices wherever possible, and avoiding text entry when you can.
  • Mobile devices not only have less screen space available than their desktop counterparts, but in general they also have less processing power available, and slower network speeds. The key mantra here is simplify, reduce, optimize. This is especially important on platforms such as Firefox OS, designed to have a small footprint and operate effectively on low cost devices.

As an example, think about how differently a site like Facebook behaves on desktop versus mobile. Such a complex desktop site would not work at all on mobile, so the way the information and functionality is presented to a user has to be rethought.

Image of the Facebook desktop site.                     Image of the Facebook Mobile site, which has much simpler presentation than the desktop version.

In the case of Location Finder, the app is very simple, so it was not difficult to think of a responsive layout that would work on multiple devices. First of all, I used the following CSS to ensure that the title bar (<h1>) would remain a constant height, while the map would fill up the rest of the space available:

html {
  width: 100%;
  height: 100%;
}

body {
  width: 100%;
  height: inherit;
  overflow: hidden;
}

#map_canvas {
  width: 100%;
  height: 95%;
}

h1 {
  line-height: 4.8rem;
  min-height: 5rem;
  height: auto;
  margin: 0;
}

I then made sure that the install button keeps over to the right of the title bar using absolute positioning, and then employed a simple media query to reduce the font size of the <h1> and the button, so they don't overlap one another at narrow screen widths (this looks fine on a Firefox OS Keon phone in portrait mode, which is 320px across.)

@media (max-width: 380px) {
  h1 {
    font-size: 2rem;
  }
 
  #install {
    font-size: 1.2rem;
  }
}

Planning what your app should do, and how

Once you have an idea for a Web app, you should write down the app's intended functionality and target audience as concisely as possible. If you can summarise it one sentence, then your idea is probably a good fit for an app. You should make the app as simple as possible - focus on getting it to do one thing — or a few closely related things — well. If you have loads of different use cases you want to achieve, you might want to split them across different apps.

Once this is decided on, it is always a good idea to start with paper sketches — try drawing out different screens to show what the app will look like, and what the workflow will be as the user uses your app. You'll probably want to do a separate set of sketches for desktop and mobile. Depending on what you want your app to do, the workflow might be quite different on mobile and desktop.

Consistent design according to device guidelines

One challenge of a multi-platform development environment is that you have somewhat of a contradiction with regards to the visual design and UX. On the one hand, you want to have an app with its own individual personality; on the other hand you want your app to fit in with the look and feel of the device. There are a couple of different approaches to this problem (which are discussed in more detail in our Graphics and UX articles) — you could design something fairly neutral that will work okay across most places, or you could serve different stylesheets depending on which device the app is installed or viewed on.

To make things easier for Firefox OS for example, we have written up comprehensive design guidelines for styling Firefox OS apps, including example assets, behaviours and transitions, and design pattern information. For the Location Finder app, I just took the standard gradient slices and CSS from the guidelines and plugged them into my app, to create something consistent.

You also need to create an icon, or series of icons to use with your app. Indeed, this is a familiar practice with Web and app developers, and you will often end up with a favicon, a few sizes of icons for different platform homescreens, a larger, more detailed application icon to show in marketing material, etc. We have written a Firefox OS icon design guide to give you more information for this particular case.

Creating a new app, or porting an old site/page/app?

If you want to make an existing web site into an installable app, essentially you just need to add a manifest file to provide metadata about the app (such as language and permissions settings) and an install mechanism (the Firefox OS Install API handles this, for example) to allow app installation.

However, the likelihood is that you'll want to do more than this, to optimise your app's layout, design and functionality for the different target devices it will be installed upon. If the existing site is a monolithic legacy app, then you may even decide that the best course of action is to create a completely separate app for small screens. Retrofitting responsive design for such sites often works out a lot more expensive than just starting afresh.

Paid apps and in-app payments

You should decide if you want to make money with your app. You have the options of selling the app on a marketplace (a paid app) or implementing in-app payments. See the App payments guide for more information.

Implementing app functionality

There are many different types of functionality you might want to implement in your app, and to make things easier we have arranged our tutorials according to task areas. If you want to search by API or other technology feature, the best way is to use our search box, or go to the relevant section of the site, for example APIs or CSS.

There are two types of installable app available, hosted apps, which can be distributed anywhere the same as normal websites, and packaged apps, which are archived in a .zip file and hosted in an app store, where they tend to be subjected to a rigorous testing and verification process before publication (the Firefox Marketplace, for example). For a discussion of the differences between the two, read Packaged apps.

Note that if you don't wish to make your app an installable app, and just want to run it as a regular web page, you don't need to take these steps.

Manifest

You need to add a manifest file to your app (a JSON file, often called manifest.webapp, and located in the root of your app directory), which defines a number of different items of metadata including language, name and description, icon information, permissions for using restricted APIs, and more. Let's look at the manifest file for our sample Location Finder app:

{
  "name": "Location",
  "description": "Location finder uses geolocation to find out where you are, and plots a map of your surroundings using the Google Maps API.",
  "launch_path": "/~cmills/location-finder/",
  "icons": {
    "128": "/~cmills/location-finder/img/icon-128.png"
  },
  "developer": {
    "name": "Chris Mills",
    "url": "http://www.conquestofsteel.co.uk"
  },
  "default_locale": "en"
}

There are many options you can specify inside a manifest file, and we cover these all in detail in our dedicated App manifest article; let's just briefly cover the options contained in the above minimal example:

  • "name": "Location" — this specifies the name of your app, which is how it will appear both in the marketplace and on your device's home screen below the app icon when installed. It is a good idea to make this as short and snappy as possible.
  • "description": "Location finder uses..." — contains a description of your app's functionality, to be displayed in the app's Marketplace description. Make it as short as possible and try to make your app sound exciting, so it will encourage users to try it out.
  • "launch_path": "/~cmills/location-finder/" — contains the path to the root directory of your app on your Web server. This should be a relative path traveling from the root URL of your server. So the absolute URL to my sample app is http://people.mozilla.com/~cmills/location-finder/. The root URL is http://people.mozilla.com, and the relative path I need is therefore /~cmills/location-finder/.
  • "icons": { — contains a list of the different icons available in the app.
    • "128": "/~cmills/location-finder/img/icon-128.png" — specifies that you have a 128px square icon available in the application, and provides a relative path to the icon file. Like the launch path, this must be a relative path travelling from the root path of the server. App icons should be in PNG format, and while you can include as many as you like, you need to include at least a 128px icon.
  • "developer": { — contains information about the developer of the app.
    • "name": "Chris Mills", — the developer name, listed on the marketplace page.
    • "url": "http://www.conquestofsteel.co.uk" — the developer's website, listed on the marketplace page. Ideally this should link to a site where more information or support  for the app can be found.
  • "default_locale": "en" — specifies the default language your app uses.

My Location Finder app's root directory also has an .htaccess file in it, which contains the following line:

AddType application/x-web-app-manifest+json .webapp

Manifest files need to be served with a mimetype of application/x-web-app-manifest+json.

Install API functionality

In our sample Location Finder app, I've implemented an install button that you can click when viewing the Web page, to install that site on Firefox OS as an app. The button markup is nothing special:

<button id="install">
  Install on FirefoxOS
</button>

This button's functionality is implemented using the Install API (see install.js):

function install(ev) {
  ev.preventDefault();
  // define the manifest URL
  var manifest_url = "http://people.mozilla.com/~cmills/location-finder/manifest.webapp";
  // install the app
  var installLocFind = navigator.mozApps.install(manifest_url);
  installLocFind.onsuccess = function(data) {
    // App is installed, do something
  };
  installLocFind.onerror = function() {
    // App wasn't installed, info is in
    // installapp.error.name
    alert(installapp.error.name);
  };
};

// get a reference to the button and call install() on click
var button = document.getElementById('install');

var installCheck = navigator.mozApps.checkInstalled("http://people.mozilla.com/~cmills/location-finder/manifest.webapp");
// check whether the app defined in the above manifest file is installed
installCheck.onsuccess = function() {
  if(installCheck.result) {
    button.style.display = "none";
    // if it's already installed on the device, hide the install button, as we don't need it.
  } else {
    button.addEventListener('click', install, false);
    // if it isn't, run the install code contained in the install() function
  };
};

Let's run through briefly what is going on:

  1. We get a reference to the install button and store it in the variable button.
  2. We use navigator.mozApps.checkInstalled to check whether the app defined by the manifest at http://people.mozilla.com/~cmills/location-finder/manifest.webapp is already installed on the device. This test is stored in the variable installCheck.
  3. When the test is successfully carried out, its success event is fired, therefore installCheck.onsuccess = function() { ... } is run.
  4. We then test for the existance of installCheck.result using an if statement. If it does exist, meaning that the app is installed, we hide the button. An install button isn't needed if it is already installed.
  5. If the app isn't installed, we add a click event listener to the button, so the install() function is run when the button is clicked.
  6. When the button is clicked and the install() function is run, we store the manifest file location in a variable called manifest_url, and then install the app using navigator.mozApps.install(manifest_url), storing a reference to that installation in the installLocFind variable. You'll notice that this installation also fires success and error events, so you can run actions dependant on whether the install happened successfully or not.

You may want to verify the implementation state of the API when first coming to Installable web apps.

Web app functionality categories

There are a great number of different things you might want your Open Web App to do, but largely they are going to fall into some common task categories, which we will deal with in turn. In this content zone we are going to look at applied uses of technologies as related to Open Web Apps and their specific issues and use cases. If you want to search for more generic information on a specific CSS property or API, such as a basic implementation guide or reference page, then you are advised to do a search using our search bar, or browse the relevant section of the site (Web API, CSS, etc.).

The task categories are:

  • Gathering information
  • Controlling device display
  • Data storage and offline usage
  • Controlling media
  • Services for users
  • Utility APIs

You can explore these more deeply starting at our Developing Web Apps page.

App permissions

You should note that some of the advanced APIs you can utilise in Open Web Apps (for example Contacts API, Camera API, Device Storage API) that allow access to device features or hardware are restricted for security purposes, meaning that they require access permissions to be set in the manifest file, and distribution through the Firefox Marketplace (or another trusted app store). The three levels of permission are as follows:

  • Normal — APIs that don't need any kind of special access permissions.
  • Privileged — APIs available to developers to use in their applications, as long as they set access permissions in the app manifest files, and distribute them through a trusted source.
  • Certified — APIs that control critical functions on a device, such as the call dialer and messaging services. These are generally not available for third party developers to use.

For more information on app permission levels, read Types of packaged apps.

Testing your apps

You should really do multiple test runs on your apps at different stages of development, so you can keep a check on whether you are going in the right direction, and find major bugs as soon as possible. To help you out, we have written a guide to testing on a wide variety of devices, which provides many hints and tips, as well as a usage guide for the different testing tools available, including the Firefox OS simulator. You should always try to test on real devices where possible, though.

Publishing your apps

So you've got your app created, and you want to share it with the world? Great! There are a couple of options for you, which give you the freedom to do what you want with your creation. First, you can just host the app as a standard website/page, on any online location of your choosing. To make it installable, you just need to provide a manifest file to describe and define your app, and an install mechanism, as we discussed above. Second, you can package your app in a zip file, and either host the packaged app yourself, or publish it an app store (such as the Firefox Marketplace). The Firefox Marketplace will provide an installation button if you are hosting your app's manifest file there. We have written a detailed guide to Publishing your apps, which guides you through creating packaged apps, as well as providing publication FAQs and checklists, information on using the Firefox Marketplace API, and ideas on promotion and monetization.

It's important to note that each app should be hosted from its own domain. Different apps should not share the same domain. An acceptable solution is to host each app from a different subdomain, for example. See FAQs about apps manifests for more information on origins.

The video below provides a useful overview of the advantages of open marketplaces and an open web approach to app discovery:

Revision Source

<p>Open Web Apps are essentially no different than standard websites or Web pages. They are built using standard open Web technologies — HTML, CSS, JavaScript, etc. — and can be accessed using a Web browser. The main differences lie in their ability to be installed on a device and work offline, and access to advanced APIs that allow interaction with device features such as the camera, address book, and other such things. In addition, they are built on open technologies as much as is possible. Where differences lie in technology implementation between platforms, efforts should be made to ensure that both are supported, through a combination of feature detection and appropriate code for different platforms, and graceful degradation.</p>
<p>This article is designed to act as a good starting point for anyone wishing to learn more about Open Web Apps, whether you are a developer or project manager, or have another role relevant to app development or delivery. Here we'll provide you with a light, high level overview of Open Web Apps and the disciplines involved in their creation, from planning right through to publishing. Subsequent articles will go into each discipline in much more detail, providing you with all the resources you need to build and distribute great Open Web Apps.</p>
<h2 id="Advantages_of_Open_Web_Apps">Advantages of Open Web Apps</h2>
<p>Let's look at the advantages of Open Web Apps in a little more detail:</p>
<ul>
  <li><strong>Local installation and offline storage</strong>: Open Web Apps can be installed on the device, and leverage APIs such as <a href="/en-US/docs/Web/Guide/DOM/Storage" title="/en-US/docs/Web/Guide/DOM/Storage">local storage</a> and <a href="/en-US/docs/IndexedDB" title="/en-US/docs/IndexedDB">IndexedDB</a> to provide local data storage capabilities. In addition, open Web technologies tend to have a much smaller footprint than native apps and can generally be updated atomically rather than having to install a complete new package each time there's an update. (an exception to this is packages apps, which require a whole new package when updating.) Apps are therefore less dependent on an always-on Web connection, and more useful when networks are patchy.</li>
  <li><strong>Hardware access</strong>: The metadata provided with Open Web Apps can be used to grant the application permission to privileged APIs that enable usage of device hardware features, something the Web platform has not traditionally enjoyed.</li>
  <li><strong>Breaking the walled gardens</strong>: The norm for mobile platforms tends to be be walled gardens written with proprietary technologies, so apps are locked inside their platforms. And smartphones tend to be expensive, and require credit cards for app purchases. Open Web Apps tend to be able to run on much cheaper hardware, especially in the case of Firefox OS devices where you've literally just got Firefox running on top of a lightweight Linux kernel. And they are written using open Web technologies, which is the most distributed platform around. In addition, Firefox OS devices feature payment systems where you can simply prepay for apps, or add the cost to your phone bill.</li>
  <li><strong>Open Web App stores</strong>: Following on from the previous point, you can choose to host your apps in an existing marketplace (such as the <a href="https://marketplace.firefox.com/" title="https://marketplace.firefox.com/">Firefox Marketplace</a>), or host them somewhere else entirely. It's up to you. Mozilla aims to put the developer back in control of every aspect of the app experience — from easy development to distribution to direct customer relationship management. And the apps can be searched for just like any other Web-based experience.</li>
</ul>
<p>The following video also looks at general advantages of open web apps, and developing for the Firefox OS platform:</p>
<p style="text-align: center;"><iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/RJJkFshnnVc/?feature=player_detailpage" width="640"></iframe></p>
<h2 id="Platforms_supporting_Open_Web_Apps">Platforms supporting Open Web Apps</h2>
<p><a href="/en-US/docs/Mozilla/Firefox_OS">Firefox OS</a> is Mozilla's exciting new Open Web App platform, which aims to deliver a smartphone experience to low cost handsets, and show how a mobile platform can be done in openness. But it doesn't stop there. Mozilla is offering Open Web App features like privileged APIs and manifests for standardization, and planning to roll out support for installing Open Web Apps on other platforms, like Firefox for desktop, Firefox for Android, and even other browsers.</p>
<p>Imagine a single app runtime that will work seamlessly across multiple platforms.</p>
<h2 id="A_simple_example_app">A simple example app</h2>
<p>We have written a number of example apps to help demonstrate all the different concepts we are teaching in this series of articles; you can download them from Github, and install them (for example, on Firefox OS) from the <a href="https://marketplace.firefox.com/" title="https://marketplace.firefox.com/">Firefox Marketplace</a>. The particular app we'll focus on in this article is called <a href="https://github.com/chrisdavidmills/location-finder" title="https://github.com/chrisdavidmills/location-finder">Location Finder</a> — it is a very simple app that uses the <a href="/en-US/docs/WebAPI/Using_geolocation" title="/en-US/docs/WebAPI/Using_geolocation">Geolocation API</a> to return the location of the device accessing the app, and then plots those coordinates on a Google Map. You can also <a href="http://people.mozilla.com/~cmills/location-finder/" title="http://people.mozilla.com/~cmills/location-finder/">see it running live</a>.</p>
<p><img alt="Location finder is the sample app I am using to demonstrate various concepts in the Introduction to web apps article." src="https://mdn.mozillademos.org/files/5653/sample-app.png" style="margin: 0px auto; width: 310px; height: 401px; display: block;" /></p>
<p>Most of the implementation details are not important, but we will be discussing fundamental points of interest in the sections that follow.</p>
<h2 id="Planning_and_design">Planning and design</h2>
<p>As with any Web site or page, you should think carefully about the functionality and information your project will offer to its users, and its user experience. These topics are covered in a lot more detail in our <a href="#">Planning your app</a> and <a href="#">App layout</a> article series.</p>
<h3 id="Think_responsive">Think responsive</h3>
<p>One major consideration that will come into every step of the design and development process is responsive design — how will your app look and behave on different platforms? You should aim to optimize the layout and design for larger screens like desktops, medium screens like tablets, and small screens like mobile devices. But screen size is not the only consideration:</p>
<ul>
  <li>You may be tasked with providing an optimized layout for devices in portrait and landscape mode.</li>
  <li>Some devices have higher resolution displays than others, which brings a whole host of issues. How do you ensure that images can look sharp and crisp on higher resolution screens, without file sizes becoming unacceptably high?</li>
  <li>Entering data is a much more painful experience for users on mobile phones than it is for desktop users. For an acceptable experience you will likely have to provide radically different input mechanisms, for example letting users choose from preset options or popular choices wherever possible, and avoiding text entry when you can.</li>
  <li>Mobile devices not only have less screen space available than their desktop counterparts, but in general they also have less processing power available, and slower network speeds. The key mantra here is simplify, reduce, optimize. This is especially important on platforms such as Firefox OS, designed to have a small footprint and operate effectively on low cost devices.</li>
</ul>
<p>As an example, think about how differently a site like Facebook behaves on desktop versus mobile. Such a complex desktop site would not work at all on mobile, so the way the information and functionality is presented to a user has to be rethought.</p>
<p><img alt="Image of the Facebook desktop site." src="https://mdn.mozillademos.org/files/5655/facebook-desktop.png" style="width: 600px; height: 361px;" /> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <img alt="Image of the Facebook Mobile site, which has much simpler presentation than the desktop version." src="https://mdn.mozillademos.org/files/5657/facebook-mobile.png" style="width: 203px; height: 361px;" /></p>
<p>In the case of Location Finder, the app is very simple, so it was not difficult to think of a responsive layout that would work on multiple devices. First of all, I used the following CSS to ensure that the title bar (<code>&lt;h1&gt;</code>) would remain a constant height, while the map would fill up the rest of the space available:</p>
<pre class="brush: css">
html {
  width: 100%;
  height: 100%;
}

body {
  width: 100%;
  height: inherit;
  overflow: hidden;
}

#map_canvas {
  width: 100%;
  height: 95%;
}

h1 {
  line-height: 4.8rem;
  min-height: 5rem;
  height: auto;
  margin: 0;
}</pre>
<p>I then made sure that the install button keeps over to the right of the title bar using absolute positioning, and then employed a simple media query to reduce the font size of the <code>&lt;h1&gt;</code> and the button, so they don't overlap one another at narrow screen widths (this looks fine on a Firefox OS Keon phone in portrait mode, which is 320px across.)</p>
<pre class="brush: css">
@media (max-width: 380px) {
  h1 {
    font-size: 2rem;
  }
 
  #install {
    font-size: 1.2rem;
  }
}</pre>
<h3 id="Planning_what_your_app_should_do.2C_and_how">Planning what your app should do, and how</h3>
<p>Once you have an idea for a Web app, you should write down the app's intended functionality and target audience as concisely as possible. If you can summarise it one sentence, then your idea is probably a good fit for an app. You should make the app as simple as possible - focus on getting it to do one thing — or a few closely related things — well. If you have loads of different use cases you want to achieve, you might want to split them across different apps.</p>
<p>Once this is decided on, it is always a good idea to start with paper sketches — try drawing out different screens to show what the app will look like, and what the workflow will be as the user uses your app. You'll probably want to do a separate set of sketches for desktop and mobile. Depending on what you want your app to do, the workflow might be quite different on mobile and desktop.</p>
<h3 id="Consistent_design_according_to_device_guidelines">Consistent design according to device guidelines</h3>
<p>One challenge of a multi-platform development environment is that you have somewhat of a contradiction with regards to the visual design and UX. On the one hand, you want to have an app with its own individual personality; on the other hand you want your app to fit in with the look and feel of the device. There are a couple of different approaches to this problem (which are discussed in more detail in our Graphics and UX articles) — you could design something fairly neutral that will work okay across most places, or you could serve different stylesheets depending on which device the app is installed or viewed on.</p>
<p>To make things easier for Firefox OS for example, we have written up <a href="http://buildingfirefoxos.com/" title="http://buildingfirefoxos.com/">comprehensive design guidelines</a> for styling Firefox OS apps, including example assets, behaviours and transitions, and design pattern information. For the Location Finder app, I just took the standard gradient slices and CSS from the guidelines and plugged them into my app, to create something consistent.</p>
<p>You also need to create an icon, or series of icons to use with your app. Indeed, this is a familiar practice with Web and app developers, and you will often end up with a favicon, a few sizes of icons for different platform homescreens, a larger, more detailed application icon to show in marketing material, etc. We have written a <a href="http://www.mozilla.org/en-US/styleguide/products/firefoxos/icons/" title="http://www.mozilla.org/en-US/styleguide/products/firefoxos/icons/">Firefox OS icon design guide</a> to give you more information for this particular case.</p>
<h3 id="Creating_a_new_app.2C_or_porting_an_old_site.2Fpage.2Fapp.3F">Creating a new app, or porting an old site/page/app?</h3>
<p>If you want to make an existing web site into an installable app, essentially you just need to add a <a href="/en-US/docs/Web/Apps/Manifest" title="/en-US/docs/Web/Apps/Manifest">manifest file</a> to provide metadata about the app (such as language and permissions settings) and an install mechanism (the Firefox OS <a href="/en-US/docs/Web/Apps/JavaScript_API" title="/en-US/docs/Web/Apps/JavaScript_API">Install API</a> handles this, for example) to allow app installation.</p>
<p>However, the likelihood is that you'll want to do more than this, to optimise your app's layout, design and functionality for the different target devices it will be installed upon. If the existing site is a monolithic legacy app, then you may even decide that the best course of action is to create a completely separate app for small screens. Retrofitting responsive design for such sites often works out a lot more expensive than just starting afresh.</p>
<h3>Paid apps and in-app payments</h3>
<p>You should decide if you want to make money with your app. You have the options of selling the app on a marketplace (a paid app) or implementing in-app payments. See the <a href="/en-US/docs/Web/Apps/App_payments_guide" title="/en-US/docs/Web/Apps/App_payments_guide">App payments guide</a> for more information.</p>
<h2 id="Implementing_app_functionality">Implementing app functionality</h2>
<p>There are many different types of functionality you might want to implement in your app, and to make things easier we have arranged our tutorials according to task areas. If you want to search by API or other technology feature, the best way is to use our search box, or go to the relevant section of the site, for example <a href="#">APIs</a> or <a href="#">CSS</a>.</p>
<p class="note">There are two types of installable app available, <strong>hosted apps</strong>, which can be distributed anywhere the same as normal websites, and <strong>packaged apps</strong>, which are archived in a .zip file and hosted in an app store, where they tend to be subjected to a rigorous testing and verification process before publication (the <a href="https://marketplace.firefox.com/" title="https://marketplace.firefox.com/">Firefox Marketplace</a>, for example). For a discussion of the differences between the two, read <a href="https://developer.mozilla.org/en-US/docs/Web/Apps/Packaged_apps">Packaged apps</a>.</p>
<div class="note">
  <p class="note">Note that if you don't wish to make your app an installable app, and just want to run it as a regular web page, you don't need to take these steps.</p>
</div>
<h3 id="Manifest">Manifest</h3>
<p>You need to add a manifest file to your app (a JSON file, often called manifest.webapp, and located in the root of your app directory), which defines a number of different items of metadata including language, name and description, icon information, permissions for using restricted APIs, and more. Let's look at the manifest file for our sample Location Finder app:</p>
<pre class="brush: json">
{
  "name": "Location",
  "description": "Location finder uses geolocation to find out where you are, and plots a map of your surroundings using the Google Maps API.",
  "launch_path": "/~cmills/location-finder/",
  "icons": {
    "128": "/~cmills/location-finder/img/icon-128.png"
  },
  "developer": {
    "name": "Chris Mills",
    "url": "http://www.conquestofsteel.co.uk"
  },
  "default_locale": "en"
}</pre>
<p>There are many options you can specify inside a manifest file, and we cover these all in detail in our dedicated <a href="/en-US/docs/Web/Apps/Manifest" title="/en-US/docs/Web/Apps/Manifest">App manifest article</a>; let's just briefly cover the options contained in the above minimal example:</p>
<ul>
  <li><code>"name": "Location"</code> — this specifies the name of your app, which is how it will appear both in the marketplace and on your device's home screen below the app icon when installed. It is a good idea to make this as short and snappy as possible.</li>
  <li><code>"description": "Location finder uses..."</code> — contains a description of your app's functionality, to be displayed in the app's Marketplace description. Make it as short as possible and try to make your app sound exciting, so it will encourage users to try it out.</li>
  <li><code>"launch_path": "/~cmills/location-finder/"</code> — contains the path to the root directory of your app on your Web server. This should be a relative path traveling from the root URL of your server. So the absolute URL to my sample app is <code>http://people.mozilla.com/~cmills/location-finder/</code>. The root URL is <code>http://people.mozilla.com</code>, and the relative path I need is therefore <code>/~cmills/location-finder/</code>.</li>
  <li><code>"icons": {</code> — contains a list of the different icons available in the app.
    <ul>
      <li><code>"128": "/~cmills/location-finder/img/icon-128.png"</code> — specifies that you have a 128px square icon available in the application, and provides a relative path to the icon file. Like the launch path, this must be a relative path travelling from the root path of the server. App icons should be in PNG format, and while you can include as many as you like, you need to include at least a 128px icon.</li>
    </ul>
  </li>
  <li><code>"developer": {</code> — contains information about the developer of the app.
    <ul>
      <li><code>"name": "Chris Mills",</code> — the developer name, listed on the marketplace page.</li>
      <li><code>"url": "http://www.conquestofsteel.co.uk"</code> — the developer's website, listed on the marketplace page. Ideally this should link to a site where more information or support&nbsp; for the app can be found.</li>
    </ul>
  </li>
  <li><code>"default_locale": "en"</code> — specifies the default language your app uses.</li>
</ul>
<p>My Location Finder app's root directory also has an .htaccess file in it, which contains the following line:</p>
<pre>
AddType application/x-web-app-manifest+json .webapp</pre>
<p>Manifest files need to be served with a mimetype of <code>application/x-web-app-manifest+json</code>.</p>
<h3 id="Install_API_functionality">Install API functionality</h3>
<p>In our sample Location Finder app, I've implemented an install button that you can click when viewing the Web page, to install that site on Firefox OS as an app. The button markup is nothing special:</p>
<pre class="brush: html">
&lt;button id="install"&gt;
  Install on FirefoxOS
&lt;/button&gt;</pre>
<p>This button's functionality is implemented using the Install API (see install.js):</p>
<pre class="brush: js">
function install(ev) {
  ev.preventDefault();
  // define the manifest URL
  var manifest_url = "http://people.mozilla.com/~cmills/location-finder/manifest.webapp";
  // install the app
  var installLocFind = navigator.mozApps.install(manifest_url);
  installLocFind.onsuccess = function(data) {
    // App is installed, do something
  };
  installLocFind.onerror = function() {
    // App wasn't installed, info is in
    // installapp.error.name
    alert(installapp.error.name);
  };
};

// get a reference to the button and call install() on click
var button = document.getElementById('install');

var installCheck = navigator.mozApps.checkInstalled("http://people.mozilla.com/~cmills/location-finder/manifest.webapp");
// check whether the app defined in the above manifest file is installed
installCheck.onsuccess = function() {
  if(installCheck.result) {
    button.style.display = "none";
    // if it's already installed on the device, hide the install button, as we don't need it.
  } else {
    button.addEventListener('click', install, false);
    // if it isn't, run the install code contained in the install() function
  };
};</pre>
<p>Let's run through briefly what is going on:</p>
<ol>
  <li>We get a reference to the install button and store it in the variable <code>button</code>.</li>
  <li>We use <code>navigator.mozApps.checkInstalled</code> to check whether the app defined by the manifest at <code>http://people.mozilla.com/~cmills/location-finder/manifest.webapp</code> is already installed on the device. This test is stored in the variable <code>installCheck</code>.</li>
  <li>When the test is successfully carried out, its success event is fired, therefore <code>installCheck.onsuccess = function() { ... }</code> is run.</li>
  <li>We then test for the existance of <code>installCheck.result</code> using an <code>if</code> statement. If it does exist, meaning that the app is installed, we hide the button. An install button isn't needed if it is already installed.</li>
  <li>If the app isn't installed, we add a click event listener to the button, so the <code>install()</code> function is run when the button is clicked.</li>
  <li>When the button is clicked and the <code>install()</code> function is run, we store the manifest file location in a variable called <code>manifest_url</code>, and then install the app using <code>navigator.mozApps.install(manifest_url)</code>, storing a reference to that installation in the <code>installLocFind</code> variable. You'll notice that this installation also fires success and error events, so you can run actions dependant on whether the install happened successfully or not.</li>
</ol>
<p>You may want to verify the <a href="/en-US/docs/Web/Apps/JavaScript_API">implementation state of the API</a> when first coming to Installable web apps.</p>
<h3 id="Web_app_functionality_categories">Web app functionality categories</h3>
<p>There are a great number of different things you might want your Open Web App to do, but largely they are going to fall into some common task categories, which we will deal with in turn. In this content zone we are going to look at applied uses of technologies as related to Open Web Apps and their specific issues and use cases. If you want to search for more generic information on a specific CSS property or API, such as a basic implementation guide or reference page, then you are advised to do a search using our search bar, or browse the relevant section of the site (<a href="/en-US/docs/Web/API" title="/en-US/docs/Web/API">Web API</a>, <a href="/en-US/docs/Web/CSS" title="/en-US/docs/Web/CSS">CSS</a>, etc.).</p>
<p>The task categories are:</p>
<ul>
  <li>Gathering information</li>
  <li>Controlling device display</li>
  <li>Data storage and offline usage</li>
  <li>Controlling media</li>
  <li>Services for users</li>
  <li>Utility APIs</li>
</ul>
<p>You can explore these more deeply starting at our <a href="/en-US/docs/Web/Apps/Developing" title="/en-US/docs/Web/Apps/Developing">Developing Web Apps</a> page.</p>
<h4 id="App_permissions">App permissions</h4>
<p>You should note that some of the advanced APIs you can utilise in Open Web Apps (for example Contacts API, Camera API, Device Storage API) that allow access to device features or hardware are restricted for security purposes, meaning that they require access permissions to be set in the manifest file, and distribution through the <a href="https://marketplace.firefox.com/" title="https://marketplace.firefox.com/">Firefox Marketplace</a> (or another trusted app store). The three levels of permission are as follows:</p>
<ul>
  <li>Normal — APIs that don't need any kind of special access permissions.</li>
  <li>Privileged — APIs available to developers to use in their applications, as long as they set access permissions in the app manifest files, and distribute them through a trusted source.</li>
  <li>Certified — APIs that control critical functions on a device, such as the call dialer and messaging services. These are generally not available for third party developers to use.</li>
</ul>
<p>For more information on app permission levels, read <a href="/en-US/docs/Web/Apps/Packaged_apps#Types_of_packaged_apps" title="/en-US/docs/Web/Apps/Packaged_apps#Types_of_packaged_apps">Types of packaged apps</a>.</p>
<h4 id="Testing_your_apps">Testing your apps</h4>
<p>You should really do multiple test runs on your apps at different stages of development, so you can keep a check on whether you are going in the right direction, and find major bugs as soon as possible. To help you out, we have written a guide to testing on a wide variety of devices, which provides many hints and tips, as well as a usage guide for the different testing tools available, including the <a href="https://addons.mozilla.org/en-US/firefox/addon/firefox-os-simulator/" title="https://addons.mozilla.org/en-US/firefox/addon/firefox-os-simulator/">Firefox OS simulator</a>. You should always try to test on real devices where possible, though.</p>
<h2 id="Publishing_your_apps">Publishing your apps</h2>
<p>So you've got your app created, and you want to share it with the world? Great! There are a couple of options for you, which give you the freedom to do what you want with your creation. First, you can just host the app as a standard website/page, on any online location of your choosing. To make it installable, you just need to provide a manifest file to describe and define your app, and an install mechanism, as we discussed above. Second, you can package your app in a zip file, and either host the packaged app yourself, or publish it an app store (such as the <a href="https://marketplace.firefox.com/" title="https://marketplace.firefox.com/">Firefox Marketplace</a>). The Firefox Marketplace will provide an installation button if you are hosting your app's manifest file there. We have written a detailed guide to <a href="/en-US/docs/" title="/en-US/docs/">Publishing your apps</a>, which guides you through creating packaged apps, as well as providing publication FAQs and checklists, information on using the <a href="http://firefox-marketplace-api.readthedocs.org/en/latest/index.html" title="http://firefox-marketplace-api.readthedocs.org/en/latest/index.html">Firefox Marketplace API</a>, and ideas on promotion and monetization.</p>
<div class="note">
  <p>It's important to note that each app should be hosted from its own domain. Different apps should not share the same domain. An acceptable solution is to host each app from a different subdomain, for example. See <a href="/en-US/docs/Web/Apps/FAQs/About_app_manifests">FAQs about apps manifests</a> for more information on origins.</p>
</div>
<p>The video below provides a useful overview of the advantages of open marketplaces and an open web approach to app discovery:</p>
<p style="text-align: center;"><iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/QCH_ncCrZfE/?feature=player_detailpage" width="640"></iframe></p>
Revert to this revision