Gatsbys createPages-Funktion für verschiedene Seitentypen verwenden

Von openmedi veröffentlicht am 5/19/2019, 1:56:14 PM

(Gatsby ist ein static site generator, der auf React und GraphQL setzt.)

Wie kann man Gatsby dazu bewegen mehr als einen Typ von Seiten dynamisch zu erstellen? Gatsbys createPages-Funktion kann nur einmal von gatsby-node.js exportiert werden. Was tun?

Was meine ich mit “dynamisch erstellen”? Gatsby bietet die Möglichkeit in einem speziellen Ordner src/pages direkt Seiten zu erstellen. Diese Seiten können selbst auch Inhalte über GraphQL nachladen (z. B. den Titel des Blogs o. Ä.), aber manchmal reicht das nicht. Wenn ich zum Beispiel meine Blogposts in Gatsby darstellen will, dann möchte ich dass jeder dieser Posts eine eigene URL hat. All diese Posts sollten unterschiedliche URLs haben, aber ansonsten die gleichen Styles und Layout, d. h. dasselbe Template verwenden.

Genau für diesen Anwendungsfall gibt es die createPages-Funktion, die dafür sorgt, dass die benötigten Daten angefragt und entsprechende Seiten erstellt werden (über die createPage-Action).

Ich begenete dem Problem mehr als nur einen Typ von Seiten dynamisch erstellen zu müssen, als ich mein Blog, von WordPress (zumindest im “public” Frontend) nach Gatsby umzog.

Denn neben den eigentlichen Blogposts, die ich aus meinem CMS über GraphQL dynamisch lade, gibt es noch Pages, Tags und Kategorien. Alles Dinge, die ebenfalls dynamisch erzeugt werden. Die createPages-Funktion erwartet aber, dass man eine einzige Promise zurückgibt und mehrmaliges Exportieren der Funktionieren funktioniert natürlich nicht.

Die Lösung liegt in der Nutzung von Promise.all. Promise.all gibt eine einzige Promise zurück, die aufgelöst (resolved) wird, wenn alle Promises, die man als ein Array als Parameter an die Funktion übergibt, aufgelöst worden sind. Kurz gesagt: Ich kann also für alle Seitentypen, für die ich dynamisch erzeugte Seiten erstellen muss, promises erzeugen, die ich dann als Array-Element in ein Promise.all([promise1, promise2]) packe:

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPosts = new Promise((resolve, reject) => {
    ...
  })

  const pages = new Promise((resolve, reject) => {
    ...
  })

  const tags = new Promise((resolve, reject) => {
    ...
  })

  const categories = new Promise((resolve, reject) => {
    ...
  })


  return Promise.all([blogPosts, tags, categories])
}

Unsere createPages-Funktion gibt eine einzige Promise zurück, die selbst aber erst aufgelöst wird, wenn alle anderen Promises aufgelöst worden sind.

Posted in: Artikel
Tags: Gatsby