React och Episerver: Är vi där än?

En av våra utvecklare, Peter Karlsson, skrev nyligen en artikel om ett intressant case där man byggt en React-applikation med Episerver som CMS åt en kund. **Spoiler**: Vi är inte riktigt där än, men det finns goda skäl att börja tänka i de här banorna.

En kund bad oss nyligen att utreda möjligheten att bygga om deras sajt till en React-applikation i SPA-utförande. En av utmaningarna hos den aktuella kunden är att deras sajt består av både redaktionellt innehåll och olika applikationsdelar, att den översätts, och att flera olika sajter delar kodbas och behöver kunna konfigureras separat.

Motiveringen för att bygga allt i React är att applikationsdelen är integrerad med det redaktionella innehållet, och utspritt över olika delar av sajten. Därför vore det lite av en mardröm att hantera exempelvis routing i både applikations- och innehållsdelen, särskilt eftersom sajten översätts till flera olika språk.

I de moderna ramverkens barndom gjordes en del förhastade implementationer, men vid det här laget är saker som rendering på serversidan och rimlig routing en självklar del av Reacts ekosystem. Det finns inga skäl att bli sittande med en lösning som presterar sämre i exempelvis sökmotorer och sociala medier, bara för att man vill arbeta med modern teknik.

Nuläget
Det finns stöd inbyggt i Episerver för att bygga en sajt på moderna ramverk som React¹, men det bygger på att man fortfarande använder .Net MVCs razor-vyer.

Det är inte heller ett problem att använda Episerver som ett rent API som bara levererar data i JSON-format. Dock är vi inte riktigt där när det gäller att köra det som ett headless CMS. On Page Edit och Preview Mode är exempelvis tätt sammankopplat med .NET MVC.
Vår målsättning i det här fallet var att helt eliminera razor-vyerna då dessa inte fyllde någon annan funktion än att slussa vymodeller från servern till frontend-applikationen. Vi har tidigare blivit sittande med lösningar där en oändlig mängd data-attribut måste fyllas för att konfigurera en integrerad applikation, vilket har en tendens att bli fult och buggbenäget om komplexa datatyper ska skickas.

@*Varför blir det alltid såhär?*@

<div id="prefix-@Model.ThingId" data-info="@Model.Info.ToJson()" data-language="@(!String.IsNullOrEmpty(Model.Settings.Language) ? Model.Settings.Language : "sv-SE")"></div>

 

De som känner mig vet att jag rekommenderar reactjs.net så fort jag får chansen. Det är i min mening ett utmärkt sätt att pröva på React-utveckling i Microsoft-miljö, utan att behöva integrera onödigt komplicerade byggsteg. Men reactjs.net fungerar bäst till enstaka, lösa komponenter². Eftersom vi i det här fallet arbetar med en sajt som har mycket redaktionellt innehåll så måste alla sidor kunna skickas ut färdigrenderade från servern, och samtidigt kunna navigeras utan kompletta sidomladdningar (alltså en Single Page Applikation, eller SPA).

Genom .NETs NodeServices så anropar vi renderingsfunktionen i React-dom. En fördel är alltså att vi inte behöver förlita oss på ett externt bibliotek för att tolka JSX-syntax, utan kan använda nya funktioner i samma takt som de lanseras i React.
Vi hänvisar sedan till vår färdiga bundle, i det här fallet byggt med webpack, i en node-modul. Där mockar vi också bland annat ett window-objekt, eftersom vissa funktioner är beroende av ett sådant. Det är alltså inte krav för att rendera React-komponenter, men i vissa fall använder våra komponenter externa bibliotek som är beroende av ett globalt window-objekt. Ett sådant exempel är en integration mot Google Maps.

On Page Edit och sidegenskaper
Det går alldeles utmärkt att ersätta Episervers inbyggda HTML-extensions med ren markup, dekorerad med attribut som knyter den till olika sidegenskaper. Men för att få till On Page Edit får man alltså bygga egna komponenter motsvarande DisplayTemplates för alla varianter av egenskaper som ska renderas i redigeringsläget. Om man bara kikar i sidkällan på en sida renderad i redaktörsläge så får man ganska bra bild av vad exempelvis Html.PropertyFor(…) spottar ur sig (Joel Abrahamsson har såklart en utmärkt grundkurs ihur PropertyFor fungerar).

<h1>@Html.PropertyFor(x => x.Heading, new { CustomTag = "span" })></h1>

 

blir

<h1>
  <span data-epi-property-name='Heading' data-epi-property-rendersettings="{&quot;customTag&quot;:&quot;span&quot;}">
  Rubriken från Episerver
  </span>
</h1>

 

Settings-objektet blir en smula manglat när det skrivs ut som en sträng, men det går att vänja sig vid.

Sen är det inte konstigare än att skriva ut attributen då en egenskap ska renderas inne i Edit Mode. (Glöm inte att data-attribut skrivs med små bokstäver och bindestreck, även i JSX.)

render () {
  return (
    <h1>
       <span data-epi-property-name='Heading' data-epi-property-rendersettings='{&quot;customTag&quot;:&quot;span&quot;}'> 
       /* Rubriken hamnar här så fort Episerver hittat hit */
       </span>
    </h1>
  );
}

 

Detta görs alltså med fördel i en egen komponent för att slippa kladd i render(), och så att vi slipper hantera den den snåriga formateringen av settings-objektet mer än nödvändigt. Render-funktionen ovan skulle alltså med fördel bo i exempelvis en komponent som heter StringProperty som då skulle kunna ta emot saker som tag-namn och egenskapsnamn via props-objektet.

renderHeading() {
  return this.props.isEditMode ? <StringProperty tagName="span"
  propertyName="Heading" /> : <span>this.props.heading</span>
}
render () {
  <h1>{this.renderHeading()}</h1>
}

 

Det fina är att det räcker att låna attributen så fyller Episerver på med värden från sidans egenskaper helt av sig själv, åtminstone när det gäller primitiva datatyper. Om man prompt vill bygga logik baserad på egenskapernas värde och exponera dessa i On Page Edit så kommer man förmodligen sabba Reacts state-hantering när man uppdaterar värdena i och med att man inte uppdaterar innehållet via Reacts normala renderingscykel, utan skjuter in dem rakt i DOMet, som förr i tiden.

Innan ni börjar
Det här är alltså inte en implementation som är officiellt stödd av Episerver. Däremot kommer de definitivt att behöva utveckla stöd för att användas headless, om de ska hänga med de närmaste åren. Om man väljer att utveckla på det här sättet redan nu så bör man vara medveten om att man riskerar att behöva bygga en hel del själv som annars kommer “gratis” med produkten, och beroende på hur man använder Episerver idag, och hur mycket man har modifierat verktyget sedan innan, så kan en övergång till SPA och headless innebära ett mer eller mindre omfattande utvecklingsarbete.


¹ Eller Angular 2 (eller 4 eller 12), Vue.js eller vad man nu föredrar. Jag dömer ingen.

² Även om exempelvis stöd för routing nyligen har tillkommit och öppnat för mer komplexa lösningar.




  • En bild med grön bakgrund som symboliserar hur vi har jobbat med Episerver och React
    React och Episerver: Är vi där än?
  • darksocial_AW_Coverbild_1080x1080_web.png
    Dark Social AW 26 april
  • mats
    Esatto deltar i Good Tech Hack
  • Fyra händer med knutna nävar som möts i mitten
    Mixat kund- och leverantörsteam
  • Esattos medarbetare Johan
    Riskerna med Business Model Canvas
  • Custellence logga
    Custellence - från insikt till handling
  • Tre av esattos medarbetare
    Esattos karriärsite
  • Episerver logga
    Episerver – konkurrensfördel
  • Esattos medarbetare Louise och Josefin
    Esatto-familjen blir större
  • Esattos medarbetare Jocke
    Joakim - ny Creative Director
  • Detaljbild av vajrar som bildar ett rutnät
    AI – Ska vi börja nu eller kan vi vänta?
  • Logga om dark social
    Marknadsförares största utmaning hittills?
  • två medarbetare med lila filter
    En podd om vår framtid
  • Tre personer håller upp diplom
    Best Lead Generating Website
  • Esattos medarbetare Hanna
    Hej hallå Hanna!
  • Personer som räcker upp handen
    Välkommen till framtiden
  • Personer som spelar boule
    Episerver Premium Partner
  • En av Esattos medarbetare
    We are on a roll!
  • Esattos medarbetare Amanda och Hanna håller upp sina mobiler
    Esattos stjärnhimmel expanderar!
  • En man håller föredrag framför publik
    Kompetensfrukost
  • Dator och surfplatta som visar grafer
    Esatto <3 Analys
  • Hund med glasögon
    Kompetensfrukost
  • Esattos medarbetare Johan
    All we want for Christmas
  • En tjej och en kille med emojiansikten
    Vi satsar på sociala medier med Dingle
  • Esattos medarbetare Pierre
    Pierre stärker vårt utvecklingsteam
  • Esattos medarbetare Anna
    Anna-lys
  • Dator på träbord med kaffekopp och skrivblock
    Vi söker en Frontend Lead
  • Esattos medarbetare Björn
    Välkommen Björn
  • Esattos medarbetare Thomas och Henrik
    Vi växer i sundsvall
  • Esattos medarbetare Nathalie
    Dingle växer
  • Orangea stolar i ett mötesrum
    Vi söker en senior webbutvecklare
  • Esattos medarbetare Frida
    Esatto <3 Frida
  • Mockup hemsida
    Episerver web awards
  • Esattos medarbetare Mats och Michael
    Nya topprekryteringar
  • Esattos medarbetare Johan
    Ny digital affärsutvecklare
  • Esattos medarbetare Hannah
    Nummer 28
  • Tre medarbetare på möte
    Ung Cancer mentorskapsprogram
  • Esattos medarbetare Alexander
    Välkommen Alexander
  • Esattos medarbetare Ludvig Andreas och Lisa
    Välkommen Ludvig, Andreas och Lisa
  • Vita hyllor på en vägg
    Esattos nya boning