Op neverleafs.nl staat een keuzehulp waarin je met Herman praat. Hij vraagt voor welke ruimte je iets zoekt, hoe hoog het mag worden en wat je wil uitgeven, en komt met een paar planten die daarbij passen. Dat deel werkte al goed. Wat niet werkte was alles daarna. Verliet je de chat, dan was het gesprek weg: op de collectiepagina stonden weer alle 61 kunstplanten op best verkocht en begon je opnieuw met filteren.
Dat is zonde van de beste informatie die je als webshop kunt krijgen. Iemand heeft net in eigen woorden verteld wat hij zoekt, en dat blijft achter in een logbestand terwijl hij twee klikken verderop weer van voren af aan begint.
De afgelopen dagen heb ik daar een laag voor gebouwd. Hieronder wat het doet, hoe het in elkaar zit, en de twee dingen die onderweg stukgingen.
Wat Herman afgeeft
De keuzehulp draait op een eigen subdomein, keuzehulp.neverleafs.nl, los van de Shopify-shop. Herman hangt nu aan elk antwoord een blok met negen velden: ruimte, plek, stijl, hoogte_min, hoogte_max, budget_max, soorten, buiten en zakelijk. De bezoeker ziet dat blok niet, het staat achter het antwoord.
Het vult aan in plaats van te overschrijven. Mensen vertellen hun wensen in stukjes: eerst de ruimte, drie berichten later pas het budget. Een profiel dat bij elk antwoord opnieuw wordt gezet, gooit precies weg wat het gesprek daarvoor al had opgeleverd.
Eerst toestemming, in het gesprek zelf
De vraag of hij het mag onthouden staat in de chat, op het moment dat er iets te onthouden valt. Niet in een balk onderaan het scherm, want die leest niemand. Herman laat er meteen bij zien wat hij begrepen heeft, hier woonkamer en tot €130, zodat duidelijk is waar je ja tegen zegt.
Nee is een gewone knop naast ja, even groot. Zonder toestemming gaat er niets mee naar de shop.
Waar het profiel staat
De keuzehulp staat op een subdomein en de shop op het hoofddomein, dus het profiel gaat met postMessage naar neverleafs.nl. Daar zet het thema het in een cookie op .neverleafs.nl, negentig dagen houdbaar, met een kopie in localStorage voor als de cookie niet beschikbaar is. First party, geen partij van buiten ertussen.
Aan de themakant zijn het twee bestanden, assets/nlf-context.js en snippets/nlf-context-bar.liquid, ingehangen in theme.liquid. Die lezen het profiel bij elke paginaweergave opnieuw. Uitrollen gaat met shopify theme push met --only en --nodelete, zodat de rest van het thema er niet aan hoeft.
Op de collectiepagina
Bovenin staat wat Herman weet, als losse chips die je kunt aanpassen of wissen, met daarachter hoeveel producten erbij passen. In dit gesprek 12 van de 61.
Daaronder schuiven die planten naar voren. Twee regels waar ik niet vanaf wilde.
Er verdwijnt nooit iets. Wat niet past zakt naar beneden. Iemand die halverwege besluit dat hij toch een olijfboom wil, moet die gewoon kunnen vinden. Een filter dat stilletjes de helft van je assortiment wegneemt op basis van een gesprek van vier berichten is te zelfverzekerd.
Het merkje heeft een drempel. Producten krijgen punten voor de genoemde plantsoort, de gevraagde hoogte, de stijl en het budget. Bij een drempel van drie punten kreeg 40 van de 63 kaarten het merkje “past bij je gesprek”, en daarmee zei het niets meer. Op zes punten bleven er vijf over. Een merkje werkt alleen zolang het schaars is.
Op de productpagina
Op de productpagina staat geen algemene aanbeveling, maar de rekensom voor dit ene artikel. De hoogte uit het gesprek naast de hoogte van het product, het budget naast de prijs, de stijl naast de soort. Drie regels met een reden erbij.
Het blok zit naast de gewone koopkant, niet in de plaats daarvan. En als het artikel niet past, staat dat er net zo goed: te hoog blijft te hoog, met de reden erbij. Dat is het stuk waar ik zelf het meeste van verwacht, want een plant die achteraf niet in de hoek past komt terug.
Twee dingen die stukgingen
De chat viel stil op een leeg antwoord bij een nette 200. Claude Sonnet geeft in de huidige versie een denkblok terug als eerste blok van het antwoord, met een lege tekst erin. De code las content[0].text, kreeg een lege string en toonde de bezoeker “Sorry, ik ben heel even slecht bereikbaar”, terwijl er niets mis was. De oplossing is een regel: zoek het eerste tekstblok in plaats van het eerste blok. Het soort fout dat je in een snelle test niet ziet, omdat het antwoord er meestal gewoon staat.
Het tweede: mijn repo liep achter op de server. De catalogus in de repo had 12 producten, op de server stonden er 63, want daar vult een cron hem aan. Ik heb een halve middag naar sortering zitten kijken die in de code klopte en op de pagina niet. Bij deze app controleer ik nu eerst de live versie voordat ik erop bouw.
Wat ik ga meten
Het staat sinds deze week live, dus er zijn nog geen cijfers en ik ga ze ook niet beloven. Drie dingen gaan in de meting: hoeveel gesprekken op ja eindigen, hoe vaak er vanaf een gemerkte kaart wordt doorgeklikt vergeleken met de rest van het raster, en of de retouren op hoogte teruglopen. Hoe ik zo’n meting opzet staat in beslissen op bewijs, en waarom dit soort werk in het thema hoort en niet in een app in rollouts tegen elkaar draaien.
De bouwtijd zat trouwens niet in de chat of in het model, die stonden er al. Hij zat in de vraag wat je met een gesprek doet zodra het voorbij is.
