Week 2

Maken van componenten mogelijk maken, storyblok koppelen en de preview omgeving laten werken

Deze week ben ik bezig gegaan met het mogelijk maken om componenten te creëren, het koppelen van Storyblok aan onze website en ben ik begonnen met het opzetten van een preview omgeving zodat we vrijdag aan Mattijs konden laten zien hoe zo'n preview omgeving eruit zou komen te zien.

Storyblok koppelen

Storyblok is dus een headless CMS. Dit betekent dat het dus volledig losgekoppeld is van de website en niet samenhangt zoals met Wordpress momenteel het geval is. Echter, doormiddel van de Storyblok API kunnen we wel met onze Storyblok omgeving praten en de data ophalen die we nodig hebben.

Gelukkig stelt Storyblok zowel de API als twee keys die we nodig hebben open zodat we er gebruik van kunnen maken. De storyblok API kunnen we eenvoudig installeren door 't volgende te doen:

npm install storyblok-js-client

Vervolgens moeten we die JS client gebruiken. Ik heb er daarom voor gekozen om een aparte `storyblok-instance` aan te maken zodat we daarna die instance overal kunnen gebruiken en maar op één plek de keys hoeven mee te geven:

// src/lib/storyblok-instance.js
require('dotenv-safe').config()
const StoryblokClient = require('storyblok-js-client')

const {
  ELEVENTY_ENV,
  STORYBLOK_PREVIEW_KEY,
  STORYBLOK_PUBLIC_KEY
} = process.env
const production = ELEVENTY_ENV === 'production'
const STORYBLOK_KEY = production 
  ? STORYBLOK_PUBLIC_KEY
  : STORYBLOK_PREVIEW_KEY

module.exports = new StoryblokClient({
  accessToken: STORYBLOK_KEY,
  cache: {
    clear: 'auto',
    type: 'memory'
  }
})

Allereerst halen we de environment keys op die we nodig hebben. Als we niet in productie zitten willen we de PREVIEW_KEY van Storyblok gebruiken zodat we ook drafts op kunnen halen uit het CMS.

In productie willen we echter alleen de gepubliceerde pagina's en componenten ophalen dus gebruiken we de PUBLIC_KEY. Door dit bestandje te exporteren kunnen we precies deze instance overal gebruiken waar we data van Storyblok moeten ophalen, super handig dus!

Data van Storyblok gebruiken

Om nu daadwerkelijk de data van Storyblok te gebruiken moeten we dus de bovenstaande instance gebruiken. Dit kan eenvoudig door hem te importeren en de methods te gebruiken die erop beschikbaar zijn volgens de documentatie van Storyblok. In ons geval hebben we enkel de `get` method nodig:

// src/site/_data/site.js
const Storyblok = require('../../lib/storyblok-instance')

module.exports = async () => {
  const env = process.env.ELEVENTY_ENV
  const version = env === 'production' ? 'published' : 'draft'

  const pages = await Storyblok.get('cdn/stories', { version, starts_with: 'pages' }),

  const { stories = [] } = pages.data

  return { stories }
}

Omdat we Eleventy gebruiken als Static Site Generator (we hebben voor Eleventy gekozen omdat dit volgens ons de enige SSG is die Vanilla JavaScript gebruikt) kunnen we in een `_data` map bestanden aan maken om tijdens buildtime data op te halen.

Vervolgens wordt de opgehaalde data onder de naam van het bestand beschikbaar in je templates als volgt (dit is eveneens hoe de homepage er in eerste instantie uit zag):

<!-- src/site/index.html -->
<main>
    <header>
        <h1>Home page</h1>
        <p>If you see this everything is working</p>
    </header>
    <section>
        <h2>Go to another page</h2>
        
        <!-- Hier kunnen we nu gebruik maken van site.stories -->
        {% for story in site.stories %}
            <a href="story.full_slug">{{ story.name }}</a>
        {% endfor %}
    </section>
</main>
<!-- ... -->

De bovenstaande template markup wordt dus door Eleventy gegenereerd naar een statische index.html zodra we zeggen:

npm run build

Eleventy haalt voor ons dan alle benodigde data op, schrijft die bestanden weg en klaar is Kees, je hebt een hele website.

Preview omgeving opzetten in Storyblok

Er zat wel één nadeel aan het moeten draaien van een build (zoals dat heet) om de nieuwe data te kunnen gebruiken: We kunnen onze preview omgeving niet zomaar live updaten, iets wat we idealiter wel zouden willen.

Om dit alsnog te kunnen bewerkstelligen had ik bedacht om een aparte preview omgeving te bouwen waarbij de componenten allemaal opgebouwd zijn uit JavaScript zodat we de pagina alsnog live kunnen updaten.

De connectie maken met Storyblok

Ook voor het opzetten van de preview omgeving moeten we weer allereerst een connectie maken met Storyblok. Dit konden we doen doormiddel van een soort 'bruggetje' van de preview omgeving naar onze website. Het enige wat we hiervoor hoeven te doen is een script inladen in onze website zodat we gebruik kunnen maken van de SDK van Storyblok:

<!-- src/site/_includes/components/scripts.html -->
<script src="//app.storyblok.com/f/storyblok-latest.js?t={{ token }}" type="text/javascript">
</script>
<script src="/scripts/preview.js"></script>
<script src="/scripts/index.js"></script>

Vervolgens kunnen we nu gebruik maken van een `storyblok` variabele in onze client-side code:

// src/assets/js/preview-environment.js
if (storyblok.isInEditor()) {
    storyblok.on('change', () => {
        console.log('Storyblok content changed, getting new data')
        
        storyblok.get('cdn/stories', { version: 'draft' })
            .then(updatePreview)
    })
}

Het 'change' event werd afgevuurd wanneer iemand op 'Save' of cmd + s drukte binnen het CMS. Als iemand nu dus de preview omgeving opslaat halen wij de nieuwe data op en updaten we de preview omgeving met de verse data door JavaScript componenten te updaten.

De pagina wordt dus als het ware gehijacked door JavaScript wanneer iemand binnen de preview omgeving erin werkt. Hierdoor heb je dus alsnog een live updatende preview omgeving zodat de eindgebruiker zijn of haar wijzigingen kan volgen.

Last updated