Deployn

Anleitung - Erster Blog mit Gatsby und Ghost

Ich zeige Schritt-für-Schritt, wie man eine Gatsby.js Webseite bzw. Blog mit Ghost als CMS einrichten kann und anschließend veröffentlicht.

Anleitung - Erster Blog mit Gatsby und Ghost-heroimage

Auf dieser Seite fasse den Inhalt meiner Videos zum Thema Gatsby und Ghost zusammen. Da es meiner Meinung nach nicht genügend deutschsprachige Anleitungen dazu gibt, habe ich eins erstellt. Es geht darum, wie man von Grund auf seine erste Gatsby.js Seite erstellt, Ghost auf einem VPS installiert und als headless CMS verwendet und auch, wie man die Seite dann online in der Gatsby-Cloud veröffentlicht. Ich zeige alle Schritte, die dazu nötig sind. Die Videos haben eine Gesamtlänge von zwei Stunden und befinden sich (demnächst) bei YouTube (aufgrund der Größe und Reichweite möchte ich diese nicht selbst hosten), dementsprechend gehe ich nicht auf jede Kleinigkeit ein, sondern versuche eher einen Überblick zu geben.

Videos

Auf YouTube habe ich eine Playlist erstellt. Bisher sind der erste Teil und der zweite Teil online (Links zu YouTube). Der dritte Part fehlt.

Installation der Gatsby-Seite

Installation der Gatsby-CLI

Bevor die lokale Gatsby-Seite erstellt werden, müssen ein paar Programme vorinstalliert werden. Wir brauchen Node.js, Git sowie VSCode (oder einen anderen Texteditor).

Im Terminal (als Administrator ausgeführt) installieren wir die Gatsby-CLI.

npm install -g gatsby-cli

Die Gatsby-CLI ist damit installiert.

Gatsby-Seite erstellen

Zunächst muss git/bash geöffnet werden (entweder Standalone oder in VSCode)

Der Befehl gatsby new erstellt eine neue Gatsby Seite.

Die Gatsby-Seite ist damit erstellt.

Live-Server starten

Zum Starten des Live-Servers muss man der anzeigten Anweisung folgen.

cd namedesneuenverzeichnisses
# bzw cd vollständiger Pfad vom Verzeichnis, an dem die neue Seite erstellt wurde
npm run develop

Der Live-Server wird gestartet. Mit Strg + C wird er wieder beendet.

Lokales Gatsby-Projekt bearbeiten

Nachdem das Projekt geöffnet wird, können nun die einzelnen Elemente bearbeitet werden.

Index.js anpassen

Der Inhalt der index.js im Verzeichnis /src/pages kann gelöscht werden, wir wollen stattdessen unseren eigenen hinzufügen. /src/pages/index.js:

import * as React from "react";

const IndexPage = () => {
	return (
		<div>
			<h1> Hallo Welt </h1>
			<p> Hier könnte Ihre Werbung stehen 😃 </p>
		</div>
	);
};

export default IndexPage;

Innerhalb der Return-Funktion kann dann HTML-in-JS-Code genutzt werden. Wird der Development-Server wieder gestartet (entweder gatsby develop oder npm run develop), sind die Änderungen zu sehen.

CSS global einbinden

Für das Styling kann CSS genutzt werden. Dazu eine CSS-Datei erstellen und diese bearbeiten.

mkdir src/styles
touch src/styles/global.css

Ich erstelle eine global.css in einem Styles-Ordner In diese kommt dann gewöhnlicher CSS-Code. /src/styles/global.css:

body {
	margin: 0 auto;
	max-width: 50em;
}

h1 {
	color: slateblue;
}

Der CSS-Code kann in der jeweiligen Gatsby-Seite importiert werden oder wir nutzen den gatsby-browser. Dazu gatsby-browser.js im Root-Verzeichnis erstellen.

touch gatsby-browser.js

In die Datei folgenden Code einfügen:

import "./src/styles/global.css";

Sobald der Server neu gestartet wird, sind die Änderungen durch die CSS-Datei zu sehen.

Wir erstellen eine neue Unterseite im Pages-Verzeichnis.

touch src/pages/about.js

Und fügen da wieder den Code ein, denn wir benötigen.

import * as React from "react";

const About = () => {
	return (
		<div>
			<h1> About </h1>
			<p> Das ist die About-Seite 😃 </p>
			<p> Einen Link zur Hauptseite gibt es leider noch nicht </p>
		</div>
	);
};

export default About;

Diese Seite ist nach dem Speichern unter localhost:8000/about zu sehen, sofern der Gatsby-Server noch läuft.

Mit Gatsby-Link lassen sich interne Links einfügen. Wir müssen es nur importieren. Dazu ändern wir die About-Seite wieder.

import * as React from "react";
import { Link } from "gatsby";

const About = () => {
	return (
		<div>
			<h1> About </h1>
			<p> Das ist die About-Seite 😃 </p>
			<p>
				<Link to="/"> Home </Link> ist nun verlinkt.
			</p>
		</div>
	);
};

export default About;

Struktur mit Komponenten

Die Gatsby-Browser.js Datei kann ich wieder leeren, die brauchen wir vorerst nicht mehr. Es ist empfehlenswert wiederverwendbare Komponenten zu nutzen. Dazu erstellen wir einen neuen Ordner.

mkdir src/components
touch src/components/layout.js

In die Layout.js füge ich folgenden Code ein:

import * as React from "react";
import { Link } from "gatsby";

const Layout = ({ pageTitle, children }) => {
  return (
    <main>
      <title>{pageTitle}</title>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <a href="https://deployn.de" target="_blank">Deployn</href>
          </li>
        </ul>
      </nav>
      <h1>{pageTitle}</h1>
      {children}
    </main>
  );
};

export default Layout;

Der Link im <a>-Tag ist deutlich langsamer (und das liegt nicht nur an der Geschwindigkeit meiner Seite).

Jetzt müssen die Seiten angepasst werden.

import * as React from "react";
import Layout from "../components/layout";

const About = () => {
	return (
		<Layout pageTitle="About">
			<p> Das ist die About-Seite 😃 </p>
		</Layout>
	);
};

export default About;
import * as React from "react";
import Layout from "../components/layout";

const IndexPage = () => {
	return (
		<Layout pageTitle="Home">
			<p> Das ist nicht die About-Seite 😃 </p>
		</Layout>
	);
};

export default IndexPage;

Dadurch habe ich eine Layout-Komponente, die ich wieder verwende.

Styling mit Komponenten

Ich erstelle eine module.css.

touch src/components/layout.module.css

Da kommt CSS-Code rein.

.container {
	margin: 0 auto;
	max-width: 50em;
}

.heading {
	color: slateblue;
}

Dieses CSS importieren wir in der Komponente.

import * as React from "react";
import { Link } from "gatsby";
import { container, heading } from "./layout.module.css";

const Layout = ({ pageTitle, children }) => {
  return (
    <main className={container}>
      <title>{pageTitle}</title>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
          <li>
            <a href="https://deployn.de" target="_blank">Deployn</href>
          </li>
        </ul>
      </nav>
      <h1 className={heading}>{pageTitle}</h1>
      {children}
    </main>
  );
};

export default Layout;

Bilder mit Gatsby-Plugin-Image einfügen

Mit Gatsby-Plugin-Image lassen sich Bilder einfügen und dabei optimieren. Dazu muss das Plugin installiert sein.

npm install gatsby-plugin-image

Es muss auch in der Gatsby-Config als Plugin gelistet sein.

Bild von gatsby-config.js

Wir möchten ein statisches Bild einfügen, zunächst fügen wir irgendein Bild in das Projekt ein.

mkdir src/images
# hier nun ein Bild einfügen

Dieses Bild soll auf der About-Seite geladen werden. Dazu StaticImage importieren und nutzen.

import * as React from "react";
import { StaticImage } from "gatsby-plugin-image";
import Layout from "../components/layout";

const About = () => {
	return (
		<Layout pageTitle="About">
			<p> Das ist die About-Seite 😃 </p>
			<StaticImage src="../images/bild.jpg" />
		</Layout>
	);
};

export default About;

Es können noch ein paar Optionen genutzt werden.

import * as React from "react";
import { StaticImage } from "gatsby-plugin-image";
import Layout from "../components/layout";

const About = () => {
	return (
		<Layout pageTitle="About">
			<p> Das ist die About-Seite 😃 </p>
			<StaticImage src="../images/bild.jpg" alt="Eine Bildbeschreibung" width="200" placeholder="tracedSVG" />
		</Layout>
	);
};

export default About;

Die Dokumentation erklärt das Plugin ausführlicher.

Gatsby-Seite bereitstellen

Für das Build muss gegebenenfalls die Site-URL in der Gatsby-config eingetragen werden.

module.exports = {
  siteMetadata: {
    title: "Deployn",
    siteUrl: "https://deployn.de",
  },
  plugins: [
    "gatsby-plugin-gatsby-cloud",
    "gatsby-plugin-image",
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-sitemap",
    {
      resolve: "gatsby-plugin-manifest",
      options: {
        icon: "src/images/icon.png",
      },
    },
    "gatsby-plugin-sharp",
    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "images",
        path: "./src/images/",
      },
      __key: "images",
    },
    },
  ],
};

Nun kann der Build-Prozess gestartet werden.

npm run build

Im Public-Ordner wird jetzt eine Seite erstellt. Die Seite kann veröffentlicht werden, indem der Inhalt auf einen Webserver gepackt wird.

Server einrichten

Als Nächstes wird ein CMS benötigt. Ich möchte dafür Ghost.js headless benutzen. Hat man einen Server mit Traefik als Proxy Manager bereits eingerichtet, kann diese Anleitung genutzt werden. Ansonsten fasse ich hier noch mal die Schritte zusammen.

Möchte man weder Ghost lokal installieren (schwierig, wenn es immer online sein soll und es mehrere Autoren gibt), noch aus finanziellen Gründen Ghost Pro nutzen, bleibt nur das Hosting auf einem Server.

VPS mieten

Ich nutze dafür hier einen Server von Netcup (Affiliate-Link). Für Neukunden habe ich hier Gutscheine für die Server. Nutzt man den Server nur für Ghost reicht der kleinste aus, jedoch hat der auch wenig Speicherplatz.

Ubuntu 20.04 installieren

Auf dem Server installiere ich Ubuntu 20.04.

Funktioniert es auch mit den anderen Images? Ja, sogar fast identisch, weil ich Docker nutze.

SSH Verbindung herstellen

Ich stelle eine SSH Verbindung zum Server her. Bei Windows muss ich dafür vorerst den OpenSSH-Client aktivieren. Dazu unter “Apps und Features” auf „optionale Features“ drücken.

Dort lässt sich der OpenSSH-Client installieren (nicht verwechseln mit OpenSSH-Server).

Jetzt ein Terminal aufrufen.

ssh root@185.183.158.137

Die IP-Adresse muss die des eigenen Servers sein

User einrichten

apt update apt upgrade

Damit updaten wir den Server aus den Ubuntu Datenpaketen

useradd -m -G sudo jewgeni passwd jewgeni

Damit erstellen wir einen neuen Nutzer, fügen ihn der sudo-Gruppe hinzu und geben ihm ein Passwort

reboot

Damit starten wir den Server neu

ssh jewgeni@185.183.158.137

Diesmal verbinden wir uns mit dem neu erstellten Nutzer

Docker installieren

Möglichkeit 1 ist es, sich einfach Docker aus den Standard-Ubuntu-Paketen zu installieren.

sudo apt install docker docker-compose

Nachteil: Es ist nicht die neuste Version.

Möglichkeit 2 ist es, die offizielle Anleitung zu befolgen.

sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  sudo apt-get update
  sudo apt-get install docker-ce docker-ce-cli containerd.io

Damit ist Docker installiert

sudo gpasswd -a jewgeni docker

Damit fügen wir den Benutzer in die Docker-Gruppe hinzu Ich installiere auch noch Lazydocker.

curl https://raw.githubusercontent.com/jesseduffield/lazydocker/master/scripts/install_update_linux.sh | bash

Ich erstelle einen Docker Ordner und gebe der Gruppe Docker alle Rechte daran.

mkdir docker
sudo apt install acl
sudo setfacl -Rdm g:docker:rwx docker
sudo setfacl -Rm g:docker:rwx docker
sudo chmod -R 775 docker
sudo chown -R jewgeni:docker docker

Domain einrichten

Als Nächstes benötige ich eine Domain für den Server. Auch hier verwende ich Netcup (Affiliate-Link). Eine Domain mit “.de” als TLD kostet 5 € im Jahr (auch in den folgenden Jahren).

In den DNS Einstellungen der Domain setze ich einen Eintrag für Root (@), sowie einen mit einer Wildcard (*), nachdem ich die Default-Werte gelöscht habe.

Nach dem Speichern vergehen bis zu 48 Stunden, bevor der Eintrag wirklich Auswirkungen hat.

Nginx-Proxy-Manager

Installieren

Zur einfacheren Verwaltung eines Nginx Reverse-Proxys und Let’s Encrypt Zertifikaten möchte ich den Nginx-Proxy-Manager auf dem Server installieren.

ssh jewgeni@185.183.158.137

Verbindung zum Server wiederherstellen

cd ~/docker
sudo docker network create npm_net
mkdir nginx-proxy-manager
cd nginx-proxy-manager
mkdir data/mysql -p
mkdir letsencrypt
touch .env
echo "DB_PWD=$(openssl rand -hex 16)" >> .env
echo "DB_ROOT_PWD=$(openssl rand -hex 16)" >> .env
touch docker-compose.yml

Wir haben damit ein neues Docker-Netzwerk und im neuen nginx-proxy-manager Ordner weitere Verzeichnisse und zwei Dateien erstellt Die Docker-Compose Datei muss befüllt werden. Man kann dazu auch VSCode nutzen.

nano docker-compose.yml
version: "3.7"


networks:
  npm_net:
    external:
      name: npm_net
  internal:
    external: false
  default:
    driver: bridge


services:
  nginx-proxy-manager:
    container_name: nginx-proxy-manager
    image: jc21/nginx-proxy-manager:2.9.3
    restart: unless-stopped
    networks:
      - npm_net
      - internal
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    environment:
      DB_MYSQL_HOST: npm_db
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: npm
      DB_MYSQL_PASSWORD: $DB_PWD
      DB_MYSQL_NAME: npm
      DISABLE_IPV6: true
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    depends_on:
      - npm_db

  npm_db:
    container_name: npm_db
    image: mariadb:10.6.1
    restart: unless-stopped
    networks:
      - internal
    environment:
      MYSQL_ROOT_PASSWORD: $DB_ROOT_PWD
      MYSQL_DATABASE: npm
      MYSQL_PASSWORD: $DB_PWD
      MYSQL_USER: npm
     volumes:
       - ./data/mysql:/var/lib/mysql
docker-compose up -d

Die Logs können in Lazydocker angesehen werden.

lazydocker
# bzw. sudo lazydocker

Konfigurieren

Die Anmeldung unter der IP-Adresse und Port 81 erfolgt mit admin@example.com und dem Passwort “changeme”.

Wir benötigen einen neuen Proxy Host.

Als Domain muss nun die Subdomain eingetragen werden, unter der man diese GUI des nginx-proxy-managers erreichen möchte. Hostname ist localhost. Port ist 81, sofern diese Einstellung in der docker-compose Datei nicht geändert wurde.

Unter den SSL-Einstellungen muss ein neues Zertifikat angefordert werden.

Sobald es gespeichert ist, lässt sich der nginx-proxy-manager über die Subdomain aufrufen.

Firewall

Wir installieren eine Firewall auf dem Server (optional).

ssh jewgeni@185.183.158.137

Verbindung zum Server wiederherstellten

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw default deny incoming
sudo ufw enable
sudo reboot

Es muss ein anderer Port gewählt werden, wenn SSH nicht über Port 22 genutzt wird, sonst sperrt man sich selbst aus Docker sorgt dafür, dass die Firewall nicht richtig blockiert. Bei Github gibt es eine Lösung:

sudo nano /etc/ufw/after.rules

In diese Datei wird unten folgender Code angefügt.

# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN

-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP

COMMIT
# END UFW AND DOCKER

Jetzt muss ich noch die Routen erlauben.

sudo ufw route allow 80/tcp sudo ufw route allow 443/tcp sudo reboot

Ghost CMS

Installation

Die Installation von Ghost lässt sich durch Docker sehr einfach durchführen. Dazu verbinde ich mich wieder mit dem Server.

ssh jewgeni@185.183.158.137

Verbindung zum Server wiederherstellten

cd ~/docker
mkdir ghost
cd ghost
mkdir content
mkdir db
touch .env
touch docker-compose.yml
echo "DB_PWD=$(openssl rand -hex 20)" >> .env
nano docker-compose.yml
version: "3.7"

networks:
    npm_net:
        external:
            name: npm_net
    internal:
        external: false
    default:
        driver: bridge

services:
    ghost:
        container_name: ghost
        image: ghost:4.6.4
        restart: unless-stopped
        networks:
            - npm_net
            - internal
        security_opt:
            - no-new-privileges:true
        environment:
            - database_client=mysql
            - database_connection_host=ghost-db
            - database_connection_user=root
            - database_connection_password=$DB_PWD
            - database_connection_database=ghost
            - url=https://ghost.pixan.de
        volumes:
            - ./content:/var/lib/ghost/content
        depends_on:
            - ghost-db

    ghost-db:
        container_name: ghost-db
        image: mariadb:10.6.1
        restart: unless-stopped
        networks:
            - internal
        security_opt:
            - no-new-privileges:true
        environment:
            MYSQL_ROOT_PASSWORD: $DB_PWD
        volumes:
            - ./db:/var/lib/mysql
docker-compose up -d

Ghost Reverse-Proxy

Als Nächstes muss im Nginx-Proxy-Manager ein neuer Proxy-Host für Ghost eingerichtet werden. Der Hostname entspricht dem Namen des Services (in meinem Fall ghost), der Port von Ghost ist 2368.

Bild der Proxy-Host Einstellungen

Unter den SSL Einstellungen wieder ein neues Zertifikat anfordern (oder auf DNS-Challenge umstellen).

Nach dem Speichern müsste das Ghost CMS über die URL erreichbar sein. Unter domain.de/ghost befindet sich die Administration. Hier muss man sich einen Account anlegen.

Headless

Ghost erstellt (wie auch z. B. WordPress) automatisch ein Frontend. Nutzt man kein Gatsby, kann man so auch einen Blog direkt betreiben. Wir benötigen aber kein Frontend, dass von Unbekannten besucht werden soll. Deshalb können wir die Seite unter den Einstellungen auf privat stellen.

Posts

Wenn man den Nutzer Ghost löscht, sollten zum Test mindestens zwei Testposts erstellt und veröffentlicht werden. Sonst haben wir nichts, worüber das Query später laufen kann.

Ghost als Quelle

Plugin installieren

Um Ghost als Quelle zu nutzen, muss das Gatsby Source Ghost Plugin in der Gastby-Seite installiert werden.

npm install gatsby-source-ghost

Content-API-Key

Das Plugin benötigt den content-Api-Key, um sich verifizieren zu können. Diesen kann man in der Ghost-Instanz unter dem Menüpunkt “Integrations” erstellen.

Nachdem ein Name vergeben wird, ist der API-Key zu sehen.

Einbinden in Gatsby

Anschließend muss das Plugin inklusive der eigenen Daten der Gatsby-Config Datei hinzugefügt werden.

module.exports = {
	siteMetadata: {
		title: "Pixan",
		siteUrl: "https://pixan.de",
	},
	plugins: [
		"gatsby-plugin-gatsby-cloud",
		"gatsby-plugin-image",
		"gatsby-plugin-react-helmet",
		"gatsby-plugin-sitemap",
		{
			resolve: "gatsby-plugin-manifest",
			options: {
				icon: "src/images/icon.png",
			},
		},
		"gatsby-plugin-sharp",
		"gatsby-transformer-sharp",
		{
			resolve: "gatsby-source-filesystem",
			options: {
				name: "images",
				path: "./src/images/",
			},
			__key: "images",
		},
		{
			resolve: `gatsby-source-ghost`,
			options: {
				apiUrl: `https://ghost.pixan.de`,
				contentApiKey: `74bb1b0d67765995e687357669`,
			},
		},
	],
};

Im Root-Verzeichnis muss nun eine gatsby-node.js erstellt werden.

const path = require(`path`);

exports.createPages = async ({ graphql, actions, reporter }) => {
	const postTemplate = path.resolve(`./src/templates/post.js`);

	// Query Ghost data
	const result = await graphql(`
		{
			allGhostPost(sort: { order: ASC, fields: published_at }) {
				edges {
					node {
						slug
					}
				}
			}
		}
	`);

	// Handle errors
	if (result.errors) {
		reporter.panicOnBuild(`Error while running GraphQL query.`);
		return;
	}

	if (!result.data.allGhostPost) {
		return;
	}

	// Create pages for each Ghost post
	const items = result.data.allGhostPost.edges;
	items.forEach(({ node }) => {
		node.url = `/${node.slug}/`;

		actions.createPage({
			path: node.url,
			component: postTemplate,
			context: {
				slug: node.slug,
			},
		});
	});
};

Jetzt benötigen wir die Template-Datei für die Posts, die dynamisch aus den GhostPosts erstellt werden sollen. Wir speichern sie in den Ordnern src/templates.

cd src
mkdir templates
cd templates
touch post.js
import React from "react";
import { graphql } from "gatsby";

const Post = ({ data }) => {
	const post = data.ghostPost;
	return (
		<>
			<article className="post">
				{post.feature_image ? <img src={post.feature_image} alt={post.title} /> : null}
				<h1>{post.title}</h1>
				<section dangerouslySetInnerHTML={{ __html: post.html }} />
			</article>
		</>
	);
};

export default Post;

export const postQuery = graphql`
	query ($slug: String!) {
		ghostPost(slug: { eq: $slug }) {
			title
			slug
			feature_image
			html
		}
	}
`;

Damit werden die Posts dynamisch erstellt.

Dynamische Liste

Als Beispiel möchte ich, dass alle Posts als Link auf der Blogseite gezeigt werden. Dazu verändern wir die blog.js-Datei.

import * as React from "react";
import { graphql, Link } from "gatsby";
import Layout from "../components/layout";

const Blog = ({ data }) => {
	return (
		<Layout pageTitle="Blog">
			<p>Hier könnte ein Blog sein.</p>
			<ul>
				{data.allGhostPost.edges.map(({ node }) => (
					<li>
						<Link to={`/${node.slug}`}>{node.title}</Link>
					</li>
				))}
			</ul>
		</Layout>
	);
};

export default Blog;

export const postSlug = graphql`
	query MyQuery {
		allGhostPost {
			edges {
				node {
					slug
					title
				}
			}
		}
	}
`;

Über die Map-Funktion werden alle Slugs nach dem dazugehörigen Titel durchsucht. Der Titel wird angezeigt, der Link führt selbstverständlich zum Slug.

Veröffentlichen in der Gatsby-Cloud

Repository erstellen

Zunächst benötige ich ein Repository. Dazu nutze ich GitHub. Nach der Anmeldung kann ein neues (privates) Repository erstellt werden.

Lokales Projekt zu Github kopieren

In meinem Gatsby Projekt initiiere ich Git. Für den pull benötige ich die URL des Repositorys.

git init
git pull https://github.com/Benutzername/Name.git
git remote add origin https://github.com/Benutzername/Name.git

In die Git-Ignore-Datei füge ich zumindest .cache, .vscode, node-modules sowie public hinzu, damit diese Dateien oder Verzeichnisse nicht hochgeladen werden.

Vor dem Upload muss Git konfiguriert werden.

git config --global user.name "Github Name"
git config --global user.email eigenemail@gmail.com

Nun alle Dateien auswählen, damit sie in den Staged Changes auftauchen. Über den Haken bestätigen und einen Kommentar schreiben.

Über das Symbol unten können die Änderungen synchronisiert werden.

Anschließend müsste in Github der Code in master-branch zu sehen sein.

Gatsby-Cloud

Jetzt einen kostenlosen Account in der Gatsby-Cloud erstellen. Beim Hinzufügen einer neuen Seite aus einem Github Repository wird ein Webhook angezeigt. Den kopieren wir uns.

Dieser kann wiederum den Integrationen als Custom Integration in Ghost hinzugefügt werden.

Letztlich müsste indessen die Seite erstellt sein.

Unter den Einstellungen lässt sich die eigene Domain hinzufügen.

Die angezeigten DNS-Einstellungen müssen gesetzt werden.

Damit ist die Einrichtung soweit fertig und die Seite ist (eventuell erst nach ein paar Stunden) unter der eigenen Domain erreichbar.


Diese Website verwendet Cookies. Diese sind notwendig, um die Funktionalität der Website zu gewährleisten. Weitere Informationen finden Sie in der Datenschutzerklärung