Offline Map Tile Capabilities in WorldMonitor’s PWA Service Worker

WorldMonitor’s Progressive Web App uses a NetworkFirst caching strategy in its service worker to store PMTiles vector tile ranges locally, enabling full map rendering without an internet connection after the initial load.

The koala73/worldmonitor repository implements a robust offline-first architecture for its mapping interface through a carefully configured service worker. By leveraging vite-plugin-pwa to intercept PMTiles requests and apply intelligent caching policies, the application ensures that users can browse geographic data even when connectivity is unavailable or intermittent.

Network-First Caching for PMTiles Ranges

The service worker configuration in vite.config.ts specifically targets vector tile archives using a NetworkFirst handler. This strategy intercepts requests where the URL ends with .pmtiles or originates from PMTiles CDNs (*.r2.dev or build.protomaps.com).

// vite.config.ts - runtimeCaching configuration
{
  urlPattern: ({ url }) => url.pathname.endsWith('.pmtiles') || 
                         url.hostname.includes('r2.dev') ||
                         url.hostname === 'build.protomaps.com',
  handler: 'NetworkFirst',
  options: {
    cacheName: 'pmtiles-ranges',
    expiration: {
      maxEntries: 500,
      maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days
    }
  }
}

This approach prioritizes fresh data by attempting the network first, but stores the response bytes in the pmtiles-ranges cache. Subsequent requests for identical tile ranges are served directly from the cache, allowing the map to continue drawing even when navigator.onLine returns false.

Cache Size and Lifetime Management

The configuration imposes strict storage constraints to prevent unbounded growth. The pmtiles-ranges cache retains a maximum of 500 entries and automatically purges tiles older than 30 days (2,592,000 seconds). This balance ensures sufficient offline coverage while maintaining reasonable storage footprints on user devices.

Static Asset Precaching for UI Reliability

Beyond dynamic tile data, the service worker precaches all essential application assets at install time. The workbox.globPatterns in vite.config.ts captures JavaScript bundles, CSS stylesheets, icons, images, and font files:

// vite.config.ts - workbox configuration
workbox: {
  globPatterns: ['**/*.{js,css,ico,png,svg,woff2}'],
  // Additional runtimeCaching entries...
}

This guarantees that the map interface itself—including the MapLibre GL rendering engine and UI components—loads instantly from the cache during subsequent visits, regardless of network status.

Stale-While-Revalidate for Visual Assets

Map-related imagery and typography receive a StaleWhileRevalidate treatment. The worker caches image assets matching patterns like \.(?:png|jpg|jpeg|svg|gif) and Google Fonts (fonts.googleapis.com) with this strategy, serving cached versions immediately while fetching updates in the background. This ensures map icons, glyphs, and symbols remain available offline while silently refreshing when connectivity returns.

Service Worker Lifecycle and Protocol Registration

The registration logic in src/main.ts handles version consistency critical for offline reliability. On initialization, the application clears stale workers and caches, then registers the new worker. It also triggers page reloads when updated workers take control, preventing version skew that could otherwise break offline rendering after deployments.

For the service worker to intercept PMTiles requests, the application must register the custom protocol handler. The registerPMTilesProtocol function in src/config/basemap.ts configures MapLibre GL to route pmtiles:// URLs through the standard fetch pipeline, making them visible to the service worker's caching rules.

// src/config/basemap.ts
import { registerPMTilesProtocol } from '@/config/basemap';

// Called before map instantiation
registerPMTilesProtocol();

When the map requests vector tiles through this protocol, the URLs match the service worker's urlPattern and the tile ranges are stored in pmtiles-ranges.

Verifying Offline Behavior

To test the offline capabilities manually, enable the "Offline" toggle in your browser's Developer Tools under Application → Service Workers. Refresh the page—the UI including the map should still render, and network requests for *.pmtiles will show (from ServiceWorker) in the response column.

Summary

  • NetworkFirst caching for .pmtiles files and CDN endpoints stores vector tile ranges in the pmtiles-ranges cache, enabling offline map rendering after the initial network fetch.
  • Storage limits cap the tile cache at 500 entries with a 30-day expiration, managed automatically by Workbox to prevent excessive disk usage.
  • Precached static assets including JavaScript, CSS, and fonts ensure the map UI framework loads without network connectivity.
  • Stale-while-revalidate strategies keep map icons and typography available offline while updating in the background when connections resume.
  • Protocol registration is required in src/config/basemap.ts for the service worker to intercept and cache PMTiles requests properly.

Frequently Asked Questions

How does WorldMonitor handle map tiles when the user goes offline?

The service worker serves previously cached PMTiles ranges from the pmtiles-ranges cache using a NetworkFirst strategy. After the first successful fetch, tile data persists locally for 30 days, allowing the map to render geographic features without an active connection.

What is the storage limit for offline map tiles?

The configuration restricts the pmtiles-ranges cache to 500 entries and a 30-day maximum age. Older or excess entries are automatically purged by the Workbox expiration plugin to prevent excessive disk usage on user devices.

Does the offline functionality work for all map providers or only PMTiles?

According to the vite.config.ts source code, the offline caching specifically targets PMTiles archives (.pmtiles files) and their CDN endpoints (*.r2.dev, build.protomaps.com). The service worker configuration explicitly filters for these URL patterns, meaning offline capabilities are optimized for the PMTiles provider implementation.

How do I verify that the service worker is caching tiles correctly?

Open your browser's Developer Tools, navigate to the Application panel, and enable the "Offline" toggle in the Service Workers section. Refresh the page and inspect the Network tab—requests for .pmtiles resources should show (from ServiceWorker) in the size column, confirming cached responses are being served instead of network requests.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →