Blue background with pattern

De eerste PWA op Deity Falcon voor Uitgeverij Pluim

Peter Jaap BlaakmeerOrange dot8 Jul 2019

13 min read

Vorige week lanceerden we ons eerste PWA-project voor een Magento 2-project. In deze blogpost leggen we uit waarom en hoe we deze geavanceerde en razendsnelle webshop hebben gebouwd. Als je niet kunt wachten om het resultaat te zien (dat begrijpen we helemaal!) kun je de webshop hier bezoeken; uitgeverijpluim.nl.

In de Magento PWA scene is er veel gepraat en weinig actie geweest met betrekking tot het daadwerkelijk bouwen van shops. We hebben proof of concepts gezien, maar daarmee kom je niet verder. Dus toen we de kans kregen om een PWA shop te bouwen, besloten we om er gewoon voor te gaan en te zien waar we zouden uitkomen. We hadden het geluk dat we een klant tegenkwamen die bereid was om dit avontuur met ons aan te gaan!

Wensen van de klant

Toen de klant ons benaderde, hadden ze geen idee wat een PWA was en wat het inhield. Uitgeverij Pluim is een Nederlandse uitgeverij die in 2018 is gestart. Ze geven literaire fictie en non-fictie boeken uit gericht op de Nederlandse markt. We pitchten hen PWA en legden uit wat dit voor hen kon betekenen. Twee van de belangrijkste voordelen van PWA zijn de snelheid van de webshop en de hoge Google Pagespeed Insight scores die relatief eenvoudig haalbaar zijn ten opzichte van een standaard Magento 2 frontend implementatie.

De vereisten waren vrij eenvoudig, wat ons het vertrouwen gaf om te beginnen met het bouwen van een PWA. Op dit moment zijn de PWA's nog niet zo rijk aan functies als de standaard Magento 2 frontend en gelijkwaardige functies zijn nog ver weg. De belangrijkste initiële vereisten voor fase 1 waren

  • Mogelijkheid om auteurs te tonen
  • Mogelijkheid om boeken te tonen
  • Mogelijkheid om aankomende agendapunten te tonen
  • Mogelijkheid om nieuwsberichten te tonen
  • Gemakkelijk onderhoudbaar
  • Snelle website

De volgende vereisten voor fase 2 waren;

  • Mogelijkheid om producten te verkopen
  • Mogelijkheid om iDeal te gebruiken als betaalmethode
  • Mogelijkheid tot basis e-mailmarketing

Vanwege de relatief kleine hoeveelheid boeken in de shop (ongeveer 20 tot 50 op een bepaald moment), konden we het doen zonder filteropties en zoekfunctie. Vanwege de beperking tot de Nederlandstalige markt, konden we het ook stellen zonder internationalisatie en complexe belastinginstellingen etc.

We zijn toen op zoek gegaan naar manieren om deze twee fasen te scheiden en de contentsite (zonder e-commerce functionaliteit) zo snel mogelijk online te krijgen.

React

Eerst praten we over onze onderliggende tech stack. We zijn van oudsher een PHP-bureau - we hebben altijd met Magento gewerkt en een paar jaar geleden zijn we begonnen met het ontwikkelen van microservices en ondersteunende tools voor e-commerce in Laravel, wat ook een PHP-framework is (maar niet specifiek gericht op een bepaald type webapp). Onze frontend stack is altijd gewoon HTML/JS/CSS geweest (en XML met betrekking tot Magento).

PWA-aanbiedingen zijn echter niet gebouwd in PHP. Ze worden geschreven in Javascript en meer specifiek in een Javascript frontend framework. Er zijn hier twee belangrijke spelers: Vue en React. We hebben beide overwogen en uiteindelijk voor React gekozen. Ik ga niet dieper in op waarom we React verkozen boven Vue, die keuze kun je zelf nalezen. Uiteindelijk komt het neer op persoonlijke voorkeur (en discussiëren klinkt vaak als een religieus debat).

Gatsby

Nadat we een tijdje geleden besloten hadden om met React te gaan werken, begonnen we te spelen met het bouwen van pure React-apps (zoals onze tableratesgenerator.com) en het bouwen van sites met behulp van Gatsby, wat een React-gebaseerde statische site-generator is. In feite is de site waarop je dit leest gebouwd op Gatsby. Gatsby stelt ons in staat om efficiënt en snel extreem snelle sites te bouwen in een relatief korte tijd en zonder veel training voor ontwikkelaars. React-componenten zijn uiteindelijk gewoon kleine bundeltjes Javascript, waardoor het voor iedereen met wat Javascript-ervaring vrij eenvoudig is om te begrijpen wat er in zo'n framework gebeurt. Bovendien zijn de Gatsby-documenten gewoon uitstekend en is de community erg gastvrij (hallo Jason!).

Aangezien de eerste mijlpaal was om een content site up and running te krijgen, besloten we voor Gatsby te gaan om de site up and running te krijgen. We hadden een ontwerp in pure HTML/JS/CSS en hebben dit herschreven naar een Gatsby-thema, dat in feite een verzameling React-componenten is. Hierdoor konden we deze componenten later met relatief gemak overzetten naar onze PWA-oplossing, aangezien we ook voor React kozen toen we de PWA-route voor e-commerce kozen.

De Gatsby-site is nog steeds hier toegankelijk.

Prismic

Nu is het tijd om Prismic te introduceren. Prismic is een van de vele interessante headless CMS-aanbiedingen. Een headless CMS is een content management systeem waarmee je je content kunt beheren zonder dat je iets te zeggen hebt over hoe die content op de voorkant wordt gepresenteerd. Als je bijvoorbeeld Wordpress gebruikt zonder frontend, maar alleen de Wordpress API gebruikt om je gegevens van de Wordpress backend te halen en deze weer te geven in je eigen aangepaste frontend, dan gebruik je het in feite als een headless CMS.

We hebben een vrij diepgaande vergelijking gemaakt tussen een aantal headless CMS aanbieders zoals Prismic, Sanity, Contentful, ButterCMS en Cockpit. Deze vergelijking zou een blogpost op zich kunnen zijn, maar samengevat kozen we voor Prismic vanwege zijn prijspunt (goedkoop maar niet te goedkoop), functieset (redelijk compleet) en hun reactiesnelheid op onze vragen (erg snel). We wilden ook een gehoste SaaS-oplossing (om de overhead te minimaliseren), dus zelf gehoste oplossingen werden niet overwogen. Contentful is een geweldige optie maar waanzinnig duur.

Het opzetten van Prismic is een zeer aangenaam proces; hun backend is snel en een lust voor het oog. Hun documentatie is uitgebreid en diepgaand en bovenal is de hoeveelheid bibliotheken en tools die ze aanbieden in een grote verscheidenheid aan talen en frameworks ongeëvenaard. Dit lijkt een typisch Frans iets te zijn, aangezien de Algolia-integraties net zo eindeloos zijn. Vooral de NodeJS en React componenten voor Prismic.io waren echte tijdbespaarders tijdens ons project.

Prismic biedt ook een GraphQL API endpoint dat we hebben gebruikt om er gegevens uit te halen.

Toen we Prismic hadden ingesteld, vroegen we de klant om alle gegevens in te voeren. We maakten aangepaste types voor een aantal entiteiten;

Screenshot of Prismic custom types overview

Vervolgens koppelden we Prismic aan Gatsby via het gatsby-source-prismic pakket om alle gegevens beschikbaar te maken in onze Gatsby site. Omdat Gatsby een statische site bouwt en geen server nodig heeft nadat deze is geïmplementeerd, gebruikten we Netlify voor (gratis!) hosting van de site.

Magento 2

Op naar e-commerce! Tegen die tijd hadden we de contentsite bijna klaar voor gebruik, maar we moesten de producten op de site tonen, zij het zonder e-commerce functionaliteit. We zetten een vrij standaard Magento 2 instance op en configureerden die zodat de klant er producten aan kon toevoegen. Nadat ze hun producten in Magento hadden geüpload, konden we de gatsby-source-magento2 gebruiken om productgegevens van Magento 2.3 op te halen via GraphQL.

Deity Falcon

Dit is waar de magie gebeurt. We hebben alle voorwaarden gecreëerd om aan de slag te gaan met de PWA-implementatie; we hadden een Magento 2-instantie met productgegevens en een Prismic-instantie met alle andere content, zoals auteurs, agendapunten, nieuwsberichten en contentpagina's. We wilden werken in React, zodat we de componenten die we al hadden geschreven in Gatsby konden overzetten naar de PWA-oplossing. We wilden in React werken zodat we de componenten die we al in Gatsby hadden geschreven, konden overzetten naar de PWA-oplossing. We hebben een aantal prettige gesprekken gehad met het Eindhovense Deity, dat een reeks producten ontwikkelt voor e-commerce, waaronder Falcon en PushPro.

Hun Falcon product is een PWA oplossing geschreven in React die bestaat uit twee hoofdonderdelen; Falcon Server en Falcon Client. Falcon Server fungeert als de lijm tussen onze backend systemen (zoals Magento en Prismic) en de frontend. De frontend is in dit geval Falcon Client, maar het systeem is onafhankelijk opgezet - we hadden ervoor kunnen kiezen om onze Gatsby site als frontend te gebruiken en Falcon Server te gebruiken om e-commerce functionaliteit in ons project te introduceren.

Waarom hebben we dan gekozen om ons ontwerp in Falcon Client te implementeren in plaats van e-commerce functionaliteit in de vorm van een Falcon Server implementatie in Gatsby? Omdat we al veel aangepaste React componenten hadden geschreven in Gatsby, was het vrij eenvoudig om dit over te zetten. We hadden ook geen afhankelijkheid met betrekking tot data, omdat dit was geabstraheerd in Magento en Prismic. We gokten dat dit minder werk was dan het schrijven van onze eigen implementatie van Falcon Server voor Gatsby en achteraf gezien lijkt het erop dat we de juiste keuze hebben gemaakt, in ieder geval qua tijd. Merk op dat we geen gebruik hebben gemaakt van Falcon UI, wat een UI-component bibliotheek is voor React. Dit komt omdat we het ontwerp niet vanaf nul hebben opgebouwd; we hadden het al omgezet in gewone HTML/JS/CSS. Falcon UI zou een optie zijn om te gebruiken wanneer we het ontwerp nog moesten omzetten van Figma naar code, naast andere UI component library zoals Storybook.

Aangepast werk in Falcon API-providers

Tot nu toe had de enige grote brok aangepast ontwikkelingswerk te maken met de frontend. Maar Prismic data naar Falcon Server halen was iets dat nog niet eerder gedaan was; we moesten onze eigen sourcing pakketten schrijven. Uiteindelijk schreven we 5 API providers om de 5 custom content types van Prismic te sourcen (Agenda, Auteur, Homepage, Nieuws, Pagina). Boeken werden al gesourced van Magento door Falcon's Magento 2 module, hoewel we een extensie moesten schrijven om custom velden van Magento door te geven via Falcon Server naar Falcon Client (zie het Deity Falcon data flow schema):

Sitemap generator

We hebben ook een sitemap generator geschreven in Falcon Server. We konden de Magento 2 sitemap niet gebruiken omdat deze ons de Magento URL's voor de producten zou geven in plaats van de Falcon URL's en het zou alleen URL's voor de boeken hebben, maar we hebben 5 andere content types die we ook geïndexeerd willen hebben. Falcon Server is de plek om dit te doen; dit is het enige systeem dat op de hoogte is van alle routes die beschikbaar zijn binnen de site. We zullen deze sitemap generator binnenkort open-sourcen, dus houd onze Github pagina in de gaten.

Afbeeldingen CDN

Dan hadden we nog de kwestie van afbeeldingen; we hadden afbeeldingen die binnenkwamen vanuit Magento en we hadden afbeeldingen die binnenkwamen vanuit Prismic. Dit zou in essentie prima werken, maar we wilden een enkele repository om deze afbeeldingen te beheren en we wilden een CDN voor afbeeldingen implementeren. We besloten voor Cloudinary te gaan omdat we goede dingen hadden gehoord en ze een geweldige Magento 2 extensie hebben. Door deze extensie te gebruiken, zou Magento ons de Cloudinary-versie van de productafbeelding retourneren, maar Prismic doet dit niet. Daarom schreven we ons @elgentos/cloudinary-automatic-image-uploader pakket voor Falcon Server. Wanneer we een URL van een afbeelding ontvangen van Prismic, hashen we deze en controleren we of er een corresponderend bestand bestaat in Cloudinary. Zo ja, dan sturen we die URL terug. Zo niet, dan uploaden we het naar Cloudinary met behulp van hun NodeJS SDK en halen we de resulterende Cloudinary URL op. Een van de (vele) coole dingen is dat we de gezichtsbeeldtransformatie kunnen toepassen voor de auteursfoto's, zodat Cloudinary automatisch bijsnijdt naar het gezicht van de auteur.

iDeal betaalmethode integratie

Falcon biedt out of the box een PayPal en een Adyen integratie. Helaas biedt de Adyen integratie alleen een credit card implementatie en geen iDeal integratie, die we nodig hadden. We wilden gaan voor een eenvoudige iDeal betaalimplementatie en kozen voor Mollie vanwege hun extreem eenvoudige API en hun geweldige Magento 2 extensie. De Magento 2 extensie doet eigenlijk al het zware werk; we moesten de extensie alleen een beetje uitbreiden om een andere redirect URL te kunnen doorgeven. Dit is omdat we de klant terug moeten sturen naar de Falcon frontend in plaats van de standaard Magento 2 frontend. Je kunt ons vinden op onze Github pagina; Falcon Mollie implementatie voor Magento 2.

Pagespeed Insights optimalisatie

We wilden een snelle site, en een snelle site is wat we kregen! We hebben veel tijd besteed aan het optimaliseren van de code en de Webpack bundels waaruit onze uiteindelijke site bestaat, maar hier is het resultaat (en ja, daar zijn we best trots op!);

Hosting

We zijn al lange tijd fan van het Hypernode-aanbod van Byte en draaien al onze Magento-webshops op dat platform. Aangezien dit een relatief lichte site is, wilden we de hele stack op een enkele Hypernode kunnen draaien. Dit had zo zijn uitdagingen omdat we natuurlijk de eersten waren die dit probeerden. Hypernode is een beheerd platform, dus we hadden niet volledig de vrije hand om alles naar onze wensen in te richten. Maar we kregen geweldige hulp van het ondersteuningsteam van Hypernode en we kregen het aan de praat. In het kort, hier is een deel van het werk dat we moesten doen om onze Hypernode compatibel te maken met Falcon;

  • Node en yarn (of npm) installeren
  • Crons instellen die de Falcon client en server zullen starten wanneer ze niet draaien
  • Nginx configureren zodat het poort 80/443 proxy doorgeeft aan poort 3000 (waarop Falcon client draait)
  • Configureer Nginx zodat de Magento site beschikbaar zal zijn op een sub-subdomein (magento.projectname.hypernode.io)
  • Redirect www naar niet-www
  • Redirect http naar https

Uren

Hoe lang heeft dit alles geduurd? We hadden een aanloopperiode waarin de klant zijn wensen bepaalde, inhoud creëerde, enz. We zijn half april begonnen met het bouwen van de Gatsby site, half mei met het bouwen van de Falcon shop en op 4 juli hebben we de shop gelanceerd. Hier is een visueel overzicht;

Hier volgt een uitsplitsing van de belangrijkste projectonderdelen die we hebben besproken;

Component Sub-component Uren

Magento 2 opzet 9

Prismic opzet 17

Gatsby implementatie 48

Falcon implementatie totaal 250

Prismic 65

Cloudinary 32

Mollie 16

Hosting 7

CI/CD opzet 4

Sitemap generator 2

Overige 124

Projectbeheer 20

Totaal 344

Conclusie

We zijn al met al erg blij met ons proces en hoe de webshop is geworden. We hebben veel geleerd en hebben het gevoel dat we een gelijkaardig project in de helft van de tijd zouden kunnen doen (neem dit ons niet kwalijk ;-)). Ontwikkelen in Falcon/React was een beetje een leercurve omdat we uit de PHP wereld kwamen. Falcon is nog niet bug-vrij of feature-compleet, maar het team werkt hard en ze zijn erg reactief op Slack. Ze luisteren naar feedback en implementeren voorgestelde wijzigingen vrij snel. We zijn ontzettend trots dat we de eerste Deity Falcon webshop op hun nieuwe architectuur hebben gelanceerd en we zijn benieuwd wat de toekomst ons brengt!