JavaScript als PHP

Mit JAMstack dynamische Websites mit JavaScript erstellen

04. Januar 2021

6 min

Statisch generierte Websites und dynamischer Inhalt (inkl. einfacher Pflege per CMS) stehen sich nicht im Weg. Das war die große Erkenntnis, die dazu geführt hat, dass ich über die letzten Wochen meine Website neu gemacht habe.

Mein Wissensstand bis vor einigen Wochen war noch folgender:

Eine dynamische Website mit Editor-CMS, bedingt eine Art Server mit Datenbank und CMS-System. Klassischerweise arbeitet man viel mit PHP und erstellt Templates und Snippets etc.

Für jemanden wie mich, der eher aus der Design-Richtung kommt, kommt Kirby als Datei-basiertes CMS einer Traumlösung schon sehr nahe.

Im Gegensatz dazu gibt es Lösungen für statisch generierte Websites, deren Pflege aber recht technisch ist (z.B. in Form von Markdown-Dateien direkt in Git verwaltet).

Die JAMstack Architektur

Bei mir ist das so: Wenn mir ein Begriff über längere Zeit regelmäßig in meinem Twitter-Feed begegnet, dann spricht das dafür, dass ich mich mal damit auseinandersetzen sollte. Genauso war es auch mit JAMstack.

Gesagt, getan, habe ich erkannt, dass es für mich die Lösung für mein Website-Problem ist.

JAM steht für:

  • Javascript
  • APIs
  • Markup

JAMstack ist also eine Art Architektur für Websites, die aus clientseitigem JavaScript, wiederverwendbaren APIs und statisch generiertem Markup besteht.

Das klingt soweit erst mal recht abstrakt, bedeutet aber in der Praxis einfach folgendes:

  1. Die Website wird mit JavaScript Tools gebaut, die man sonst nur mit SPA (Single Page Applications) verbindet (React, Vue.js etc.).
  2. Die daraus entstehenden Websites werden aber nicht als klassische SPA ausgespielt, sondern beim Deploy der Website werden einmalig alle einzelnen Seiten statisch generiert. Die jeweilige SPA-Library wird asynchron geladen und gestartet. Man hat am Ende also das Beste aus beiden Welten. Eine superschnell geladene statische Website und die Power einer SPA.
  3. An dieser Stelle kommen dann auch die APIs, nämlich z.B. in Form eines Headless CMS, ins Spiel. Der Inhalt der dynamischen Website wird einmalig beim Bauen aus dem CMS geladen.

In der Praxis bedeutet das für mich also eine erstklassige Developer-Experience, da ich komplett in JavaScript bleiben kann und nicht zusätzlich mit PHP arbeiten muss. Durch die statische Generation der Seiten hat man zudem eine extrem performante, SEO-optimierte Website, die bei Bedarf auch noch einfach durch Libraries wie React interaktiv gemacht werden kann. Der Inhalt der Website kann jederzeit komfortabel über ein CMS gepflegt werden.

Entwicklen mit Next.js

Nach kurzer Recherche habe ich mich für Next.js als React-Framework entschieden. Es ermöglicht alles, was ich mir als Ziel gesetzt habe und ist dabei etwas freier beim Umgang mit React, als z.B. Gatsby.

Next.js ermöglicht es auf die einfachste Art und Weiße mit React statische Webseiten zu erstellen.

Man muss nur im Ordner pages eine Datei index.js anlegen und dort eine React-Komponente exportieren.

1export default function Home() {
2 return <h1>Hello Word</h1>;
3}
1export default function Home() {
2 return <h1>Hello Word</h1>;
3}

Das ist tatsächlich alles!

Wenn man möchte, müsste man sich ab jetzt nicht mehr mit React beschäftigen und könnte seine Website in dieser Komponente in reinem, altbekanntem HTML schreiben.

Richtig Spaß macht es aber natürlich erst, wenn man seine Seite in wiederverwendbare Komponenten einteilt und weitere Vorteile von React nutzt.

1import Layout from '../components/Layout';
2import Teaser from '../components/Teaser';
3import AboutWidget from '../components/AboutWidget';
4import BlogWidget from '../components/BlogWidget';
5import ContactWidget from '../components/ContactWidget';
6
7export default function Home(props) {
8 return (
9 <Layout
10 title={props.title}
11 description={props.description}
12 previewImage={props.previewImage}>
13 <Teaser text={props.header} />
14 <AboutWidget
15 text={props.aboutTeaser}
16 imageUrl={props.image.url}
17 imageDescription={props.image.description}
18 />
19 <BlogWidget
20 blogPost1={props.blogPosts[0]}
21 blogPost2={props.blogPosts[1]}
22 />
23 <ContactWidget text={props.contact} />
24 </Layout>
25 );
26}
1import Layout from '../components/Layout';
2import Teaser from '../components/Teaser';
3import AboutWidget from '../components/AboutWidget';
4import BlogWidget from '../components/BlogWidget';
5import ContactWidget from '../components/ContactWidget';
6
7export default function Home(props) {
8 return (
9 <Layout
10 title={props.title}
11 description={props.description}
12 previewImage={props.previewImage}>
13 <Teaser text={props.header} />
14 <AboutWidget
15 text={props.aboutTeaser}
16 imageUrl={props.image.url}
17 imageDescription={props.image.description}
18 />
19 <BlogWidget
20 blogPost1={props.blogPosts[0]}
21 blogPost2={props.blogPosts[1]}
22 />
23 <ContactWidget text={props.contact} />
24 </Layout>
25 );
26}

Auf GitHub kannst du dir gerne genau anschauen, wie ich meine Seite aufgebaut habe.

Contentful als Headless CMS

Contentful

Als Headless CMS nutze ich Contentful. Für mich war hier die Herangehensweise, wie man den Inhalt strukturiert, neu.

Früher habe ich den Inhalt im CMS analog zur Informationsarchitektur meiner Website aufgebaut. Es gab also Seiten und diese Seiten hatten Inhalte. In CMS wie Contentful ist das Stichwort aber "strukturierter Inhalt".

Da Inhalt heutzutage nicht mehr nur für eine Plattform genutzt, sondern auf vielen Kanälen (Marketing Website, Social Media Kanäle, Apps) ausgespielt wird, macht man sich mehr Gedanken, wie der Inhalt richtig strukturiert wird und beschäftigt sich dann in der jeweiligen Plattform damit, wie man an den Inhalt kommt und wie er dort verwendet wird. Hierbei ist dann GraphQL ein Segen, sodass man sich supereinfach pro Seite seine Queries für den passenden Inhalt zusammenstellen kann.

Und wie kriegt man jetzt die dynamischen Daten in seine Website? Auch ganz simpel. Next.js stellt eine Funktion getStaticProps() zur Verfügung, in der man die Daten aus seinem CMS laden kann. Ich lade hier z.B. per GraphQL die nötigen Daten aus dem Headless CMS Contentful und übergebe sie als props an meine Seite.

1import { queryContent } from '../lib/content';
2
3export async function getStaticProps() {
4 const content = await queryContent(
5 `{
6 page: pageCollection(where: {slug: "home"}, limit: 1) {
7 items {
8 title
9 slug
10 description
11 previewImage {
12 url
13 description
14 }
15 }
16 },
17 blogPosts: blogPostCollection(order: [date_DESC], limit: 2) {
18 items {
19 title
20 summary
21 slug
22 }
23 }
24 }`
25 );
26
27 return {
28 props: {
29 content
30 }
31 };
32}
1import { queryContent } from '../lib/content';
2
3export async function getStaticProps() {
4 const content = await queryContent(
5 `{
6 page: pageCollection(where: {slug: "home"}, limit: 1) {
7 items {
8 title
9 slug
10 description
11 previewImage {
12 url
13 description
14 }
15 }
16 },
17 blogPosts: blogPostCollection(order: [date_DESC], limit: 2) {
18 items {
19 title
20 summary
21 slug
22 }
23 }
24 }`
25 );
26
27 return {
28 props: {
29 content
30 }
31 };
32}

Serverless Hosting mit Vercel

Vercel

Obwohl man eine Next.js Website überall hosten kann, wo es Node.js gibt, bietet es sich an Vercel zu nutzen. Vercel entwicklet Next.js und hat so sein Hosting darauf spezialisiert. Ohne viel Konfiguration bekommt man Out-of-the-Box:

  • CI/CD und GitHub / GitLab Integration
  • Preview-Umgebungen für jeden Branch und MR
  • Serverless Hosting der statischen Dateien im globalen Edge-Netzwerk

Ich muss sagen, ich bin sehr begeistert wie einfach das Aufsetzten und Nutzen funktioniert. Wo man vorher mit Server, PHP-Versionen, MySQL usw. umgehen musste, ist hier alles zum größten Teil ein Klick.

Wie JavaScript als PHP

Der Weg von Idee zum Veröffentlichen im Web war für mich noch nie schneller und hat noch nie so viel Spaß gemacht.

Tatsächlich fühlt es sich von der Herangehensweise sehr ähnlich an, wie man auf die klassische Art und Weise Websites mit PHP gebaut hat – nur jetzt komplett in JavaScript.

Man bewegt sich hierbei in einer Welt, die gerade viel Momentum hat und sich schnell weiterentwickelt (Javascript, Node JS, React etc.). Das hat viel Potenzial und kann viel Spaß machen, man sollte sich aber natürlich immer darüber bewusst sein, was man für Technologien nutzt, was deren Vor- und Nachteile sind und wie man diese richtig einsetzt. Wer sich auf dem klassischen PHP-Weg wohlfühlt, ist dort natürlich weiterhin gut Zuhause. In der JavaScript Welt fühlt sich auch oft einiges sehr erzwungen und hingebogen an.

Trotzdem bin ich sehr davon gehyped was da so erzwungen und gebogen wird und werde meine Website in nächster Zeit erweitern, um dabei noch die eine oder andere Technologie ausprobieren zu können.

Zusatz: Lokal auf dem iPad

Web-Entwicklung auf dem iPad

Als kleines, zusätzliches Schmankerl ist es durch die gewählten Technologien möglich, die Website komplett lokal auf dem iPad (großer Fan!) zu entwickeln. Das Ganze ist mit der iOS App play.js möglich, da diese eine integrierte Node.js Umgebung mitbringt. Und das ist am Ende alles was man braucht, um die Website lokal laufen zu lassen. Apps, die zusätzlich den Workflow erleichtern:

Kontakt

Wir kennen uns und hatten schon länger keinen Kontakt mehr?

Klingt beruflich interessant und wir sollten mal gemeinsam zu Steuerbot sprechen?

Schreib' mir doch gerne 'ne E-Mail, folge mir oder vernetze dich!