Headless WordPress-distribution: DNS, SSL och AI
Tech
AI
headless CMS
WordPress
Next.js

Headless WordPress-distribution: DNS, SSL och AI

En riktig headless WordPress-distribution kan bryta DNS, SSL, bilder och formulär. Så här fixade jag det i produktion.

Uygar DuzgunUUygar Duzgun
Mar 27, 2026
Uppdaterad 4 apr. 2026
8 min read

Det här är del 2 i min serie om migrering av WordPress utan headless. Headless WordPress deployment är där de verkliga problemen börjar, eftersom DNS, SSL, bilder, formulär och redirects går sönder på olika sätt. I del 1 byggde jag om frontend på en dag med Claude Code, Stitch MCP och Next.js. I den här artikeln visar jag vilka deploymentsproblem jag stötte på, hur jag löste dem, och varför AI fortfarande behövde mänskligt omdöme.

Problemet med headless WordPress deployment som ingen pratar om

Att bygga frontend är den enkla delen. Enligt min erfarenhet blir headless WordPress deployment svårt i samma ögonblick som du delar upp en webbplats i två system: Vercel för frontend och WordPress för backend. Du har inte längre en enkel stack. Du får DNS, certifikat, medie-URL:er, REST-endpoints och administrativ åtkomst som drar åt olika håll.

När `optagonen.se` flyttades till Vercel började varje request som tidigare träffade WordPress istället landa på den nya frontenden. Det bröt GraphQL, uppladdningar, Contact Form 7 och adminåtkomst på en gång. Om du planerar din egen headless WordPress deployment behöver du designa för de brytpunkterna innan du byter DNS.

Jag testade detta i en riktig produktionsmigrering, inte i en sandbox. Lärdomen var tydlig: koden var klar snabbt, men infrastrukturen tog tid.

Dela DNS för en headless WordPress deployment

Den renaste lösningen var att ge WordPress en egen subdomän: `wp.optagonen.se`. Det separerade frontend och backend utan att tvinga mig att reverse-proxy allt genom en enda origin. Det gjorde också arkitekturen lättare att resonera kring när man felsöker SSL och medieleverans.

DomänPekar påSyfte
---------
`optagonen.se`VercelFrontend i Next.js
`wp.optagonen.se`OriginserverWordPress-backend

Jag lade till `wp.optagonen.se` som alias i Hestia, pekade DNS A-posten till origin-IP:t och uppdaterade frontendens miljövariabel:

`WP_URL=https://wp.optagonen.se`
`CF7_FORM_ID=8`
`WP_APP_PASSWORD=...`

Den delen är enkel på pappret. I praktiken exponerade den headless WordPress deployment en kedjereaktion. Varje system som antog den gamla domänen behövde en ny målpunkt.

Headless WordPress deployment och SSL-certifikat som fallerar

Det första som gick sönder var SSL. Det gamla Let's Encrypt-certifikatet täckte bara `optagonen.se` och `www.optagonen.se`, så `https://wp.optagonen.se` misslyckades direkt. Det här är förväntat beteende. Let's Encrypt validerar domänägarskap per hostname, och webbläsaren avvisar anslutningen om certifikatet inte matchar.

Hestias inbyggda förnyelse misslyckades eftersom den fortfarande försökte validera huvuddomänen via HTTP-01, men huvuddomänen pekade nu på Vercel. Certbot misslyckades av en annan anledning: Hestia fångade upp ACME-utmaningen och returnerade sin egen thumbprint istället för Certbots. Det är den typen av konflikt som AI inte kan sluta sig till från första principer. Du behöver veta hur panelen beter sig.

Jag fixade det genom att temporärt flytta Hestias ACME challenge-konfiguration ur nginx include-sökvägen, utfärda ett certifikat endast för `wp.optagonen.se`, och sedan kopiera tillbaka de förnyade filerna till Hestias SSL-katalog. Jag lade också till en renewal hook så att processen fortsätter vara automatisk.

För att få förtroende lutade jag mig mot de officiella dokumenten från Let's Encrypt och Certbot. Det hjälpte mig att bekräfta ACME-flödet innan jag rörde produktionen igen.

Varför headless WordPress deployment avvisade subdomänen

När SSL väl fungerade accepterade WordPress fortfarande inte den nya hosten. Istället för att returnera GraphQL-data omdirigerade den till `/wp-signup.php`. Det berättade för mig att WordPress inte gillade den inkommande host headern.

Lösningen var en enda nginx-direktiv:

`proxy_set_header Host optagonen.se;`

Den raden fick WordPress att bete sig som om requests fortfarande kom från huvuddomänen, medan webbläsaren stannade på `wp.optagonen.se`. I en headless WordPress deployment betyder den här typen av host-normalisering mer än man tror. WordPress är väldigt åsiktsfullt när det gäller site-URL:er.

Jag har sett samma klass av problem dyka upp i andra migreringar också. Frontenden fungerar, backenden svarar, och sedan bryter en felmatchad host header tyst sessionsflödet.

Bilder gick sönder efter headless WordPress deployment

Efter deployen returnerade varje bild ett 502-fel. Det hände eftersom WordPress medie-URL:er fortfarande pekade på `/wp-content/uploads/...`, och de sökvägarna löstes nu mot Vercel istället för originservern. I min setup kom problemet från två ställen: hårdkodade URL:er i statiska filer och dynamiska URL:er som returneras av WPGraphQL.

Jag fixade de hårdkodade URL:erna först. Jag ersatte varje `https://optagonen.se/wp-content/uploads/`-referens med `https://wp.optagonen.se/wp-content/uploads/` över sex filer. Det täckte ungefär 70 bildsökvägar.

Sedan fixade jag de dynamiska GraphQL-URL:erna med en Next.js rewrite:

`/wp-content/uploads/:path*` → `https://wp.optagonen.se/wp-content/uploads/:path*`

Det höll frontenden ren och undvek att skriva om mediedata inuti WordPress. Det gjorde också den headless WordPress deployment mer underhållbar, eftersom webbläsaren fortfarande begär samma sökväg medan servern hanterar proxyn.

Rekommenderat läsning

Om du vill gå djupare i den här typen av systemdesign rekommenderar jag att du läser min AI-powered WordPress migration workflow och mitt multi-agent content pipeline. De inläggen visar hur jag strukturerar infrastruktur- och innehållssystem runt automation.

Kontaktformulär, ID:n och den sista deployment-fällan

Contact Form 7 såg okej ut först, men formuläret slutade fungera eftersom ID:t i frontenden var fel. Standardformulärets ID var `1`, men det riktiga formuläret i WordPress var `8`. En snabb API-koll bekräftade det.

Det var en liten fix, men den spelar roll. I en headless WordPress deployment kan ett enda fel ID göra att ett fungerande formulär ser trasigt ut även när backenden mår bra. Jag satte `CF7_FORM_ID=8` och formuläret kom direkt tillbaka online.

Det är därför jag alltid testar hela flödet manuellt:

Skicka formuläret från den live frontenden.
Kontrollera nätverksrequesten.
Bekräfta svaret i WordPress.
Verifiera att datan når inkorgen eller CRM.

Den sekvensen fångar problem snabbare än att gissa utifrån loggar.

Vad AI hjälpte med och vad den missade

Claude Code hjälpte mig att gå snabbt, men den ersatte inte förståelse. Den hanterade de repetitiva delarna bra: att greppa konfigurationsfiler, generera nginx-snippets, hjälpa med certbot-kommandon och ersätta bild-URL:er i bulk. Den höll också felkedjan i minnet, vilket sparade tid när en fix skapade ett nytt problem.

Men AI kunde inte avgöra hela arkitekturen. Den visste inte att Hestia skulle intercepta ACME-förfrågningar. Den visste inte när man skulle använda en subdomän istället för en reverse proxy. Och den visste inte ordningen på operationerna som skulle undvika downtime.

Rekommenderat läsning

Det är det verkliga värdet av AI i en headless WordPress deployment: den accelererar diagnosen, men du behöver fortfarande den människa som förstår stacken. Jag använder samma princip i mitt arbete med att bygga AI automation systems for e-commerce och i mitt arbete med content pipeline.

Slutlig arkitektur efter deploymenten

Efter fixarna landade stacken i en ren uppdelning:

KomponentPlatsSyfte
---------
Next.js frontendVercelServerar sidor och hanterar routing
WordPress + WPGraphQL`wp.optagonen.se`Content API och medielagring
Contact Form 7`wp.optagonen.se`Formhantering
BildproxyNext.js rewrite-regelRoutar uploads till origin
Frontend SSLVercelAutomatisk hantering
Backend SSLCertbot + renewal hookAuto-förnyade certifikat

Den strukturen är stabil och enkel att felsöka. Den håller också frontenden snabb samtidigt som den bevarar redaktionellt arbetsflöde i WordPress. För en headless WordPress deployment är den balansen målet.

Lärdomar från den här headless WordPress deploymenten

Här är det jag lärde mig från migreringen:

DNS-ändringar bryter mer än man tror, särskilt när en domän nu tjänar två system.
SSL fallerar oftast först, eftersom certifikatvalidering beror på routing.
Serverpaneler och externa ACME-verktyg kan hamna i konflikt om de hanterar samma domän.
Bild-URL:er finns på fler ställen än man tror, inklusive statiska filer och GraphQL-output.
AI är användbart för felsökning, men det kan inte ersätta omdömet kring infrastruktur.

De här lärdomarna kom från en riktig produktionsflytt, inte en handledning. Det är därför jag numera budgeterar lika mycket tid för deployment som för själva bygget.

Slutsats

Headless WordPress deployment är inte svårt på grund av koden. Det är svårt eftersom DNS, SSL, media och host headers alla är beroende av varandra. I den här migreringen fixade jag subdomänsplitten, certifikatvalideringen, bildleveransen och Contact Form 7, och jag lärde mig exakt var AI hjälper och var den slutar.

Om du planerar din egen migrering, läs frontend-ombyggnaden först, testa certifikatflödet tidigt och verifiera varje mediesökväg innan lansering. Kolla sedan den livea sajten, bekräfta formulären och se till att backenden fortfarande beter sig som WordPress förväntar sig.

Om du vill ha fler praktiska genomgångar av deployment, fortsätt läsa de relaterade inläggen och jämför dem med din egen stack. Det är det snabbaste sättet att undvika misstag i din nästa headless WordPress deployment.

Föreslagen bild-alt-text:

Skärmdump av Vercel och WordPress split-arkitektur som visar frontend- och backend-domäner
Hestia kontrollpanel SSL-setup för wp.optagonen.se certifikatförnyelse
Next.js rewrite-regel som mappar WordPress uploads till originservern