Work on more than one document at a time with tabs in your Progressive Web App
In the world of computing, the desktop metaphor is an interface metaphor that is a set of unifying concepts used by graphical user interfaces (GUI) to help users interact more intuitively with the computer. In keeping with the desktop metaphor, GUI tabs are modeled after classic card tabs inserted in books, paper files, or card indexes. A tabbed document interface (TDI) or tab is a graphical control element that allows multiple documents or panels to be contained within a single window, using tabs as a navigational widget for switching between sets of documents.
Progressive Web Apps can run in various display modes determined by the
display
property in the web app manifest. The options are fullscreen
, standalone
,
minimal-ui
, and browser
. These display modes follow a
well-defined fallback chain
("fullscreen"
→ "standalone"
→ "minimal-ui"
→ "browser"
). If a browser does not support a
given mode, it falls back to the next display mode in the chain. Using the
"display_override"
property, developers can specify their own fallback chain
if they need to.
What is tabbed application mode
Something that has been missing from the platform so far is a way to let PWA developers offer their users a tabbed document interface, for example, to enable editing different files in the same PWA window. Tabbed application mode closes this gap.
Use cases for tabbed application mode
Examples of sites that may use tabbed application mode include:
- Productivity apps that let the user edit more than one document (or file) at the same time.
- Communication apps that let the user have conversations in different rooms per tab.
- Reading apps that open article links in new in-app tabs.
Differences to developer-built tabs
Having documents in separate browser tabs comes with resource isolation, which is not possible using the web today. Developer-built tabs wouldn't scale acceptably to hundreds of tabs like browser tabs do. Browser affordances such as navigation history, "Copy this page URL", "Cast this tab" or "Open this page in a web browser" would be applied to the developer-built tabbed interface page, but not the selected document page.
Differences to "display": "browser"
The current "display": "browser"
already has a
specific meaning:
Opens the web application using the platform-specific convention for opening hyperlinks in the user agent (e.g., in a browser tab or a new window).
While browsers can do whatever they want regarding UI, it would clearly be a pretty big subversion
of developer expectations if "display": "browser"
suddenly meant "run in a separate
application-specific window with no browser affordances, but a tabbed document interface".
Setting "display": "browser"
is effectively the way you opt out of being put into an application
window.
Current status
Step | Status |
---|---|
1. Create explainer | Completed |
2. Create initial draft of specification | Completed |
3. Gather feedback & iterate on design | Completed |
4. Origin trial | Completed |
5. Launch | Completed (ChromeOS) |
Use tabbed application mode
To use tabbed application mode, developers need to opt their apps in by setting a specific
"display_override"
mode value in the web app manifest.
{
"display": "standalone",
"display_override": ["tabbed"]
}
Next, the property "tab_strip"
can optionally be used to fine-tune the tab behavior. It has two
allowed sub-properties, "home_tab"
and "new_tab_button"
. If the "tab_strip"
property is not
present, it will default to the following object:
"tab_strip": {
"new_tab_button": {
"url": <start_url>,
},
}
Home tab
The home tab is a pinned tab that, if enabled for an app, should always be present when the app is open. This tab should never navigate. Links clicked from this tab should open in a new app tab. Apps can choose to customize the URL this tab is locked to and the icon displayed on the tab.
The "home_tab"
member of the "tab_strip"
object contains information about a special "home tab"
that is intended to serve as the top-level menu for the application. It contains the following member:
"scope_patterns"
: The"scope_patterns"
member is a list of URL Patterns that define the scope of the home tab relative to the manifest URL.
New tab button
The "new_tab_button"
member of the "tab_strip"
object describes the behavior of a UI affordance (such as
a button) which, when clicked/activated, opens a new application context within
the application window. It has the following member:
"url"
: The"url"
member is a string that represents a URL relative to the manifest URL that is within scope of a processed manifest.
An application has a new tab button if the processed manifest's new_tab_button's
"url"
member is outside of home tab scope. If the application does not have a
new tab button, the browser doesn't make the "new tab" affordance available to
the user.
Complete example
A complete example to configure the behavior of an app with a tabbed interface may look as follows:
{
"name": "Tabbed App Example",
"start_url": "/",
"display": "standalone",
"display_override": ["tabbed"],
"tab_strip": {
"home_tab": {
"scope_patterns": [
{"pathname": "/"},
{"pathname": "/index.html"}
]
},
"new_tab_button": {
"url": "/create"
}
}
}
Detect tabbed application mode
Apps can detect whether they are running in tabbed application mode by checking the
display-mode
CSS media feature
in either CSS or JavaScript:
@media (display-mode: tabbed) {
/* Styles to apply in tabbed application mode. */
}
const tabbedApplicationModeEnabled = window.matchMedia('(display-mode: tabbed)').matches;
Interaction with the Launch Handler API
The Launch Handler API lets sites redirect app
launches into existing app windows to prevent duplicate windows from being opened. When a
tabbed app sets "client_mode": "navigate-new"
, app launches will open a new tab in an
existing app window.
Demo
You can try tabbed application on ChromeOS:
- Install the app tabbed-application-mode.glitch.me (source code).
- Click the different links on the different tabs.
Feedback
The Chrome team wants to hear about your experiences with tabbed application mode.
Tell us about the API design
Is there something about tabbed application mode that does not work like you expected? Comment on the web app manifest Issue that we have created.
Report a problem with the implementation
Did you find a bug with Chrome's implementation? File a bug at
new.crbug.com. Be sure to include as much detail as you can,
instructions for reproducing, and enter UI>Browser>WebAppInstalls
in the Components box.
Glitch works great for sharing quick reproduction cases.
Show support for the API
Are you planning to use tabbed application mode? Your public support helps the Chrome team prioritize features and shows other browser vendors how critical it is to support them.
Send a tweet to @ChromiumDev using the hashtag
#TabbedApplicationMode
and let us know where and how you are using it.
Useful links
- Explainer
- Web app manifest spec issue
- Chromium bug
- Blink Component:
UI>Browser>WebAppInstalls
Acknowledgements
Tabbed application mode was explored by Matt Giuca. The experimental implementation in Chrome was the work of Alan Cutter. This document was reviewed by Joe Medley. Hero image by Till Niermann on Wikimedia Commons.