Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(manifest): Improvements to scope page #36137

Merged
merged 9 commits into from
Oct 31, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 38 additions & 27 deletions files/en-us/web/manifest/scope/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ browser-compat: html.manifest.scope

{{QuickLinksWithSubpages("/en-US/docs/Web/Manifest")}}

The `scope` manifest member is used to define the navigation scope of your web application.
It restricts the web pages that can be navigated while the manifest is applied.
The `scope` manifest member is used to specify the top-level URL path that contains your web application, determining which pages and subdirectories are part of the web app and where the manifest is applied.
Web pages within the defined scope are presented distinctly so that users can recognize when they are navigating within the app.

## Syntax

Expand Down Expand Up @@ -36,73 +36,84 @@ It restricts the web pages that can be navigated while the manifest is applied.

## Description

The `scope` member specifies the navigation boundaries of your web app, that is, pages that are considered part of the app and that are not. You can add a `scope` for your web app to ensure users remain within the {{Glossary("Application_context", "application's context")}} while navigating your app.
The `scope` member defines the set of URLs that is considered part of your web app when the manifest is applied.
dipikabh marked this conversation as resolved.
Show resolved Hide resolved

### Fallback behavior
It enables deep linking into your web app from other applications. For example, if your hiking app's scope is `https://hikingapp.com/trails/`, a weather app can directly link to `https://hikingapp.com/trails/trailA/trail-conditions`. Note that deep linking is possible even without defining a scope, but defining it allows you to control pages that are considered part of your web app.
dipikabh marked this conversation as resolved.
Show resolved Hide resolved

When `scope` is missing or invalid, it defaults to `start_url`. For example:
### Fallback scope behavior

- If `start_url` is `https://example.com/app/index.html?user=123#home`, the navigation scope will be `https://example.com/app/`.
- If `start_url` is `/pages/welcome.html`, the navigation scope will be `/pages/` on the same origin.
- If `start_url` is `/pages/` (the trailing slash is important), the navigation scope will be `/pages/`.
The `scope` is invalid if `start_url` is not a subset of the `scope` URL. For example:

- Valid: `scope` is `/app/` and `start_url` is `/app/home.html`.
- Invalid: `scope` is `/app/` and `start_url` is `/index.html`.
hamishwillee marked this conversation as resolved.
Show resolved Hide resolved

If `scope` is missing or invalid, it defaults to `start_url`, with the filename, query, and fragment removed. For example:

- If `start_url` is `https://example.com/app/index.html?user=123#home`, the scope will be `https://example.com/app/`.
- If `start_url` is `/pages/welcome.html`, the scope will be `/pages/` on the same origin.
- If `start_url` is `/pages/` (the trailing slash is important), the scope will be `/pages/`.

If you rely on the fallback behaviour of `scope`, ensure that URLs of all pages in your app begin with the parent path of `start_url`.
To avoid potential issues with scope determination in this way, it's recommended to explicitly specify `scope` in your manifest file.
To avoid issues with scope determination in this way, it's recommended to explicitly specify `scope` in your manifest file.

### String matching for scope
### Scope matching mechanism

String matching for the scope URL uses a simple prefix match, not the path structure.
For example, the target URL string `/prefix-of/resource.html` will match an app with `scope` set as `/prefix`, even though the path segment name is not an exact match.
To avoid unexpected behavior, it's recommended to use a scope ending with a `/`.
For example, if the `scope` is set as `/prefix`, it will match URLs starting with `/prefix`, including `/prefix-of/index.html` and `/prefix/index.html`. Note that `/prefix-of/index.html` matches even though `prefix-of` is not an exact match with the scope `/prefix`.

### Navigation scope
For this reason, it's recommended to define a scope ending with a `/`.
Setting the `scope` as `/prefix/` ensures it will match only the pages within the `/prefix/` directory, preventing unintended matches.

### In-scope and out-of-scope behavior

A URL is considered to be "within scope" if its path begins with the URL path defined in `scope`.
For example, if the `scope` is set to `/app/`, then the URLs `/app/`, `/app/page.html`, and `/app/dashboard/index.html` will all be considered within scope, while `/` or `/page.html` will not be considered within the scope of the application's context.
For example, if the `scope` is set to `/app/`, then the URLs `/app/`, `/app/page.html`, and `/app/dashboard/index.html` are all considered within scope, while `/` or `/page.html` are not.

When a user navigates to a URL, browsers use the scope to determine if the resource is within your web app's {{Glossary("Application_context", "application context")}}. For in-scope pages, browsers maintain the application context and preserve the app-like experience. They may present these pages differently to indicate to users that they are navigating within the application.

If a user navigates to a web page that is not within the scope of your web app's context, browsers may display a prominent UI element, which clearly shows the URL or at least its origin, including whether it is served over a secure connection.
This UI element will typically be different from what users see when navigating within the app's scope.
When a user navigates to a web page that is not within the scope of your web app's application context, browsers may display a prominent UI element, which clearly shows the URL or at least its origin, including whether it is served over a secure connection.
This UI element will be different from what users see when navigating within the app's scope.
dipikabh marked this conversation as resolved.
Show resolved Hide resolved
This behavior aims to make users aware that they have navigated away from your web app.
dipikabh marked this conversation as resolved.
Show resolved Hide resolved

> [!NOTE]
> The existence of a `scope` doesn't prevent navigation to URLs outside of the defined scope while the manifest is applied.
> Off-scope navigations are not blocked and not opened in a new top-level browsing context.
> The existence of a `scope` doesn't prevent users from navigating to URLs outside of the defined scope while the manifest is applied.
> Off-scope navigations are not blocked by browsers and are not opened in a new top-level browsing context.
dipikabh marked this conversation as resolved.
Show resolved Hide resolved

## Examples

### Specifying an absolute URL for scope

Consider a scenario where the manifest file for your web app is linked from `https://example.com/index.html`, and you want the navigation scope to include all the subdirectories. You can specify this scope such that it is same-origin with manifest file URL:
Suppose the manifest file for your web app is linked from `https://hikingapp.com/index.html`, and you want the scope to include all the subdirectories. You can specify this scope using an absolute URL that is same-origin with manifest file URL, as shown below. This ensures that pages like `https://hikingapp.com/store` and `https://hikingapp.com/company` are part of your web app.

```json
{
"scope": "https://example.com/"
"scope": "https://hikingapp.com/"
}
```

### Specifying a relative URL for scope

Suppose your manifest file's URL is `https://example.com/resources/manifest.json`, and you want the navigation scope to be `https://example.com/app/`. In this case, you can define the `scope` as a relative URL like so:
If your manifest file's URL is `https://hikingapp.com/resources/manifest.json`, and you want the scope to be `https://hikingapp.com/app/`, you can define it as a relative URL:

```json
{
"scope": "../app/"
}
```

### Limiting navigation to a specific part in your web app
### Defining a web app for a specific section of your site

If you have a web app with multiple sections, but you want to limit the navigation to one section, you can define the `scope` as:
If you have a website with multiple sections, but you want your web app to focus on a specific section, you can define the `scope` as:

```json
{
"name": "My Web App",
"start_url": "https://example.com/store/",
"scope": "https://example.com/store/"
"name": "My Hiking Web App",
"start_url": "https://hikingapp.com/store/",
"scope": "https://hikingapp.com/store/"
}
```

Users will be able to navigate to `https://example.com/store/products`, but navigating to `https://example.com/company/` will be out of scope for your web app. For off-scope URLs, browsers may display different UI elements to let users know they've navigated away from the app.
With this setup, pages like `https://hikingapp.com/store/products` are part of your web app, but `https://hikingapp.com/company/` is out of your web app's scope. For off-scope URLs, browsers may display different UI elements to let users know they've navigated away from the app.

## Specifications

Expand Down