How to Turn a Shopify Hydrogen Storefront into a PWA: Service Workers, Offline Caching, and Web Manifest Setup

With mobile traffic driving over 70% of e-commerce visits, turning your headless Shopify storefront into a Progressive Web App (PWA) is one of the most effective ways to achieve app-like speed, offline fallback pages, and home-screen installability.

While standard Shopify Liquid themes have limited PWA support due to theme asset hosting constraints, Shopify Hydrogen (Remix) provides a native React environment where full PWA capabilities can be implemented.

Here is a technical overview of how to turn a Hydrogen storefront into a PWA, along with key architectural considerations.

1. The 3 Core Pillars of a Hydrogen PWA

  1. Web App Manifest (manifest.json): Tells mobile browsers how your storefront should look when saved to the home screen (theme color, background color, app icons, display mode).
  2. Service Worker Registration: Intercepts network requests to cache critical assets (CSS, JS bundles, fonts) and serve custom offline pages when a customer loses internet connection.
  3. Cache Storage API Management: Prevents stale cart or pricing data by isolating dynamic Storefront API queries from static asset caching.

2. Manual Implementation Pattern (Service Worker in Remix)

In Hydrogen, you can register a service worker inside your entry.client.tsx:

// app/entry.client.tsx
if ('serviceWorker' in navigator && process.env.NODE_ENV === 'production') {
  window.addEventListener('load', () => {
    navigator.serviceWorker
      .register('/sw.js')
      .then((reg) => console.log('PWA Service Worker registered:', reg.scope))
      .catch((err) => console.error('PWA Service Worker failed:', err));
  });
}

And define custom caching rules inside public/sw.js:

// public/sw.js
const CACHE_NAME = 'hydrogen-pwa-v1';
const OFFLINE_URL = '/offline';

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => cache.addAll([OFFLINE_URL, '/build/_assets/main.css']))
  );
});

self.addEventListener('fetch', (event) => {
  if (event.request.mode === 'navigate') {
    event.respondWith(
      fetch(event.request).catch(() => caches.match(OFFLINE_URL))
    );
  }
});

3. Simplifying PWA Configuration with Visual Tools

Setting up manifest files, icon generators, and service worker update cycles manually for every client project can become repetitive.

(Full disclosure: I’m part of the engineering team at Weaverse).

To streamline this workflow, we recently launched a native PWA feature inside the Weaverse Hydrogen Builder. It allows merchants and developers to configure PWA settings directly from a visual interface:

  • One-Click Web Manifest Generator: Customize app icons, launch titles, and theme colors without manually editing JSON configs.
  • Automated Offline Fallback: Configures a custom “No Connection” offline page served instantly by the service worker when connection drops.
  • Instant Add-to-HomeScreen Prompts: Enables native install prompts for mobile iOS and Android visitors.

Are you currently implementing PWA features on your Hydrogen builds? What service worker caching strategy have you found works best for handling dynamic cart states?

Hey @Weaverse ,

Thanks for sharing such a detailed overview.

I think one of the biggest considerations when implementing PWAs with Hydrogen isn’t just offline support it’s choosing the right caching strategy for dynamic commerce data.

For static assets like JavaScript bundles, CSS, fonts, and images, aggressive caching makes perfect sense. However, I’d be much more cautious with data that changes frequently, such as cart state, pricing, inventory and customer specific information. Serving stale data in those cases can create a confusing shopping experience.

A balanced approach is often to cache static assets aggressively while using network first or stale while revalidate strategies selectively for Storefront API responses, depending on how frequently the data changes and how critical freshness is.

The visual tooling you mentioned also seems like it could simplify the repetitive setup involved in configuring manifests, icons, and offline pages, especially for teams managing multiple Hydrogen projects.

It would be interesting to hear how other Hydrogen developers are balancing performance gains with data freshness, particularly around cart synchronization and inventory updates.

If you found my reply helpful, feel free to mark it as the accepted solution so it can help other merchants following this discussion.

Thank You !