> Markdown version of [PWA](https://vaadin.com/docs/next/flow/configuration/pwa). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Progressive Web Applications

Some extra configuration enables a Vaadin application to run as a *Progressive Web Application* (PWA). PWAs aim to give the same experience as native applications, with a user-friendly installation flow, and a capability to work offline. They look like a regular application in the home screen of a mobile device or in the application menus of a desktop operating system. A PWA needs some metadata, such as name, description, and icon, which are used by the operating system to display information about the application.

To enable offline use, TypeScript needs to be used to provide the offline views. [Hilla](https://vaadin.com/hilla) is the recommended framework to build client-side views.

For a generic introduction to PWA, see the article on [What are Progressive Web Applications and Why Build a PWA](https://vaadin.com/pwa).

## <a id="progressive-web-application-concepts"></a>Progressive Web Application Concepts

All PWAs have the following common basic features that enable native-app-like behavior:

- **Web Application Manifest**

  The manifest provides information about an application, for example its name, theme, icon, and description. These details are needed to make an installable version of the web application.

  See [PWA Web Application Manifest](#manifest) for details about defining a manifest.

- **Service Worker**

  A service worker is a type of *web worker*, a JavaScript program that runs in the background. Its ability to intercept network requests makes it possible to serve files directly from the browser’s cache and create a full application experience, even when no network is available.

  Essentially, it’s a JavaScript file that:

  - runs separately from the main browser thread;

  - intercepts network requests;

  - caches and retrieves resources from the cache;

  - delivers Push messages.

  See [PWA Service Worker](#service-worker) for details about defining a service worker.

## <a id="creating-pwas-with-flow"></a>Creating PWAs with Flow

Vaadin Flow automatically serves the required resources for a PWA when you use the `@PWA` annotation in the [Application Shell](https://vaadin.com/docs/next/flow/advanced/modifying-the-bootstrap-page.md). The `@PWA` annotation must be placed in the Application Shell class.

For example, you can use the `@PWA` annotation to automatically serve PWA resources as follows:

```java
@PWA(name = "My Progressive Web Application",
     shortName = "MyPWA")
public class AppShell implements AppShellConfigurator {
}
```

The Vaadin server automatically serves the [manifest](#manifest), [service worker](#service-worker), [icons](#icons), and [offline experience](#offline), and adds the necessary additions to the application headers.

The `shortName` parameter shouldn’t exceed 12 characters. See [PWA Web Application Manifest](#manifest) for a list of `@PWA` annotation parameters you can use.

## <a id="application-installation-requirements"></a>Application Installation Requirements

To support installation on devices, the following features are required. These depend on the device and browser used:

- **Icons**

  Different icon sizes are needed to support different devices. To enhance the experience, splash screen images are also required.

- **Offline support**

  The service worker must be able to respond to serve the client if a network isn’t available.

- **Header information**

  The application must include browser- and/or device-specific theming and icon data in the header. This is in addition to the manifest file.

- **HTTPS**

  Many new browser features, including those required for PWAs, require HTTPS. Even if your PWA currently works without HTTPS in some environments (for example, Android), this is likely to change and PWAs that don’t support HTTPS probably malfunction in the future.

## <a id="manifest"></a>PWA Web Application Manifest

When the `@PWA` annotation is found, Vaadin automatically generates a web application manifest file named `manifest.webmanifest`.

Here is a list of properties in the file that you can customize. Except for `scope`, all properties can be set in the `@PWA` annotation.

- `name`

  The name of the application. Set this property in the `name` parameter in the `@PWA` annotation.

- `short_name`

  The short name of the application. This shouldn’t exceed 12 characters. It’s used on the device home screen, where there is a limited amount of space. Set this property in the `shortName` parameter in the `@PWA` annotation.

- `description`

  The description of the application. The default value is an empty string. Set this property in the `description` parameter in the `@PWA` annotation.

- `display`

  Defines the preferred display mode for the application. The default value is `standalone`. Set this property in the `display` parameter in the `@PWA` annotation.

- `background_color`

  The background color of the application. The default value is `#f2f2f2` (gray). Set this property in the `backgroundColor` parameter in the `@PWA` annotation.

- `theme_color`

  The theme color of application. The default value is `#ffffff` (white). Set this property in the `backgroundColor` parameter in the `@PWA` annotation.

- `scope`

  Defines the navigation scope of the website’s context. This restricts the web pages that can be viewed while the manifest is applied. The value is set to the context path of application. You can’t change this property in the `@PWA` annotation.

- `start_url`

  The start URL that’s navigated to when the application is launched from the installed application (home screen). The default value is an empty string `""` that points to the default route target for the application (marked with `@Route("")`). Set this property in the `startPath` parameter in the `@PWA` annotation.

- `icons`

  Automatically created from [icon resources](#icons).

> **Note:** For more information about these properties, see [Web Application Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) in the Mozilla Developer Network (MDN) web docs.

### <a id="renaming-the-manifest"></a>Renaming the Manifest

You can change the default name (`manifest.webmanifest`) of the web application manifest, using the `manifestPath` parameter in the `@PWA` annotation.

The following example shows how to do this:

```java
@PWA(name = "My Progressive Web Application",
     shortName = "MyPWA",
     manifestPath = "manifest.json")
```

### <a id="overriding-the-generated-manifest"></a>Overriding the Generated Manifest

You can override the generated manifest file with a custom manifest.

To override the generated web application manifest file:

1. Create a custom manifest file and name it to match the file name set in the `manifestPath` parameter in the `@PWA` annotation, for example `manifest.webmanifest`.

2. Add the file to your `src/main/webapp/` folder.

## <a id="service-worker"></a>PWA Service Worker

When the `@PWA` annotation exists, Vaadin automatically generates a simple service worker during application startup.

The generated service worker:

- caches [offline resources](#offline), including the TypeScript views, offline page, icons, and custom (user-defined) offline resources;

- handles the [offline experience](#offline), by serving the TypeScript views offline, or the separate offline page.

> **Note:** The service worker can only respond to full navigation events, such as refresh or direct navigation to a URL.

The service worker uses [Google Workbox](https://developers.google.com/web/tools/workbox/) to cache resources.

### <a id="service-worker.cache-resources"></a>Defining Custom Cache Resources

You can define custom resources to be cached automatically by the service worker, using the `offlineResources` parameter in the `@PWA` annotation.

For example, to define `styles/offline.css`, `img/offline.jpg` and `js/jquery.js` as offline resources for caching:

```java
@PWA(name = "My Progressive Web Application",
     shortName = "MyPWA",
     offlineResources = {
        "styles/offline.css", "js/jquery.js", "img/offline.jpg" })
```

### <a id="overriding-the-generated-service-worker"></a>Overriding the Generated Service Worker

You can override the generated service worker with a custom service worker.

To override the generated service worker file, create the file named `sw.ts` in the `frontend` folder.

> **Note: Default service worker**
>
> To ensure that your custom service worker deals with offline support and resource caching, you can copy the default service worker from `target/sw.ts` and use it as a template.

## <a id="icons"></a>PWA Application Icons

PWAs need at least three icons: a favicon for the browser page, a device icon for the installed application, and an icon used on the splash screen of the installed application.

### <a id="using-a-custom-icon"></a>Using a Custom Icon

Vaadin uses and serves default PWA icons automatically, but you can use a custom icon.

To use a custom icon image:

1. Create an icon image named `icon.png`. The icon must be in `PNG` format.

2. Add the image to `icons/` in your static web resources (`src/main/resources/META-INF/resources/icons/` in Spring projects, `src/main/webapp/icons/` for non-Spring projects).

Vaadin automatically scans for an image named `icon.png` in the `/icons` folder in the `webapp` resources folder. It uses this image to create appropriately sized images for different devices. If no icon is found, the default image is used as a fallback.

To ensure that all resized images are attractive, use an image of at least 512 × 512 pixels. This is only large enough to be scaled down, as scaling up can cause pixelation.

### <a id="overriding-generated-icons"></a>Overriding Generated Icons

All generated images are named using the icon-\[width]x\[height].png notation, for example icon-1125x2436.png.

To override a generated image:

1. Create an image of the size you want to override and name it using the notation mentioned above; for example, `icon-1125x2436.png` for a custom high-resolution splash screen image for iOS devices.

2. Add the image to `icons/` in your static web resources (`src/main/resources/META-INF/resources/icons/` in Spring projects, `src/main/webapp/icons/` for non-Spring projects).

### <a id="renaming-icons"></a>Renaming Icons

You can change the default icon path to a custom path, using the `iconPath` parameter in the `@PWA` annotation.

A custom path can be defined with the `iconPath` parameter in the `@PWA` annotation, as shown in the following example:

```java
@PWA(name = "My Progressive Web Application",
     shortName = "MyPWA",
     iconPath = "img/icons/logo.png")
```

## <a id="offline"></a>PWA Offline Experience

Vaadin supports two alternative ways of building offline experiences:

- Client-side TypeScript views (default)

- A separate offline page

For PWAs built with Vaadin, the service worker provides offline support for TypeScript routes and views. This enables building custom view logic in the offline mode. By default, it stores the application shell HTML, the compiled frontend bundles, and the other necessary resources, and then serves them offline from the browser’s cache.

When it isn’t required to build application views that work offline (for example, if it’s enough only to display a static content page in the offline mode), you can optionally use a separate offline page instead of TypeScript views (`offlinePath` property in `@PWA` annotation).

### <a id="offline-typescript-views"></a>Offline TypeScript Views

Adding the `@PWA` annotation on your application shell class enables the service worker, which automatically serves the client-side views offline.

The service worker also caches and serves offline all the imported dependencies (using `import`) in TypeScript views.

### <a id="creating-a-custom-offline-page"></a>Creating a Custom Offline Page

To use a separate offline page:

1. Create a file named `offline.html`.

2. Add the file to your static web resources directory (`src/main/resources/META-INF/resources/` in Spring projects, `src/main/webapp/` for non-Spring projects).

3. Specify `offlinePath="offline.html"` in the `@PWA` annotation.

You can change the name of the specified offline page file in the `offlinePath` parameter.

The offline page can only use resources found in the cache. By default, only the offline page, [manifest](#manifest), and [icons](#icons) are cached. If your page needs external resources (such as CSS, images, Web Components), you can define them using the `offlineResources` parameter in the `@PWA` annotation. See [Defining Custom Cache Resources](#service-worker.cache-resources) for more.

PWA annotation with `offlinePath` setting:

```java
@PWA(name = "My Progressive Web Application",
     shortName = "MyPWA",
     offlinePath = "offline.html")
public class AppShell implements AppShellConfigurator {
}
```

### <a id="generated-offline-page"></a>Generated Offline Page

The generated offline page provides compatibility with PWAs built with earlier versions of Vaadin. Consider using TypeScript views offline, or a custom offline page.

Vaadin has a built-in `offline.html` generated offline page. This is a simple page that:

- includes the application name and icon;

- communicates to the user that the application is offline, because there is no network connection.

To use the built-in offline page, specify `offlinePath="offline.html"`, as in [the earlier example](#offlinePath).

`EE06DDFE-6934-49E0-AF99-2316376BD26C`
