Configuration

The Service Worker is a JavaScript file that acts as a proxy between your web application and the network. It enables advanced features like offline functionality, background sync, and push notifications.

The PWA Bundle automatically generates and serves your service worker based on your configuration. You simply need to provide a source file (which can be empty to start) and configure the desired features.

Basic Configuration

The simplest configuration requires only specifying the source file:

/config/packages/pwa.yaml
pwa:
    serviceworker: "sw.js"

This shorthand configuration:

  • Enables the service worker

  • Uses sw.js from your /assets/ folder as the source

  • Serves it publicly at /sw.js

The sw.js file can start empty. The bundle will automatically populate it with functionality based on your configuration (Workbox, caching strategies, etc.).

Expanded Configuration

The shorthand above is equivalent to:

/config/packages/pwa.yaml
pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        dest: "/sw.js"  # Public URL (default)
        scope: "/"      # Service worker scope (default)

Configuration Options

Enabled

Type: boolean Default: false (or true when using shorthand)

Controls whether the service worker is active.

pwa:
    serviceworker:
        enabled: true

Source (src)

Type: string Required: Yes

Path to your source service worker file. This file is processed by Asset Mapper and can contain custom JavaScript that will be merged with the bundle's generated code.

pwa:
    serviceworker:
        src: "sw.js"              # From /assets/sw.js
        # or
        src: "custom/my-sw.js"    # From /assets/custom/my-sw.js

The source file can:

  • Be completely empty (bundle generates everything)

  • Contain custom service worker logic

  • Import additional modules

Destination (dest)

Type: string Default: "/sw.js"

Public URL where the compiled service worker will be accessible. This is the URL browsers will use to register the service worker.

pwa:
    serviceworker:
        dest: "/service-worker.js"
        # or
        dest: "/assets/sw.js"

Service workers must be served from the same origin as your application. The bundle handles this automatically.

Scope

Type: string Default: "/"

Defines the service worker's registration scope - the subset of pages it can control. Only pages within this scope can use the service worker.

pwa:
    serviceworker:
        scope: "/"           # Controls all pages
        # or
        scope: "/app/"       # Controls only pages under /app/

Important: The scope should match your manifest scope to ensure consistent PWA behavior.

Scope Rules:

  • Service workers can only control pages at their scope level or deeper

  • A service worker at /app/ cannot control pages at /admin/

  • Use / for a global service worker

  • The scope must be at or above the service worker's location

Use Cache

Type: boolean Default: true

Controls how the browser's HTTP cache is used when checking for service worker updates.

pwa:
    serviceworker:
        use_cache: true   # Use HTTP cache (default)
        # or
        use_cache: false  # Bypass cache on updates

When true:

  • Browser may use cached version during update checks

  • Faster checks, but updates may be delayed

  • Respects standard HTTP caching headers

When false:

  • Browser bypasses cache during update checks

  • Ensures latest version is always fetched

  • May increase server load

Skip Waiting

Type: boolean Default: false

Controls whether a new service worker version activates immediately or waits for all tabs using the old version to close.

pwa:
    serviceworker:
        skip_waiting: false  # Wait for tab closure (default)
        # or
        skip_waiting: true   # Activate immediately

When false (default - recommended):

  • New service worker waits until all tabs close

  • Prevents version conflicts

  • Ensures consistent experience across tabs

  • Safer for most applications

When true:

  • New service worker activates immediately

  • May cause version mismatches between tabs

  • Old tabs might have old assets, new tabs new assets

  • Can break applications expecting consistent versions

Use case for skip_waiting: true:

  • Critical bug fixes that must deploy immediately

  • Applications designed to handle version differences

  • Single-page apps that can gracefully reload

Complete Configuration Example

/config/packages/pwa.yaml
pwa:
    serviceworker:
        enabled: true
        src: "sw.js"
        dest: "/service-worker.js"
        scope: "/"
        use_cache: true
        skip_waiting: false

        # Workbox configuration (see Workbox documentation)
        workbox:
            enabled: true
            # ... workbox options

Service Worker Initialization

The service worker is automatically registered when you include the PWA Twig function in your template:

templates/base.html.twig
<!DOCTYPE html>
<html>
<head>
    {{ pwa() }}
</head>
<body>
    ...
</body>
</html>

The registration script:

  • Uses Workbox Window if Workbox is enabled

  • Falls back to vanilla JavaScript registration otherwise

  • Handles update checks automatically

  • Respects your configuration (scope, use_cache, skip_waiting)

Manual Service Worker Updates

For advanced control over service worker updates, use the Service Worker Stimulus Controller:

<div {{ stimulus_controller('@pwa/service-worker') }}>
    <button data-action="pwa--service-worker#update">
        Check for updates
    </button>
</div>

Next Steps

Last updated

Was this helpful?