Web push-notifikationer: sådan virker de, og sådan bruger du dem rigtigt
Sådan fungerer web push-notifikationer, fra service workers og VAPID til reel browserunderstøttelse inklusive iOS, plus den tilladelses-UX og de målinger, der afgør resultatet.
Web push-notifikationer er den eneste markedsføringskanal, hvor én dårlig designbeslutning kan lukke dig permanent ude fra en kunde. Bed om tilladelse på det forkerte tidspunkt, den besøgende klikker Bloker, og den browser er lukket for dig for altid. Ingen ny prompt, ingen ny kampagne, ingen tilbagevindingsmail. Den skævhed er grunden til, at mekanikken er værd at forstå, før du skriver en eneste besked.
Hvad web push-notifikationer er
En web push-notifikation er en besked sendt fra din server til en modtagers browser, vist af operativsystemets notifikationscenter og leveret, selv når dit site er lukket. Den sidste del er hele pointen: i modsætning til en popup på siden når web push en person, der lige nu ikke kigger på dit website.
Den er bygget af tre webplatforms-API’er, der arbejder sammen, og opdelingen mellem dem forklarer det meste af kanalens adfærd: Service Worker API, Push API og Notifications API.
Sådan fungerer web push under motorhjelmen
Service workeren
En service worker er en JavaScript-worker, der fungerer som proxy mellem din webapp, browseren og netværket. Den kører på sin egen tråd, har ingen adgang til DOM’en og bliver ved med at eksistere, efter at siden, der registrerede den, er lukket. Netop den vedholdenhed er det, der gør, at den kan modtage en push-besked og vise en notifikation, når ingen har din fane åben. Service workers kører kun i sikre kontekster, hvilket betyder HTTPS, hvor http://localhost behandles som sikkert til udvikling.
Abonnementet: et endpoint plus to nøgler
Når en service worker er aktiv, kalder siden registration.pushManager.subscribe(). Browseren taler med sin leverandørs push-tjeneste og returnerer et PushSubscription, der indeholder:
endpoint, en unik URL, som push-tjenesten modtager beskeder påkeys.p256dh, en offentlig Elliptic Curve Diffie-Hellman-nøgle på P-256-kurvenkeys.auth, en autentificeringshemmelighed
Din server gemmer alle tre og behandler endpointet som en hemmelighed, for enhver, der har det, kan sende til den modtager. Nøglerne findes, fordi payloads er krypteret hele vejen. RFC 8291 beskriver hvordan: en ECDH-udveksling på P-256 etablerer en delt hemmelighed, HKDF udleder nøgler fra den, og payloaden forsegles med AES-128-GCM under indholdskodningen aes128gcm. Push-tjenesten videresender ciffertekst, den ikke kan læse.
Push-tjenesten
Du sender ikke push-beskeder direkte til en enhed. Du sender dem til en push-tjeneste, som browserleverandøren driver: Googles FCM-endpoints til Chrome, Mozillas autopush til Firefox, Apples push-tjeneste til Safari. RFC 8030, “Generic Event Delivery Using HTTP Push”, definerer protokollen. Din server sender POST til abonnementets endpoint, og push-tjenesten klarer de svære dele af levering til mobil: én batterivenlig forbindelse til enheden, kø mens enheden er offline, og opvækning af browseren når en besked ankommer. Det er også derfor, levering ikke kan garanteres. Er enheden slukket længe nok, udløber beskederne efter deres TTL og kasseres.
VAPID: at bevise hvem der sender
At endpointet er en hemmelighed er tynd sikkerhed. RFC 8292 tilføjer Voluntary Application Server Identification, eller VAPID, så en push-tjeneste kan afgøre, hvilken applikationsserver en besked kom fra.
Du genererer et ECDSA-nøglepar på NIST P-256-kurven én gang. Den offentlige nøgle lægges i applicationServerKey, når browseren tilmelder sig, og binder dermed abonnementet til din server. For hver push sender din server en JWT signeret med den tilhørende private nøgle via ES256, med et aud-claim for push-tjenestens domæne, et exp-claim højst 24 timer ude i fremtiden og eventuelt et sub-claim med kontaktoplysninger. Push-tjenesten verificerer signaturen, så et stjålet endpoint alene ikke længere er nok til at spamme dine modtagere.
Leveringsvejen fra ende til anden
- Siden registrerer en service worker og kalder, efter at tilladelsen er givet,
subscribe()med din offentlige VAPID-nøgle. - Din server gemmer det returnerede endpoint og nøglerne på modtagerens post.
- For at sende krypterer din server payloaden med
p256dhogauth, signerer en VAPID-JWT og sender POST til endpointet. - Push-tjenesten autentificerer forespørgslen og leverer den krypterede besked.
- Browseren vækker service workeren med en
push-begivenhed, som dekrypterer payloaden og kalderServiceWorkerRegistration.showNotification(). - Et klik udløser
notificationclicki service workeren, hvor du åbner destinations-URL’en.
Hvorfor tilladelsesmodellen er så stram
Se på, hvad et abonnement giver adgang til: en baggrundsproces, der kører uden at dit site er åbent, plus muligheden for at tegne på operativsystemets notifikationsflade. Derfor spærrer browsere det bag en udtrykkelig tilladelse pr. domæne givet af brugeren, og de fleste kræver, at anmodningen følger en ægte handling fra brugeren.
En anden begrænsning overrasker folk. Chrome og Edge kræver userVisibleOnly: true ved subscribe, altså et løfte om, at hver push resulterer i en notifikation, brugeren kan se, så tavse baggrundspush er ikke en understøttet brug af API’et. Firefox anvender også en kvote på push-beskeder, der ikke genererer en notifikation.
Understøttelse i browsere og på platforme
Ifølge MDN har Push API været Baseline widely available siden marts 2023, hvilket betyder, at det virker på tværs af aktuelle versioner af Chrome, Edge, Firefox og Safari på computer samt på Chrome og Firefox til Android. To forbehold betyder mere end overskriften.
For det første er Notifications API ikke ensartet tilgængeligt. MDN markerer det som limited availability, fordi Notification()-konstruktøren kaster en TypeError i de fleste mobilbrowsere. Til alt, der skal virke på telefoner, skal du bruge vedvarende notifikationer via ServiceWorkerRegistration.showNotification(), hvilket alligevel er den service worker-vej, du er på.
For det andet er notifikationsindstillinger implementeret ujævnt. Handlingsknapper, badges, billeder og requireInteraction varierer på tværs af browsere og operativsystemer, så design notifikationer, der stadig kan læses med kun en titel, en brødtekst og et ikon.
Kravet på iOS og iPadOS
Dette forbehold afgør, om web push overhovedet er brugbart for en mobiltung målgruppe, og det bliver gengivet forkert næsten alle steder.
Apple tilføjede Web Push i iOS og iPadOS 16.4, og det virker kun for webapps, der er lagt på hjemmeskærmen. Som WebKit formulerede det: “vi tilføjer understøttelse af Web Push til webapps på hjemmeskærmen”, og “en webapp, der er lagt på hjemmeskærmen, kan bede om tilladelse til at modtage push-notifikationer”. Brugeren lægger den på via Del-menuen og “Føj til hjemmeskærm”, og tilladelsen skal derefter anmodes som svar på en direkte handling fra brugeren, for eksempel et tryk på en tilmeldingsknap.
Et site, der er åbent i en almindelig Safari-fane på iPhone, kan ikke oprette et push-abonnement. Det er en reel barriere: du beder om et installationstrin, før du overhovedet må spørge om tilladelse. På macOS er det lettere, fordi Safari 16.1 på macOS Ventura tilføjede standardbaseret Web Push til almindelige websites uden installationstrin.
Et minimalt eksempel på tilmelding
Dette er hele flowet på klientsiden. Det hører hjemme i en klik-handler, ikke ved sideindlæsning.
async function subscribeToPush(vapidPublicKey) { // Push og service workers kræver en sikker kontekst (HTTPS). if (!("serviceWorker" in navigator) || !("PushManager" in window)) return null;
const registration = await navigator.serviceWorker.register("/sw.js");
// Skal kaldes fra en brugerhandling, og kun én gang pr. bruger. const permission = await Notification.requestPermission(); if (permission !== "granted") return null;
const subscription = await registration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: vapidPublicKey, // base64url-kodet offentlig P-256-nøgle });
// Gem endpoint + nøgler på serveren, og behandl endpointet som en hemmelighed. await fetch("/api/push/subscribe", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(subscription), });
return subscription;}Inde i sw.js håndterer du push-begivenheden, kalder self.registration.showNotification(title, options) og håndterer notificationclick for at åbne destinations-URL’en.
Tilladelses-UX: der hvor de fleste programmer fejler
Spørg aldrig ved sideindlæsning
Lighthouse har en dedikeret test for netop det: “hvis din side beder om tilladelse til at sende notifikationer ved sideindlæsning, er de notifikationer måske ikke relevante for dine brugere eller deres behov”. Anbefalingen er at tilbyde en bestemt type notifikation og først bede om tilladelse, når brugeren har valgt den type til. Safari 12.1 og andre browsere gik videre og kræver interaktion med siden, før en anmodning overhovedet kan sendes.
Brug en blød forhåndsprompt
Vis din egen invitation på siden først. Den nævner værdien, den kan lukkes uden varig omkostning, og kun et klik på den udløser browserens rigtige prompt. En, der ignorerer din bløde prompt i dag, kan spørges igen næste måned. En, der klikker Bloker, kan ikke. To regler får det til at virke: beskriv hvad du faktisk vil sende i stedet for “få opdateringer”, og lok aldrig nogen til et klik ved en fejl, for en utilsigtet accept giver en øjeblikkelig framelding.
Spørg i den rette kontekst
Chromes egen anbefaling er at “lade dine brugere tage initiativet og slå notifikationer til i deres eget tempo” ved at placere kontakter diskret i eksisterende flader i grænsefladen, og at undgå “at vise prompts eller overlays uden kontekst eller lige efter, at en bruger lander på sitet”.
De øjeblikke, der virker i handel, er meget konkrete: en “giv mig besked, når den er på lager igen” på et udsolgt produkt, en ordrebekræftelsesside der tilbyder leveringsopdateringer, en prisovervågning på et produkt, som kunden ser på ofte. Tilladelsen byttes for en navngiven fordel frem for at blive høstet.
En afvisning er reelt permanent
Når nogen blokerer notifikationer, gemmer browseren den beslutning for dit domæne. Senere kald til Notification.requestPermission() afgøres ud fra den gemte værdi denied uden at vise noget, hvilket er grunden til, at MDN’s eget eksempel tjekker Notification.permission, før det overhovedet kalder requestPermission(). At omgøre en blokering kræver, at man graver i site-indstillinger, og det gør reelt ingen.
Hvad browserne gør, når du gør det forkert
Konsekvenserne er ikke længere kun en lav tilmeldingsrate.
- Chrome tilmelder automatisk domæner med meget lave acceptrater til en mere stilfærdig tilladelses-UI, opdelt efter enhedstype, hvilket dæmper prompten for alle.
- Chrome rate limiter sites, der kombinerer høj push-volumen med lavt engagement, og returnerer HTTP 429. Optrapningen løber én dag, så syv, så fjorten, og nulstilles først efter 42 sammenhængende dage uden forstyrrelser.
- Chrome fjerner nu automatisk notifikationstilladelsen for sites, en bruger ikke har interageret med for nylig, hvor der er “meget lavt brugerengagement og en høj mængde notifikationer, der sendes”. Googles begrundelse er kontant: “Under 1 % af alle notifikationer får nogen som helst interaktion fra brugerne.”
Du kan miste modtagere, du allerede havde tjent ind, alene ved at sende dårligt.
Web push sammenlignet med e-mail og SMS
| Faktor | Web push | SMS | |
|---|---|---|---|
| Rækkevidde | Kun browsere, der har sagt ja | Alle med adressen | Alle med nummeret |
| Marginal omkostning | Reelt nul | Meget lav | Pr. besked, den højeste |
| Hastighed | Sekunder, vist af styresystemet | Minutter til dage, begravet i en indbakke | Sekunder |
| Beskedlængde | En titel og en kort tekst | Ubegrænset, rig formatering | Cirka 160 tegn pr. segment |
| Samtykke | Browserprompt, ét klik | Indsamling af adresse, helst dobbelt opt-in | Udtrykkeligt og stramt reguleret |
| Identitet | En browser på én enhed | Et menneske | Et menneske |
| Flytbarhed | Ingen | Fuld eksport | Fuld eksport |
Forskellen i ejerskab, der ændrer strategien
Et push-abonnement er en URL bundet til én browserprofil på én enhed. Det er ikke et menneske. Den samme kunde, der bruger Chrome på en bærbar og Firefox på en telefon, er to urelaterede abonnementer, og du kan ikke vide, at det er samme menneske, medmindre de identificerer sig selv.
Det kan heller ikke flyttes. Du kan eksportere en e-mailliste og lægge den ind i en anden platform i morgen. Du kan ikke flytte push-abonnementer mellem leverandører, fordi nøglerne og VAPID-bindingen blev oprettet mod en bestemt applikationsservernøgle.
Behandl derfor web push som en accelerator på en kanal, du selv ejer, aldrig som en erstatning. Brug push-øjeblikket til at tjene en e-mailadresse eller et telefonnummer, ikke omvendt. Den komplette guide til marketingautomatisering dækker, hvordan du kobler flere kanaler sammen i én rejse.
Anvendelser, der virkelig virker
Kanalen belønner beskeder, der er tidsfølsomme, personligt relevante og kan handles på med ét tryk.
- Forladt kurv. En push inden for en time, fulgt op af en e-mail senere. Guiden til e-mails om forladt kurv dækker rækkefølgen.
- Besked når varen er på lager igen. Det stærkeste tilfælde, fordi brugeren udtrykkeligt har bedt om at få besked.
- Prisfald på overvågede varer. Samme logik, selvvalgt relevans.
- Levering og ordrestatus. Høj hensigt om at åbne, lav risiko for klager.
- Vigtige opdateringer i et emne, kunden følger. Nyheder, resultater, tidsvinduer.
Det, der fejler, er lige så tydeligt: generiske “vi har udgivet et nyt indlæg”-udsendelser, ensartede daglige tilbud, alt der kræver mere end en titel og en linje, genaktiveringsudsendelser til modtagere, der har ignoreret de sidste tyve notifikationer, og transaktionelt indhold, der kræver en varig registrering.
Frekvens, timing og segmentering
Start konservativt: en til tre notifikationer pr. modtager om ugen, og udvid kun, hvis frameldinger og klikrater holder. Trætheden viser sig hurtigere end i e-mail, fordi det koster ét tryk at slå lyden fra på en notifikation, styresystemet allerede har vist.
Timing er både en fordel og en fare. Push ankommer med det samme, så en besked sendt klokken 02.00 ankommer klokken 02.00. Gem eller udled modtagerens tidszone ved tilmelding, og hold afsendelser inden for et defineret vindue.
Segmentering er begrænset af det, du ved om et abonnement frem for om et menneske, så de brugbare dimensioner er adfærdsmæssige: viste sider, overvågede produkter, kurvens tilstand, hvor længe siden købet er, og platform. Guiden til kundesegmentering går dybere.
Sådan måler du web push
Fire målinger betyder noget, og de kan ikke alle måles på samme måde.
- Levering. Om push-tjenesten accepterede forespørgslen. En 201 betyder accepteret, ikke leveret. En 404 eller 410 betyder, at abonnementet er dødt.
- Visning. Om notifikationen blev vist. Det ved du kun, hvis service workeren melder tilbage, når
showNotification()er færdig. - Klikrate. Klik divideret med visninger. Det er tallet, der er værd at optimere.
- Frameldingsrate. Frameldinger og tilbagetrukne tilladelser pr. afsendelse. Hold øje med den tættere end klikraten, fordi den er den tidlige indikator på, at kanalen er ved at dø.
Faldgruber i attribution
Push-attribution smigrer sig selv. Notifikationen ankommer på en enhed, modtageren allerede har i hånden, så den tager ofte æren for et besøg, der ville være sket alligevel. Kør holdout-grupper i stedet for at antage inkrementalitet. Visninger tælles for lavt, mens hvert klik registreres, så en klikrate beregnet mod afsendelser overdriver præstationen. Og fordi et abonnement er en browser og ikke et menneske, ligner en push, der klikkes på en telefon og ender i et køb på en computer, to urelaterede begivenheder. Guiden til målinger i e-mailmarkedsføring dækker hygiejnen omkring måling på tværs af kanaler.
Samtykke, GDPR og framelding
Browserens tilladelsesprompt er en teknisk port. Den er ikke automatisk et fuldgyldigt retsgrundlag for markedsføring.
Markedsfører du til folk i EU eller Storbritannien, så behandl push, som du behandler e-mail. Forklar hvad du vil sende, før prompten vises, så samtykket er informeret og specifikt. Registrér hvornår og hvor abonnementet blev oprettet, og bundt aldrig push-samtykke sammen med en urelateret handling. Kobler du abonnementer til identificerede kunder, ligger de data inden for dine forpligtelser om persondata, herunder anmodninger om sletning.
Hygiejnen omkring framelding betyder lige så meget. Tilbyd en indstilling på sitet, så folk kan skrue ned for frekvensen i stedet for at blokere, kald PushSubscription.unsubscribe() og slet posten på serveren, når de gør det, og ryd abonnementer ud ved en 404 eller 410. MDN’s vejledning er kort og rigtig: brugere bør “tilbydes en nem måde at framelde sig flere beskeder i fremtiden”.
Hvor web push hører hjemme i din kanalstak
Web push er en god tredje kanal og en dårlig første: hurtig, gratis på marginen og uovertruffen til tidskritiske beskeder, men bundet til enheden, umulig at eksportere og ét klik fra permanent tab.
Det gør orkestrering til det egentlige problem. Hvilken besked går til hvilken kanal, hvordan du undertrykker e-mailen, når pushen allerede konverterede, og hvordan du holder ét billede af kunden på tværs af flader, der identificerer folk forskelligt. Brevo tilbyder web og mobil push ved siden af e-mail og SMS, og Tajo ligger oven på Brevo og koordinerer den logik på tværs af kanaler for Shopify-butikker. For SMS-siden, se guiden til SMS-automatisering.
Det vigtigste at tage med
- Web push er tre API’er, der samarbejder: en service worker til afvikling i baggrunden, Push API til abonnement og transport, Notifications API til visning. Et abonnement er et endpoint plus en
p256dh-nøgle og enauth-hemmelighed, payloads er krypteret hele vejen, og VAPID beviser afsenderen. - Push har været Baseline widely available siden marts 2023, men på iOS og iPadOS virker det kun for webapps, der er lagt på hjemmeskærmen.
- Bed aldrig om tilladelse ved sideindlæsning. Brug en blød forhåndsprompt, spørg i den rette kontekst, og husk at en blokering er permanent for det domæne.
- Chrome håndhæver nu stilfærdige prompts, rate limits og automatisk fjernelse af tilladelser, så dårlig afsendelse koster dig modtagere, du allerede har.
- Et abonnement er en browser, ikke et menneske, og kan ikke eksporteres. Byg e-maillisten først, og brug push til at accelerere den.