Den anden besked fra groomingbrandet, vi kalder Kestrel, kom et par uger efter projektet med tilpassede sektioner. Det var et enkelt skærmbillede af en smykkebutiks produktside med en række kort under læg i kurv-knappen: Køb 1, få 1 gratis, vælg dit andet smykke. Spørgsmålet under var kort: kan vi få det på vores produktsider?
Et Shopify køb én, få én gratis-tilbud er nemt at slå til i admin. Det svære er at få kunderne til at bruge det. Dette casestudie viser, hvordan vi byggede vælgeren, hvorfor vi ikke kopierede referencebutikkens kode, og den ene Shopify-indstilling, der gør produkt nr. to gratis.
Om dette casestudie: det er en sammensat historie baseret på rigtigt Shopify-arbejde. Brandnavnet, produktfotos og visse detaljer er ændret, og produktbillederne er illustrationer. Kodemønstrene, problemerne og løsningerne er præcis, som vi håndterede dem.

Projektet kort fortalt
| Kunde | Direct-to-consumer groomingbrand til mænd, Holland (hollandsk butik, EUR) |
| Platform | Shopify Online Store 2.0, eksisterende premiumtema bevaret |
| Omfang | 1 snippet, 1 stylesheet, 1 script, 1 ny produktsideblok, ingen apps |
| Rabat | Shopifys indbyggede automatiske rabat (Køb X, få Y) |
| Levering | Installeret af butiksejeren i temaets kodeeditor, fil for fil |
Hvorfor en indbygget BOGO-rabat ikke er nok
Shopify har understøttet Køb X, få Y-rabatter i årevis. Opret en, og kurven anvender den, så snart de rigtige produkter ligger i den. Problemet ligger i ordene så snart. Kunden skal vide, at tilbuddet findes, forlade produktsiden, finde et produkt, der er med, lægge det i kurven og vende tilbage. De fleste gør det ikke. Et banner med “1+1 gratis” uden en måde at handle på giver mest e-mails om, hvorfor rabatten ikke virkede.
Referencebutikken havde løst det med en vælger: de relevante produkter vises lige der, hvor købsbeslutningen tages, ét tryk for at vælge, og hovedknappen skifter til Læg 2 produkter i kurven. Det var oplevelsen, Kestrel ville have.
Læs referencen, og læg den så væk
Butiksejeren sendte referencebutikkens CSS, JavaScript og HTML med. Det var omhyggeligt arbejde: omkring 400 linjer med bundark, et “se alle”-lag, registrering af baggrundsfarve på produktfotos og sit eget læg i kurv-kald. Det var også skrevet til et andet tema, en anden formular og en anden kurvskuffe, og det tilhørte en anden.
Så vi brugte det som en beskrivelse af adfærden, ikke som kode. Før vi skrev noget, læste vi produktformularen i Kestrels tema. Det blev projektets mest værdifulde time.
Opdagelsen: temaet kunne allerede lægge to produkter i kurven
Temaets product-form-element har en funktion til “købes ofte sammen”-afkrydsningsfelter. Ved indsendelse samler det alle afkrydsede input[name="bundles"] i et element, der er knyttet til formularen, og sender dem til /cart/add.js sammen med hovedproduktet. Det håndterer også kurvskuffen, kurvsiden, fejlbeskeder og den klæbende læg i kurv-knap.
Det betød, at vælgeren slet ikke behøvede sit eget kurvkald. Hvert kort indeholder et skjult afkrydsningsfelt med navnet bundles, og vælger-elementet bærer formularens id:
<bogo-picker form="{{ product_form_id }}">
<label class="bogo-card__btn">
<input type="checkbox" name="bundles" value="{{ variant.id }}" class="sr-only">
<span>Choose</span>
</label>
</bogo-picker>
Vælg et kort, og dets felt bliver afkrydset. Tryk på hovedknappen, og temaet lægger begge produkter i kurven i ét kald, åbner sin egen kurvskuffe og opdaterer antallet, præcis som for alle andre produkter. Vores JavaScript er omkring hundrede linjer, og intet af det rører kurven.

Detaljerne, der får det til at føles indbygget
- Ét gratis produkt ad gangen. Vælger man et kort, fravælges de andre, så ingen ved et uheld lægger tre gratis varer i kurven.
- En knap, der siger, hvad der sker. Når et kort er valgt, skifter knappen til “Læg 2 produkter i kurven”. Temaet nulstiller teksten, når varianten skifter, så en lille
MutationObserversætter den tilbage. - Varianter på kortet. Produkter med flere varianter får en kompakt rullemenu, og feltets værdi følger med.
- Ensartede kort. Kortene deler rækker via CSS subgrid, så navne, priser og knapper står på linje, selv når et navn fylder to linjer.
- Mobil først. På telefoner ses 2,3 kort, så det næste titter frem; på desktop vises tre kort med pileknapper.
- Ren nulstilling. Efter et vellykket køb lytter vælgeren til temaets
cartUpdate-hændelse og rydder valget.
Blokken tilføjes i temaeditoren som enhver anden produktsideblok. Butiksejeren vælger en kollektion med de relevante produkter eller et metafelt med en produktliste til produktspecifikke tilbud. Tekster som “Gratis”, “Vælg” og knapteksten er indstillinger. Det aktuelle produkt og udsolgte produkter udelades automatisk.
Sådan bliver produkt nr. to faktisk gratis
Vælgeren lægger kun to produkter i kurven. Prisen styres af Shopify via en automatisk rabat:
- Opret en kollektion med de produkter, der må gives væk, for eksempel “BOGO Gratis”.
- Under Rabatter opretter du en Køb X, få Y-rabat med metoden Automatisk.
- Kunden køber: mindst 1 fra en kollektion med alle betalte produkter.
- Kunden får: 1 fra “BOGO Gratis” til værdien Gratis.
- Sæt flueben i Angiv et maksimalt antal anvendelser pr. ordre og skriv 1, ellers giver tre køb tre gratis produkter.

Shopify har ingen “alle produkter”-mulighed i feltet Kunden køber, så der skal bruges en kollektion. En automatisk kollektion med betingelsen “pris er større end 0” holder sig selv opdateret. Ét særtilfælde er værd at kende: hvis gratisprodukterne også er med i den kollektion, giver køb af to varer fra “BOGO Gratis” den ene gratis. For de fleste butikker er det fint. Hvis ikke, så tag BOGO-produkterne og udelad tagget i kollektionens betingelser.

Installation uden at uploade et tema
Kestrels live-tema havde andet upubliceret arbejde i gang, så det var ikke en mulighed at uploade en ny temaversion. Vi leverede funktionen som fem præcise trin til temaets kodeeditor: tre nye filer (en snippet, et stylesheet og et script) og to små tilføjelser til produktsektionen, en render-linje og en blokdefinition i skemaet. Hvert trin sagde præcis, hvilken linje der skulle søges efter, og hvad der skulle indsættes over den. Fordi alle ændringer kun tilføjer, overlever de næste temaopdatering med få minutters arbejde.
Vi lavede også et enkelt miniaturebillede til kollektionen “BOGO Gratis”, så den ser færdig ud overalt, hvor temaet viser den.
Det vil vi sige til enhver butik, der overvejer BOGO
- Placér valget der, hvor beslutningen tages. Et tilbud, kunden selv skal samle, springer de fleste over.
- Læs dit tema, før du skriver kode. Den bedste kodelinje i dette projekt er den, vi ikke behøvede at skrive, fordi temaet allerede kunne lægge bundles i kurven.
- Lad prislogikken blive i Shopify. En indbygget automatisk rabat virker i kurven, ved kassen og i alle rapporter, og den kan sættes på pause uden at røre temaet.
- Begræns anvendelser pr. ordre fra første dag.
Vil du have en køb én, få én gratis-vælger, en bundle-builder eller en anden tilpasset funktion på dine produktsider, så se vores Shopify-temaudvikling eller fortæl os om din butik.
Ofte stillede spørgsmål
Understøtter Shopify køb én, få én gratis uden en app?
Ja. Automatiske Køb X, få Y-rabatter er indbygget i Shopify. Det, Shopify ikke har, er en måde for kunden at vælge gratisproduktet på produktsiden, og det er det, vælgeren tilføjer.
Virker vælgeren med mit tema?
Idéen virker med ethvert Online Store 2.0-tema. Implementeringen afhænger af, hvordan dit temas produktformular lægger varer i kurven. Her genbrugte vi temaets bundle-funktion; i andre temaer lægger vi begge varer i kurven med ét kald til Cart API.
Kan gratisproduktet have varianter?
Ja. Produkter med flere varianter viser en lille rullemenu på kortet, og den valgte variant er den, der lægges i kurven.
Kan kunder misbruge tilbuddet?
Det er rabatten, ikke vælgeren, der afgør, hvad der er gratis. Med maksimalt én anvendelse pr. ordre kan en kunde aldrig få mere end ét gratis produkt i samme ordre.
Kan jeg vise forskellige gratisprodukter på forskellige produkter?
Ja. Blokken læser som standard en kollektion, og et metafelt med en produktliste kan overstyre den pr. produkt.