Service Worker für Shopify: Ein praktischer Guide

Zuletzt aktualisiert
•
Von Experten geprüft
•
5 Min. Lesezeit

Die wichtigsten Erkenntnisse

  • Service Worker auf Shopify werden durch ihren Scope blockiert. Ein Service Worker kann nur das Verzeichnis kontrollieren, aus dem er ausgeliefert wird, und Shopify liefert Theme-Assets unter /cdn/shop/t/<id>/assets/ aus, nicht im Root-Verzeichnis deines Shops.
  • Der Header, der den Scope erweitert (Service-Worker-Allowed), steht auf Shopifys dokumentierter Liste von Headern, die aus App-Proxy-Antworten entfernt werden, der Standard-Proxy-Workaround gibt dir also keine Root-Kontrolle.
  • Der Checkout läuft auf deiner Shop-Domain, ein Root-scoped Service Worker würde sich also vor die Zahlungsseiten schieben. Diese Grenze solltest du nicht überschreiten.
  • Ein schlechter Service Worker ist fast nicht mehr zu entfernen. Er lebt auf dem Gerät deiner Kunden, liefert weiterhin veraltete Seiten aus und nur ein selbstzerstörender Ersatz unter derselben URL kann ihn löschen.
  • Die meisten Shopify-Shops sollten das nicht tun. Fixes bei Bildern, Skripten und auf Theme-Ebene bringen den gleichen Geschwindigkeitsvorteil, ohne diese Fehlerquellen.

Service Worker auf Shopify sind immer dann ein Thema, wenn jemand über Offline-First-Websites, Precaching oder Web Push liest und sich fragt, warum sein eigener Shop das nicht kann. Die kurze Antwort lautet: Das Hosting-Modell von Shopify setzt ein hartes Limit dafür, von wo du die Worker-Datei ausliefern kannst, und dieses Limit entscheidet über fast alles andere.

Warum du uns vertrauen kannst

Wir sind seit über vier Jahren im Shopify-Umfeld tätig und haben mit hunderten von Shopify-Brands an ihren Storefronts gearbeitet. Jacques hat über 15 Jahre Entwicklungserfahrung. Wir entwickeln Fudge, den KI-Operator für Shopify-Shops, mit einer 4.9 Bewertung im Shopify App Store und “Built for Shopify”-Status. Wir arbeiten also jeden Tag in der Theme-Ebene und sehen, was die Plattform tatsächlich zulässt.


Was ist ein Service Worker?

Ein Service Worker ist eine JavaScript-Datei, die der Browser im Hintergrund ausführt, getrennt von jeder Seite. Sobald er installiert ist, sitzt er zwischen der Website und dem Netzwerk und kann Anfragen aus einem Cache statt vom Server beantworten.

Es ist kein Script-Tag. Er hat keinen DOM-Zugriff, überlebt Seitenwechsel und läuft weiter, nachdem der Tab geschlossen wurde. Diese Unabhängigkeit macht ihn so nützlich – und gleichzeitig so gefährlich.

Der Lifecycle

Vier Phasen sind entscheidend. Werden sie falsch umgesetzt, liefern Shops veraltete Inhalte an die Kunden aus.

PhaseWas passiertDie Falle
InstallFeuert einmal pro Worker-Version. Hier werden normalerweise Dateien geprecachtSchlägt die Installation fehl, übernimmt der Worker nie
WaitingEin neuer Worker bleibt im Leerlauf, bis jeder Tab mit der alten Version geschlossen wirdKunden können tagelang mit dem Worker von letzter Woche surfen
ActivateDer alte Worker ist weg. Der richtige Ort, um alte Caches zu löschenWird das Aufräumen übersprungen, bleiben verwaiste Caches auf dem Gerät
FetchDer Worker fängt Anfragen ab, die er sehen darfEine falsche Regel hier macht den Shop stillschweigend kaputt

Zwei Details bereiten vielen Probleme.

Der erste Seitenaufruf wird nie kontrolliert. Eine Seite muss von einem kontrollierenden Worker geladen werden, bevor dieser Worker ihre Anfragen sieht. Registrierst du ihn auf der ersten Seite, beginnt das Caching erst auf Seite zwei.1

Updates werden geprüft, nicht gepusht. Der Browser ruft das Worker-Skript bei Navigationen und funktionalen Events erneut ab und überspringt diesen Check nicht länger als 24 Stunden. Die meisten Browser ignorieren deine Caching-Header für das Skript selbst. Dennoch kannst du ein Update nicht auf ein Gerät zwingen, das die Seite nie wieder besucht.1

Mit skipWaiting() und clients.claim() lässt sich die Waiting-Phase abkürzen, auf Kosten der Ausführung neuen Worker-Codes auf Seiten, die von der alten Version gerendert wurden.


Die Shopify-Einschränkung: Scope

Hier ist das ganze Problem in einer einzigen Regel: Ein Service Worker kann nur URLs auf oder unterhalb des Pfades kontrollieren, von dem er ausgeliefert wird. Ein Worker unter /sw.js kontrolliert die gesamte Website. Ein Worker unter /assets/sw.js kontrolliert /assets/ und sonst nichts. Das Skript muss außerdem “Same-Origin” mit der Seite sein, sonst wirft die Registrierung einen SecurityError.2

Es gibt in der Spezifikation ein Schlupfloch: Der Server kann einen Service-Worker-Allowed Response-Header auf dem Worker-Skript mitsenden, um den maximalen Scope zu erweitern.2 Behalte diesen Gedanken im Hinterkopf.

Schauen wir uns nun an, wo Shopify deine Dateien ablegt.

Theme-Assets sind Same-Origin, aber tief verschachtelt. Shopify liefert Storefront-Theme-Assets über die eigene Domain des Shops unter einem Pfad wie /cdn/shop/t/4159/assets/theme.js aus. Das kannst du überprüfen, indem du dir den Quellcode eines beliebigen Live-Shops ansiehst.3 Same-Origin ist eine gute Nachricht. Der Pfad ist es nicht. Ein in den assets-Ordner deines Themes hochgeladener Worker erhält den Scope /cdn/shop/t/4159/assets/, was bedeutet, dass er zwar deine Theme-Dateien kontrolliert, aber überhaupt keine Shop-Seiten.

Inhalt > Dateien ist nicht besser. In einem Live-Online-Store werden Dateien, die dort hochgeladen werden, über die Shop-Domain unter /cdn/shop/files/ ausgeliefert (die URL, die der file_url-Filter zurückgibt). Im besten Fall registriert sich ein Worker also mit einem /cdn/shop/files/-Scope, der keine Shop-Seiten kontrolliert – die gleiche Sackgasse wie der Assets-Ordner. Dieselbe Datei ist auch über cdn.shopify.com erreichbar, aber eine Registrierung von dieser URL schlägt direkt mit einem SecurityError fehl, da es sich um eine andere Origin handelt.

Das Store-Root gehört nicht dir. Frag /sw.js bei irgendeinem Shopify-Shop an und du bekommst einen 404er. Der Online Store lässt Händler keine beliebigen Dateien im Root-Verzeichnis der Domain ablegen. robots.txt.liquid ist eine der wenigen Ausnahmen, und sie erzeugt nur robots.txt.

Und du kannst den Header nicht hinzufügen. Das CDN von Shopify liefert Theme-Assets mit einem langen Cache-Control und ohne Service-Worker-Allowed aus. Du hast keine Möglichkeit, die Response-Header von Dateien zu ändern, die Shopify ausliefert.

Die Scope-Regel in Kombination mit Shopifys Datei-Hosting bedeutet, dass der klassische Root-scoped Service Worker im Online Store schlichtweg nicht verfügbar ist.


Welche Workarounds funktionieren wirklich?

Hier liegen die meisten Artikel zu diesem Thema falsch, meist indem sie Ratschläge wiederholen, deren Türen Shopify schon vor Jahren geschlossen hat. Hier ist der ehrliche Stand der jeweiligen Wege.

RouteFunktioniert das?Realität
sw.js in den Assets-Ordner des Themes hochladenRegistriert sich, ist aber nutzlosScope ist auf das Theme-Asset-Verzeichnis beschränkt
Unter Inhalt > Dateien hochladenRegistriert sich, ist aber nutzlosScope ist auf /cdn/shop/files/ beschränkt
sw.js ins Domain-Root legenNeinDer Online Store bietet kein Root-Datei-Hosting
App Proxy plus Service-Worker-Allowed: /NeinShopify entfernt genau diesen Header
App Proxy, auf den Proxy-Unterpfad beschränktJa, knappEchter Scope, aber nur über /apps/your-path/
Reverse Proxy vor dem ShopTechnisch ja, aber nicht unterstütztShopify unterstützt das Proxying deiner Domain nicht
Headless Storefront, die du selbst hostestJaDir gehört das Root-Verzeichnis, also gehört dir der Scope

Warum die App-Proxy-Route für den Root-Scope tot ist

Ein App Proxy ordnet einen Storefront-Pfad wie /apps/your-path einem von dir betriebenen Server zu. Präfixe sind auf apps, a, community oder tools beschränkt, der Mount Point ist also nie das Root-Verzeichnis.4

Du könntest sw.js von deinem Proxy ausliefern und Service-Worker-Allowed: / mitsenden, um den Scope zu erweitern. Shopify blockiert das. Die App-Proxy-Dokumentation listet die Response-Header auf, die Shopify aus Sicherheitsgründen entfernt, und Service-Worker-Allowed steht neben Set-Cookie, Server und X-Powered-By auf dieser Liste.4

Das war eine bewusste Änderung. Händler und App-Entwickler berichten seit 2021, dass der Header entfernt wird. Root Service Worker sind kein Versehen, um das du herumdiskutieren könntest.

Was immer noch funktioniert, ist ein Service Worker, der im Proxy-Unterpfad registriert ist und /apps/your-path/ kontrolliert. Es wird kein spezieller Header benötigt, da sich dieser Scope bereits auf oder unterhalb des Speicherorts des Skripts befindet. Er kann zwar keine Produktseiten cachen, aber Push-Nachrichten empfangen, worauf wir weiter unten noch zurückkommen.

Warum die Reverse-Proxy-Route eine schlechte Idee ist

Du kannst im Prinzip ein CDN oder einen Edge Worker vor deine Domain setzen und /sw.js selbst ausliefern. Die eigene Dokumentation von Shopify zur Domain-Fehlerbehebung besagt jedoch, dass Setups wie Cloudflare DNS-Proxying und Orange-to-Orange nicht unterstützt werden und warnt, dass diese kaputtgehen können, wenn sich auf einer der beiden Seiten etwas ändert.5 Einen nicht unterstützten Proxy vor einen Store zu schalten, um eine optionale Caching-Schicht zu aktivieren, ist ein schlechter Deal.

Headless ist die einzige saubere Antwort

Wenn du eine Custom Storefront betreibst, egal ob das Hydrogen auf Oxygen ist oder dein eigenes Frontend gegen die Storefront API, hast du die Kontrolle über den Server, der auf den Root-Pfad antwortet. Du kannst /sw.js mit beliebigen Headern ausliefern und mit dem Scope / registrieren. Jede Einschränkung in diesem Abschnitt bezieht sich auf das Hosting des Online Stores, nicht auf Shopify als Commerce-Backend.


Was kann ein Service Worker auf einem Shopify-Store realistischerweise tun?

Nimm für einen Moment an, du hättest das Scope-Problem gelöst. Es gibt vier Use Cases. Sie sind nicht alle gleichermaßen sinnvoll.

Caching von statischen Assets und Schriftarten. Der echte Mehrwert. Versionierte Theme-Assets und selbstgehostete Schriftarten sind unveränderlich, also ist eine Cache-First-Regel sicher und bietet wiederkehrenden Besuchern fast sofortige Ladezeiten. Der Haken ist, dass das CDN von Shopify Theme-Assets bereits mit einer einjährigen Cache-Control ausliefert, der HTTP-Cache des Browsers erledigt diese Arbeit also ohnehin schon. Der zusätzliche Gewinn ist kleiner, als es den Anschein hat.

Eine Offline-Fallback-Seite. Günstig und risikoarm. Statt der Fehlerseite des Browsers sieht ein Käufer, der sein Signal verliert, eine gebrandete Seite deines Shops. Sie verkauft nichts, aber es ist ein nettes Detail für das Nutzererlebnis.

Background Sync für ein Formular. Eine Offline-Newsletter-Anmeldung oder das Einreichen einer Bewertung wird erneut versucht, sobald die Verbindung wieder da ist. Nützlich in Märkten mit wirklich schlechter Verbindung, andernorts eher sinnlos. Der Support ist nicht in allen Browsern gegeben, betrachte es also als eine Zusatzfunktion, unter der ein normaler Submit-Pfad liegt.

Push-Benachrichtigungen. Eine Push-Subscription ist an die Registrierung des Service Workers geknüpft, nicht an seinen Scope. Ein Worker auf einem engen Pfad kann also immer noch Pushes empfangen. Die echten Hürden liegen woanders: Du brauchst einen Permission-Prompt, den die Käufer überwiegend ablehnen, iOS liefert Web-Pushes nur an Seiten aus, die der Nutzer zu seinem Home-Screen hinzugefügt hat, und die meisten Händler nutzen am Ende doch eine Push-App aus dem App Store, anstatt das selbst zu bauen. Schau dir das Live-Listing der Push-Apps auf ihre aktuellen Pläne an, bevor du dich festlegst.

Für das mobile Publikum, auf das diese Use Cases abzielen, liegen die echten Gewinne meist woanders. Schau dir unseren Guide zum Thema Shopify Mobile Speed an, für Änderungen, die die mobilen Zahlen wirklich verbessern.

Du möchtest Speed-Fixes auf Theme-Ebene ohne Risiko? Beschreibe sie Fudge.
Kostenlose Testversion starten

Der Code und seine Vorbehalte

Wenn du Headless unterwegs bist oder eine Staging-Umgebung hast, bei der dir der Root gehört, ist dies das absolut notwendige Paar an Dateien.

Registrierung

// In deinem Layout, nachdem die Seite vollständig geladen ist.
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker
            .register('/sw.js', {scope: '/'})
            .then((reg) => console.log('Service Worker Scope:', reg.scope))
            .catch((err) => console.error('Registrierung fehlgeschlagen:', err))
    })
}

Achtung: In einem normalen Online Store schlägt das fehl, da /sw.js einen 404-Fehler zurückgibt. Ein Request auf /sw.js über deine eigene Domain ist der schnellste Weg, das zu bestätigen, bevor du irgendetwas anderes programmierst. Wenn du das zusammen mit anderen Skripten hinzufügst, zeigt dir unser Guide zum Hinzufügen von Custom JavaScript in Shopify, wo Theme-Code hingehört.

Ein minimaler Fetch-Handler

Cache-First für versionierte Assets, Network-First für Dokumente und eine ausdrückliche Weigerung, transaktionale Prozesse anzutasten.

const VERSION = 'v1'
const ASSET_CACHE = `assets-${VERSION}`
const PAGE_CACHE = `pages-${VERSION}`

// Diese niemals abfangen. Warenkorb, Kundenkonto, Checkout und App-Routen bleiben live.
const NEVER_HANDLE = [/^\/checkouts?\//, /^\/cart/, /^\/account/, /^\/apps\//, /^\/wpm/]

self.addEventListener('install', (event) => {
    event.waitUntil(caches.open(PAGE_CACHE).then((c) => c.add('/offline')))
})

self.addEventListener('activate', (event) => {
    event.waitUntil(
        caches
            .keys()
            .then((keys) => Promise.all(keys.filter((k) => !k.endsWith(VERSION)).map((k) => caches.delete(k)))),
    )
})

self.addEventListener('fetch', (event) => {
    const req = event.request
    const url = new URL(req.url)

    if (req.method !== 'GET') return
    if (url.origin !== self.location.origin) return
    if (NEVER_HANDLE.some((re) => re.test(url.pathname))) return

    // Versionierte Theme-Assets sind unveränderlich, daher ist Cache-First sicher.
    if (url.pathname.startsWith('/cdn/shop/t/')) {
        event.respondWith(
            caches.match(req).then((hit) => {
                if (hit) return hit
                return fetch(req).then((res) => {
                    if (res.ok) {
                        const copy = res.clone()
                        caches.open(ASSET_CACHE).then((c) => c.put(req, copy))
                    }
                    return res
                })
            }),
        )
        return
    }

    // Dokumente gehen zuerst ans Netzwerk. Der Cache ist nur ein Offline-Fallback.
    if (req.mode === 'navigate') {
        event.respondWith(
            fetch(req)
                .then((res) => {
                    const copy = res.clone()
                    caches.open(PAGE_CACHE).then((c) => c.put(req, copy))
                    return res
                })
                .catch(() => caches.match(req).then((hit) => hit || caches.match('/offline'))),
        )
    }
})

Dinge, die du beachten musst (wichtiger als der Code):

  • NEVER_HANDLE ist das Sicherheitsgeländer. Warenkorb, Kundenkonto und Checkout-Pfade müssen immer den Server erreichen. Einen gecachten Warenkorb zurückzugeben, bedeutet ein Support-Ticket. Ein gecachter Checkout-Schritt ist noch schlimmer.
  • Niemals Cache-First für ein HTML-Dokument nutzen. Preise, Lagerbestand und Aktionen ändern sich. Eine gecachte Produktseite zeigt dem Käufer, der sich die Werbung von heute ansieht, den Preis von gestern.
  • Erhöhe die VERSION bei jeder Änderung. Der Activate-Handler verhindert, dass sich alte Caches auf den Geräten der Kunden ansammeln.
  • Teste mit einem echten Shop, nicht mit einem Template. Themes und Apps bringen eigene Fetch-Muster mit, und Shopify fügt Routen hinzu, die du nicht geschrieben hast.

Die Risiken im Klartext

Diesen Abschnitt solltest du zweimal lesen.

Veralteter Content wird an echte Käufer ausgeliefert. Der Fehlerfall ist nicht „die Website ist langsam“. Er besteht darin, dass ein Käufer ein ausverkauftes Produkt als verfügbar sieht oder einen Sale-Banner, der vor einer Woche ausgelaufen ist, weil sein Gerät eine gecachte Kopie lädt. In deinem eigenen Browser wirst du das nicht sehen.

Der Checkout liegt auf deiner Domain. Seit Shopify den Checkout von checkout.shopify.com wegbewegt hat, finden Checkouts auf der Shop-Domain statt, auf der der Kunde surft.6 Ein Worker mit Root-Scope würde also im Request-Pfad der Zahlungsseiten sitzen. Setze keinen Custom-Caching-Code vor den Checkout. Shopify riegelt den Checkout aus PCI-Gründen ab, was auch der Grund ist, warum Analytics über die Sandboxed Web Pixels API laufen muss, anstatt über beliebige Skripte. Betrachte diese Grenze hier als absolut.

Der Warenkorb-Status geht auf unvorhersehbare Weise kaputt. Warenkorb-Routen liefern JSON zurück, das sich bei jeder Interaktion ändert. Cache nur eine Antwort, und Add-to-Cart fängt an, über seinen Inhalt zu lügen.

Ein fehlerhafter Worker ist fast nicht mehr zu entfernen. Das ist das Risiko, das Service Worker von jedem anderen Frontend-Fehler unterscheidet. Der Worker verbleibt auf dem Gerät des Käufers. Du erreichst ihn nicht, du siehst ihn nicht, und ein Rollback deines Themes ändert daran gar nichts. Er liefert so lange aus, was er gecacht hat, bis genau dieser Browser einen Ersatz von exakt der URL abruft, unter der der Worker ursprünglich registriert wurde.

Die Asset-Pfade von Shopify machen das noch schlimmer. Das Segment /cdn/shop/t/<id>/ ist an das Theme gebunden. Veröffentlichst du ein anderes Theme, kann die Skript-URL des alten Workers plötzlich ins Leere laufen. Laut Spezifikation bricht ein fehlgeschlagener Update-Fetch das Update ab und lässt den existierenden Worker weiterlaufen – dein Kill-Switch hat also keinen Ort mehr, an dem er leben kann.

Du legst einen Cache über einen Cache. Shopify betreibt bereits ein Cloudflare-gestütztes CDN vor deiner Storefront und versioniert Asset-URLs automatisch.3 Ein handgeschriebener Cache obendrauf fügt ein zweites Invalidierungs-Problem hinzu, ohne das erste zu beseitigen. Wo die wirklichen Performance-Probleme liegen, erfährst du in unserem Beitrag Status der Shopify-Performance 2026.


Wie man einen fehlerhaften Service Worker entfernt

Wenn bereits einer live ist, arbeite diese Schritte der Reihe nach ab.

1. Überprüfen, was installiert ist

Öffne in den Chrome DevTools Application > Service Workers, um die Registrierung, den Scope und die Skript-URL zu sehen. Unter Application > Storage > Cache Storage siehst du, was gecacht wurde. Notiere dir die genaue Skript-URL. Alles Weitere hängt davon ab.

2. Einen selbstzerstörenden Worker ausliefern

Die einzige zuverlässige Entfernung ist es, die Worker-Datei unter genau derselben URL durch eine zu ersetzen, deren einzige Aufgabe es ist, sich selbst zu löschen.

self.addEventListener('install', () => self.skipWaiting())

self.addEventListener('activate', (event) => {
    event.waitUntil(
        (async () => {
            const keys = await caches.keys()
            await Promise.all(keys.map((key) => caches.delete(key)))
            await self.registration.unregister()
            const clients = await self.clients.matchAll({type: 'window'})
            clients.forEach((client) => client.navigate(client.url))
        })(),
    )
})

skipWaiting() aktiviert ihn sofort, der Activate-Handler leert alle Caches und meldet den Worker ab (unregister), anschließend lädt sich jeder offene Tab ohne Controller neu. Entferne auch den Registrierungsaufruf aus deinem Theme, damit er sich nicht erneut registriert.

Er wird nur beim nächsten Besuch des Kunden ausgeführt. Der Browser überprüft das Skript innerhalb von 24 Stunden nach der Aktivität, aber ein Gerät, das nie wiederkommt, behält den alten Worker für immer. Es gibt keinen serverseitigen Purge.

3. Verstehen, was Clear-Site-Data kann und was nicht

Der Response-Header Clear-Site-Data: "storage" entfernt Service Worker für den Origin.7 Es ist die saubere Lösung für eine Website, bei der du die Response-Header kontrollierst. Im Shopify Online Store hast du diese Kontrolle nicht, das steht also nur Headless-Storefronts zur Verfügung.

4. Für einen einzelnen Käufer

Der Support kann eine einzelne Person durch die DevTools via Application > Storage > Clear site data oder in ein privates Fenster leiten. Das ist eine Notfallmaßnahme bei Beschwerden, aber kein echter Fix.


Die meisten Stores sollten das nicht tun. Hier ist, was du stattdessen tun solltest.

Das Urteil ist eindeutig: Im Shopify Online Store ist ein nützlicher Service Worker innerhalb der Regeln der Plattform nicht machbar, und die Version, die machbar ist, ist das Risiko nicht wert. Der Scope sperrt dich in ein Verzeichnis ein, das nichts kontrolliert, der Header, der das Problem lösen würde, wird entfernt, und die Reverse-Proxy-Route wird nicht unterstützt. Wenn du trotzdem einen baust, bist du nur einen Fehler von veralteten Preisen entfernt, die du nicht mehr zurückholen kannst.

Bei Headless Storefronts sieht die Sache anders aus. Wenn dir das Root-Verzeichnis gehört, gelten die normalen Web-Regeln und der obige Code ist ein sinnvoller Startpunkt.

Für alle anderen auf dem Online Store bringt es mehr, die gleiche Mühe in das Theme zu stecken:

  • Wirf App-Skripte raus, die du nicht nutzt. Drittanbieter-JavaScript ist bei den meisten Shops der größte kontrollierbare Kostenfaktor, und ein Skript zu entfernen ist immer besser, als es zu cachen.
  • Optimiere zuerst die Bilder. Richtige Größen, moderne Formate und ein sofort geladenes Hero-Bild (eager loading). Unser Guide Bilder in Shopify per Lazy Load laden behandelt die Reihenfolge, auf die es ankommt.
  • Entferne Render-blockierende Ressourcen und verkleinere den Rest (minify). In Wie man CSS und JavaScript in Shopify verkleinert erfährst du, was Shopify bereits übernimmt und was nicht.
  • Schlanke das Theme selbst ab. Die komplette Abfolge findest du unter Wie man ein Shopify-Theme schneller macht.

Jeder dieser Schritte lässt sich im Admin-Bereich rückgängig machen. Keiner davon kann dazu führen, dass ein Kunde auf einer gecachten Kopie deines Shops festsitzt.

Diese Reversibilität ist der Grund, warum Fudge nativen Theme-Code schreibt, anstatt eine Runtime-Schicht zu injizieren. Änderungen landen als Liquid-, CSS- und JavaScript-Entwürfe in deinem Theme, sodass du sie lesen, genehmigen, zurückrollen und behalten kannst, nachdem du aufhörst, uns zu bezahlen. Bitte Fudge um ein Speed-Audit und es listet auf, was deine Seiten verlangsamt (z. B. ungenutzte App-Skripte und zu große Bilder), und entwirft dann die Fixes für dein Team zur Überprüfung. Das Gleiche gilt für alles andere, was du mit dem Shopify-Store-Editor baust.


FAQ

Kann man einen Service Worker auf Shopify nutzen?

Nicht sinnvoll im Standard-Online Store. Ein Service Worker kontrolliert nur das Verzeichnis, aus dem er ausgeliefert wird, und Shopify liefert Theme-Assets unter einem verschachtelten Pfad wie /cdn/shop/t/<id>/assets/ aus, ohne dass du eine Datei im Root-Verzeichnis ablegen kannst. Du kannst zwar einen registrieren, aber sein Scope deckt Theme-Dateien ab und nicht die Shop-Seiten. Bei selbst gehosteten Headless Storefronts gibt es dieses Limit nicht.

Warum schlägt die Registrierung meines Shopify Service Workers fehl?

Zwei Ursachen decken fast jeden Fall ab. Wenn du die Datei unter Inhalt > Dateien hochgeladen hast und sie von ihrer cdn.shopify.com URL lädst, ist das eine andere Origin, was einen SecurityError wirft; über die Shop-Domain-URL /cdn/shop/files/ registriert sie sich zwar, kontrolliert aber nur diesen Ordner. Wenn du einen Root-Pfad wie /sw.js angefragt hast, gibt es einen 404-Fehler zurück, da der Online Store keine Händler-Dateien im Root-Verzeichnis der Domain hostet.

Kann ein App Proxy auf Shopify einen Root-scoped Service Worker ausliefern?

Nein. Den Scope eines Workers zu erweitern, erfordert den Service-Worker-Allowed Response-Header, und Shopifys App-Proxy-Dokumentation führt diesen Header unter denen auf, die aus Sicherheitsgründen entfernt werden. Ein über den Proxy ausgelieferter Worker funktioniert weiterhin im Proxy-Unterpfad, sodass er Push-Nachrichten empfangen, aber keine Produkt- oder Kategorie-Seiten kontrollieren kann.

Wird ein Service Worker den Shopify-Checkout kaputt machen?

Das kann passieren. Der Checkout läuft auf deiner Shop-Domain anstatt auf checkout.shopify.com, daher würde ein Root-scoped Worker direkt im Request-Pfad für die Zahlungsseiten sitzen. Fange niemals Routen wie /checkouts/, /cart oder /account ab. Shopify hält den Checkout aus PCI-Gründen stark abgeriegelt und diese Grenze sollte als absolut angesehen werden.

Wie entferne ich einen Service Worker, der veraltete Inhalte ausliefert?

Ersetze die Worker-Datei unter genau derselben URL mit einer selbstzerstörenden Version, die beim Installieren skipWaiting aufruft, jeden Cache löscht, dann self.registration.unregister aufruft und alle offenen Tabs neu lädt. Entferne auch den Registrierungsaufruf aus deinem Theme. Dies greift erst beim nächsten Besuch jedes einzelnen Käufers, und es gibt keine Möglichkeit, dies serverseitig zu bereinigen.

Macht ein Service Worker einen Shopify-Shop schneller?

Weniger, als du erwarten würdest. Shopify liefert Theme-Assets bereits über ein Cloudflare-gestütztes CDN mit einer einjährigen Cache-Lebensdauer und automatischer Versionierung aus, sodass der Browser-HTTP-Cache die meisten Geschwindigkeitsvorteile bei wiederkehrenden Besuchen übernimmt. Ungenutzte App-Skripte rauszuschmeißen, Bildgrößen zu korrigieren und Render-blockierende Ressourcen zu entfernen, bringt mehr – und das ganz ohne Risiko veralteter Inhalte.

Brauche ich einen Service Worker für Web Push auf Shopify?

Web Push erfordert die Registrierung eines Service Workers, aber das Abonnement ist an die Registrierung und nicht an deren Scope gebunden, ein Worker in einem begrenzten App-Proxy-Pfad reicht also aus. Die härteren Grenzen sind die Berechtigungsanfrage (Permission Prompt), die die meisten Käufer ablehnen, und die Tatsache, dass iOS Web-Push-Nachrichten nur an Websites ausliefert, die zum Home-Bildschirm hinzugefügt wurden. Die meisten Händler nutzen ohnehin eine Push-App aus dem App Store, anstatt sie selbst zu bauen.

Jacques's signature
Bring Theme-Änderungen live, die du tatsächlich zurückrollen kannst.

Footnotes

  1. web.dev, “The service worker lifecycle” - behandelt install, waiting, activate, den unkontrollierten ersten Ladevorgang und die auf 24 Stunden begrenzten Update-Checks des Browsers. https://web.dev/articles/service-worker-lifecycle ↩ ↩2

  2. MDN, “ServiceWorkerContainer: register() method” - Standard-Scope, die maximal erlaubte Scope-Einschränkung, der Service-Worker-Allowed Header und der Same-Origin SecurityError. https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register ↩ ↩2

  3. Shopify Dev, “The Shopify platform” - Das CDN von Shopify wird von Cloudflare unterstützt, und einige Storefront-Assets werden über die Storefront-Domain unter /cdn statt über cdn.shopify.com ausgeliefert. https://shopify.dev/docs/storefronts/themes/best-practices/performance/platform ↩ ↩2

  4. Shopify Dev, “About app proxies and dynamic data” - listet die erlaubten Präfixe und die Response-Header auf, die Shopify entfernt (darunter auch Service-Worker-Allowed). https://shopify.dev/docs/apps/build/online-store/app-proxies ↩ ↩2

  5. Shopify Help Center, “Troubleshooting issues with domains” - Shopify unterstützt keine Setups wie Cloudflare DNS Proxying und Orange-to-Orange. https://help.shopify.com/en/manual/domains/troubleshoot-issues-with-domains ↩

  6. Shopify Dev Changelog, “Checkouts will occur at the shop domain instead of checkout.shopify.com”. https://shopify.dev/changelog/checkouts-will-occur-at-the-shop-domain-instead-of-checkout-shopify-com ↩

  7. MDN, “Clear-Site-Data” - die Direktive “storage” hebt die Registrierung von Service Workern für die Origin auf. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Clear-Site-Data ↩

You might also be interested in

Jacques Blom
Jacques Blom
CTO bei Fudge.