Headless Wordpress mit Vue.js

WordPress als Headless CMS – Überblick & Beispiel mit Vue.js

WordPress, WordPress, überall WordPress. Das beliebte Content Management System macht gut ein Drittel des gesamten Internets aus. Klassische WordPress Entwicklung bietet zweifelsohne diverse Vorzüge – zumindest für bestimmte Anwendungsfälle. Manchmal drängt sich jedoch der Eindruck auf, dass sich viele Betreiber von Websites schon so daran gewöhnt haben, dass die Nutzung von WordPress überhaupt nicht mehr hinterfragt wird. 

Es ist ja auch verführerisch, dass beinahe jeder ohne große Vorkenntnisse innerhalb weniger Minuten ein Backend mit CMS und Datenbankanbindung ans Laufen bringen kann. 

WordPress trägt im Frontend jedoch einen ziemlichen Wasserkopf mit sich rum und hat so durchaus Potential wie ein Bremsklotz auf die Performance einer Seite wirken. Hinzu kommt, dass es die enormen Vorteile in Sachen Speed und User Experience, welche moderne Single Page Applications (SPA) mit sich bringen eben aufgrund der unterliegenden Technik einfach nicht bieten kann.

Schön wäre es doch, wenn man die Vorzüge dieses “Backends für Jedermann” mit einem modernen Frontend Framework wie z.B. Vue.js kombinieren könnte. Und genau da kommt Headless WordPress ins Spiel.

Was ist ein “Headless” CMS bzw. Headless WordPress?

Bei “Headless WordPress” wird lediglich das Backend von WordPress verwendet. Denn das WordPress Entwickler Team geht durchaus mit der Zeit und hat ab der WP Version 4.7.0 eine REST API spendiert, über welche auf die Inhalte der WP Datenbank zugegriffen werden kann. Diese ist ziemlich flink und kann vollständig und sehr einfach gecached werden. Somit hat jede WordPress Installation automatisch einen Zugriffspunkt, über welchen Apps und Websites Inhalte als JSON Daten abrufen können. 

Vorteile von WordPress Headless (vs. WordPress)

  • Webentwickler können sich mehr oder weniger auf Knopfdruck ein einfaches Backend erstellen
  • Benutzer können Inhalte über das gewohnte WordPress Backend pflegen
  • Moderne Frontend Frameworks sorgen für Top Performance und UX
  • Dadurch gibt es mehr gestalterische Freiräume, Interaktivität und Animierbarkeit

Nachteile von Headless WordPress (vs. WordPress)

  • Plugins die das Frontend betreffen sind nicht nutzbar
  • Individuelle Programmierung erforderlich, keine Verwendung Themes für Laien
  • Frontends sind etwas aufwendiger und Anpassungen können nur über Entwickler gemacht werden, nicht auf User Ebene
  • Für SPAs sind zusätzliche Kenntnisse erforderlich (Frontend Frameworks, NPM, Webpack…)

Wann macht  WP Headless Sinn

Die Frage ob und wann die Verwendung von Headless WordPress Sinn macht kann man aus zwei Richtungen stellen:

  1. Ich will eine Single Page Application erstellen und brauche ein einfaches Backend
  2. Ich will auf jeden Fall WordPress verwenden

Bei der ersten Ausgangssituation gilt es zu beleuchten ob ich mit Hilfe von WordPress die Funktionen im Backend realisieren kann, die ich für meine SPA brauche. Im Endeffekt taugt dies ja hauptsächlich um statische Daten zur Verfügung zu stellen, die bequem über das WP CMS gepflegt werden können.

Bei der zweiten Variante geht es letztendlich um die Abwägung der Vor- und Nachteile einer SPA gegenüber einer normalen WordPress Installation, die ich oben schon aufgelistet habe. Auch wenn das natürlich immer von der jeweiligen Umsetzung anhängt kann man grob festhalten, dass SPAs performanter und “lebendiger” umgesetzt werden können und eine bessere User Experience bieten können (z.B. gibt es keinen Break bei einem URL Wechsel). 

Wenn es um eine schicke, schnelle und interaktive Seite geht, kann eine normale WP Installation einer SPA nicht das Wasser reichen. Wenn man dann bei einer Kombination mit Headless WordPress geschickt vorgeht, lässt sich eine SPA auch in vielen Anwendungsfällen sehr bequem im Backend pflegen. Wenn es im Frontend richtig gut werden soll, stößt einfaches WordPress schnell an seine Grenze.

Aber letztendlich hat alles seinen Platz. Schließlich liegt der Ursprung von WordPress ja gerade darin, dass jeder der sich etwas damit beschäftigt eine Website erstellen kann. Der lokale Sportverein wird sicher nicht sein Jahresbudget für eine neue Seite ausgeben wollen. In solchen Fällen bietet WordPress eine solide Grundlage!

Aber auch im professionellen Umfeld wird WordPress häufig verwendet. Meiner Meinung nach ist es gerade bei Contentlastigen Seiten wie Blogs und Magazinen nach wie vor Mittel der Wahl. Zudem bietet es unendlich viele Plug-Ins und Integrationen für alle Einsatzgebiete “von der Stange”. Benötigt man z.B. einen Buchungskalender, so lässt sich das mit einem Plug-In in kürzester Zeit lösen und das für einen Bruchteil der Kosten die bei eine SPA entstanden wären. Ein beschränktes Budget in Verbindung mit aufwendigen Funktionen schließen die Programmierung einer Single Page Application eher aus.

Verbindung zur WordPress REST API herstellen

Wer mit der REST API arbeiten möchte, sollte sich zuallererst mit JSON Daten vertraut machen. Denn genau diese Liefert diese aus, wenn ein entsprechender GET  Http Request gestellt wird. Und zwar grundsätzlich bei jeder WordPressseite. 

Fügt man im Browser die Endung ‘wp-json/wp/v2/posts?’ zur URL eine beliebigen WP Installation hinzu, bekommt man als Antwort alle Posts im JSON Format in den Browser geschrieben. 

Um damit rumzuexperimentieren und sich einen Überblick über die Endpunkte zu verschaffen sollte man anstatt eines Browser jedoch lieber das Tool Postman verwenden, welches neben besserer Übersicht z.B. auch den header anzeigt und andere Requests außer GET ermöglicht.

GET Request mit Vue.js

In Vue.js verwendet man am besten Axios um https-Requests an die API zu senden. Folgender GET Request würde unter Verwendung des “created” Lifecycle-Hooks die kompletten JSON Daten zu den neuesten 10 Posts in die Variable posts schreiben (posts muss dazu vorher unter “data” als Array definiert werden:

created () {
        axios.get('https://meine-website.de/wp-json/wp/v2/posts?' )
        .then(res => {  
		this.posts = res.data
        }
}

Im Template Bereich könnte dann die Überschrift des ersten Posts wie folgt ausgegeben werden:

{{ posts[0].title.rendered }}

POST Request mit Vue.js

Ein Post Request lässt sich mit Axios ebenso leicht realisieren:

methods: {
	postData: function(data) {
		const session_url = "https://meine-seite.de/wp-json/wp/v2/posts"

            axios.post(session_url, data, {
                auth: {
                    username: 'user',
                    password: 'anwendungspasswort'
                }
            }).then( res => {
                alert('Übertragung abgeschlossen')
            });
}	

Die Daten müssen natürlich im entsprechenden Format zur Verfügung gestellt werden.

WordPress Headless Fallstricke im wahren Leben

Caching und Cross Origin Requests (CORS)

Eingangs habe ich das Caching noch als großen Vorteil genannt. Was die Serverantwortzeit betrifft ist das auch definitiv der Fall. Es gibt jedoch Fälle wo Caching bei Headless WordPress problematisch sein kann. Nämlich dann, wenn die Anfragende Single Page Application oder sonstige zugreifende App auf einem anderen Server liegt als die WordPress Installation UND mehr als eine APP auf die REST API zugreifen soll. Das ist dann nämlich ein sogenannter Cross Origin Request (CORS), also eine Anfrage von einer anderen “Herkunft”. 

Aus Sicherheitsgründen blockieren moderne Browser CORS, wenn im Header der Server-Antwort die anfragende URL nicht mit “Access-Control-Allow-Origin” benannt wird. Das ist grundsätzlich erstmal machbar. Dazu sind lediglich ein paar Zeilen Code in der functions.php oder einem Plugin erforderlich. Das könnte z.B. so aussehen:

function cors( $value) {
     $origin_url = 'http://localhost:8080';
     header( 'Access-Control-Allow-Origin: ' . $origin_url );
     header( 'Access-Control-Allow-Methods: GET' );
     header( 'Access-Control-Allow-Credentials: true' );
     return $value;
}
add_action( 'rest_api_init', function() {
     remove_filter( 'rest_pre_serve_request', 'rest_send_cors_headers' );
     add_filter( 'rest_pre_serve_request', 'cors');
}, 15 );

Somit wären Anfragen der URL localhost:8080 möglich. Was aber, wenn  verschiedene URLs die Erlaubnis bekommen sollen? WordPressseitig ist auch das erstmal möglich. Dazu muss nur die anfragende URL über die Funktion get_http_origin() identifiziert und mit einer Liste aller erlaubten URLs verglichen werden. Ist sie enthalten, lasse ich sie per PHP in den Header schreiben:

function cors( $value) {
     $origin = get_http_origin();
     $allowed_origins = [ 'http://localhost:8080', 'http://localhost:3000'' ];
     if ( $origin && in_array( $origin, $allowed_origins ) ) {
          header( 'Access-Control-Allow-Origin: ' . esc_url_raw( $origin ) );
          header( 'Access-Control-Allow-Methods: GET' );
          header( 'Access-Control-Allow-Credentials: true' );
     } 
     return $value;
}

Doch jetzt gibt es einen Unterschied! Bei der ersten Variante gibt es nur einen einzigen möglichen Header. Das bedeutet, dass Script muss nur einmal ausgeführt werden und das Ergebnis kann getrost im Cache abgelegt und bei jeder Anfrage ausgeliefert werden. 

Beim zweiten Fall muss der Header aber dynamisch an die anfragende (erlaubte) Origin angepasst werden. Wird nun aus dem Cache ausgeliefert, wird immer nur eine Origin Domain funktionieren (diejenige die zuerst angefragt hat).

Indem die REST API nicht gecached wird, lässt sich das vermeiden, was natürlich Einbußen in der Geschwindigkeit mitbringt. Eine Lösung wäre unter Umständen verschiedene Apps zu verschiedenen Endpunkten (ggf. Custom Endpoints) zu schicken. 

HTML Render-Funktion

Ein kleines Problem liegt darin, dass der gerenderte Content von WordPress Posts und Pages, welcher über die REST API geholt wird nicht einfach als String ausgegeben werden kann. Dieser enthält nämlich alle escaped HTML Tags, statt die Tags zu rendern.

Zum Glück liefert Vue.js die Lösung für dieses Problemchen mit und man braucht den String nicht mühselig umbauen. Es kann einfach in einen HTML-Tag v-html=’meinContentString’ eingefügt werden. Dann werden alle Tags aus dem String als HTML gerendert.

Authentifizierung

Bei Requests außer GET ist an der REST API eine Authentifizierung nötig. Die wenig elegante aber sehr einfache Lösung dazu wäre die User Daten eines Users mit Schreibrechten mit dem Request zu schicken:

auth: {
       username: 'user',
       password: 'passwort'
}

Würde es einem Bösewicht gelingen dies anzufangen, könnte er sich in unser WordPress Backend einloggen und dort alles machen, was der User mit entsprechenden Rechten darf. 

Eine ebenfalls sehr einfache aber etwas sichere Lösung bietet sich seit WordPress Version 5.7. Seitdem ist es möglich separate Anwendungspasswörter für die REST API zu erzeugen. Diese können per Knopfdruck vom Administrator widerrufen werden und erlauben nur den Zugang über die REST API, kein einloggen als User.

Erstellt werden können diese über das Nutzerprofil eines Administrators.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Responsive Webdesign ?! Zu unseren Projekten kommen Sie über die Navigation