[{"data":1,"prerenderedAt":925},["Reactive",2],{"content-/blog/payload":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"locale":10,"draft":6,"date":11,"image":12,"tags":15,"imageLogo":18,"imageLogo2":23,"seoImage":27,"body":29,"_type":920,"_id":921,"_source":922,"_file":923,"_extension":924},"/blog/payload","blog",false,"","Payload CMS – Erfahrungen aus Hostcraft","Code-First-CMS auf Next.js-Basis: moderne Oberfläche, Anpassungsfähigkeit und KI-Kompatibilität – aber auch Serveranforderungen, Deploy und die Abhängigkeit von Next.js","de","2026-09-25T00:00:00.000Z",{"src":13,"alt":14},"/background/background-7.svg","background",[16,17],"tools","cms",{"src":19,"alt":20,"width":21,"left":22},"/logo/payload.svg","payload-logo","45%","10%",{"src":24,"alt":25,"width":26,"right":22},"/logo/payload-icon.svg","payload-icon","20%",{"src":28},"/payload.jpg",{"type":30,"children":31,"toc":904},"root",[32,69,76,81,86,95,101,108,122,127,133,138,201,206,475,496,501,507,512,533,547,553,558,564,570,575,619,632,638,643,755,760,766,787,820,825,831,854,859,877,882,888,893,898],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37,40,50,52,59,61,67],{"type":38,"value":39},"text","Ich habe ",{"type":33,"tag":41,"props":42,"children":47},"a",{"href":43,":target":44,"rel":45},"https://payloadcms.com/","\\_blank",[46],"nofollow",[48],{"type":38,"value":49},"Payload",{"type":38,"value":51}," für ",{"type":33,"tag":41,"props":53,"children":56},{"href":54,":target":44,"rel":55},"https://hostcraft.rentals",[46],[57],{"type":38,"value":58},"Hostcraft",{"type":38,"value":60}," verwendet, eine SaaS-App, mit der Gastgeber von Ferienunterkünften eine eigene Buchungsseite bekommen (mehr dazu in der ",{"type":33,"tag":41,"props":62,"children":64},{"href":63},"/hostcraft",[65],{"type":38,"value":66},"Fallstudie",{"type":38,"value":68},"). Payload 3 läuft dort zusammen mit Next.js 16 und Postgres. Zeit für ein ehrliches Fazit.",{"type":33,"tag":70,"props":71,"children":73},"h2",{"id":72},"was-ist-payload",[74],{"type":38,"value":75},"Was ist Payload?",{"type":33,"tag":34,"props":77,"children":78},{},[79],{"type":38,"value":80},"Payload ist ein Open-Source-CMS (MIT-Lizenz), das komplett in TypeScript konfiguriert wird. Collections, Felder, Zugriffsrechte und Hooks werden nicht im Backend zusammengeklickt, sondern als Code im Projekt definiert. Aus dieser Konfiguration erzeugt Payload automatisch das Admin-Panel, eine REST- und GraphQL-API und eine typisierte Local API für den direkten Zugriff vom Server aus.",{"type":33,"tag":34,"props":82,"children":83},{},[84],{"type":38,"value":85},"Seit Version 3 ist Payload kein eigener Server mehr, sondern wird direkt in eine Next.js-App installiert. Admin-Panel, API und Frontend laufen im selben Projekt und im selben Prozess. Als Datenbank stehen Postgres, MongoDB und SQLite zur Verfügung, bei Hostcraft ist es Postgres.",{"type":33,"tag":34,"props":87,"children":88},{},[89],{"type":33,"tag":90,"props":91,"children":94},"img",{"alt":92,"src":93},"Das Payload Admin-Panel in Hostcraft","/images/blog/payload.webp",[],{"type":33,"tag":70,"props":96,"children":98},{"id":97},"vorteile",[99],{"type":38,"value":100},"Vorteile",{"type":33,"tag":102,"props":103,"children":105},"h3",{"id":104},"moderne-oberfläche",[106],{"type":38,"value":107},"Moderne Oberfläche",{"type":33,"tag":34,"props":109,"children":110},{},[111,113,120],{"type":38,"value":112},"Das Admin-Panel ist schnell, aufgeräumt und bringt Dark Mode, Tabs, Relationship-Felder, Medien-Bibliothek, Versionen und Mehrsprachigkeit mit. Bei Hostcraft sind viele Texte pro Sprache (Deutsch, Englisch, Kroatisch) pflegbar, dafür reicht ein ",{"type":33,"tag":114,"props":115,"children":117},"code",{"className":116},[],[118],{"type":38,"value":119},"localized: true",{"type":38,"value":121}," am Feld, und im Backend erscheint automatisch der Sprachumschalter.",{"type":33,"tag":34,"props":123,"children":124},{},[125],{"type":38,"value":126},"Die Oberfläche stammt aus der Konfiguration, es gibt also keinen separaten Admin-Code, der gepflegt werden muss. Neue Felder erscheinen sofort im Backend.",{"type":33,"tag":102,"props":128,"children":130},{"id":129},"anpassungsfähigkeit",[131],{"type":38,"value":132},"Anpassungsfähigkeit",{"type":33,"tag":34,"props":134,"children":135},{},[136],{"type":38,"value":137},"Payload gibt kaum Struktur vor. Man baut die Inhaltsmodelle selbst, und alles lässt sich erweitern:",{"type":33,"tag":139,"props":140,"children":141},"ul",{},[142,161,171,181,191],{"type":33,"tag":143,"props":144,"children":145},"li",{},[146,152,154,159],{"type":33,"tag":147,"props":148,"children":149},"strong",{},[150],{"type":38,"value":151},"Collections",{"type":38,"value":153}," und ",{"type":33,"tag":147,"props":155,"children":156},{},[157],{"type":38,"value":158},"Felder",{"type":38,"value":160}," (Gruppen, Tabs, Relationen, Selects, Uploads …)",{"type":33,"tag":143,"props":162,"children":163},{},[164,169],{"type":33,"tag":147,"props":165,"children":166},{},[167],{"type":38,"value":168},"Access Control",{"type":38,"value":170}," auf Collection- und Feld-Ebene, auch mit Filtern pro Benutzer",{"type":33,"tag":143,"props":172,"children":173},{},[174,179],{"type":33,"tag":147,"props":175,"children":176},{},[177],{"type":38,"value":178},"Hooks",{"type":38,"value":180},", die vor und nach dem Speichern laufen",{"type":33,"tag":143,"props":182,"children":183},{},[184,189],{"type":33,"tag":147,"props":185,"children":186},{},[187],{"type":38,"value":188},"Eigene React-Komponenten",{"type":38,"value":190}," im Admin-Panel, zum Beispiel Dashboards oder komplett eigene Views",{"type":33,"tag":143,"props":192,"children":193},{},[194,199],{"type":33,"tag":147,"props":195,"children":196},{},[197],{"type":38,"value":198},"Auth",{"type":38,"value":200}," mit Rollen, Sperre nach Fehlversuchen und Passwort-Reset, bereits eingebaut",{"type":33,"tag":34,"props":202,"children":203},{},[204],{"type":38,"value":205},"Bei Hostcraft hat jeder Gastgeber nur Zugriff auf seine eigenen Unterkünfte, Webseiten und Buchungen. Das ist keine eigene Berechtigungslogik, sondern ein paar Zeilen Access Control:",{"type":33,"tag":207,"props":208,"children":212},"pre",{"className":209,"code":210,"language":211,"meta":7,"style":7},"language-ts shiki shiki-themes dracula","export const ownSiteOrOperator: Access = ({ req: { user } }) => {\n  if (!user) return false\n  if (isOperator(user)) return true\n\n  const hostId = getUserHostId(user)\n  if (!hostId) return false\n\n  // Hosts only see sites that belong to them\n  return { host: { equals: hostId } }\n}\n","ts",[213],{"type":33,"tag":114,"props":214,"children":215},{"__ignoreMap":7},[216,282,317,348,358,387,416,424,434,466],{"type":33,"tag":217,"props":218,"children":221},"span",{"class":219,"line":220},"line",1,[222,228,233,239,244,250,255,261,267,272,277],{"type":33,"tag":217,"props":223,"children":225},{"style":224},"--shiki-default:#FF79C6",[226],{"type":38,"value":227},"export",{"type":33,"tag":217,"props":229,"children":230},{"style":224},[231],{"type":38,"value":232}," const",{"type":33,"tag":217,"props":234,"children":236},{"style":235},"--shiki-default:#50FA7B",[237],{"type":38,"value":238}," ownSiteOrOperator",{"type":33,"tag":217,"props":240,"children":241},{"style":224},[242],{"type":38,"value":243},":",{"type":33,"tag":217,"props":245,"children":247},{"style":246},"--shiki-default:#8BE9FD;--shiki-default-font-style:italic",[248],{"type":38,"value":249}," Access",{"type":33,"tag":217,"props":251,"children":252},{"style":224},[253],{"type":38,"value":254}," =",{"type":33,"tag":217,"props":256,"children":258},{"style":257},"--shiki-default:#F8F8F2",[259],{"type":38,"value":260}," ({ req: { ",{"type":33,"tag":217,"props":262,"children":264},{"style":263},"--shiki-default:#FFB86C;--shiki-default-font-style:italic",[265],{"type":38,"value":266},"user",{"type":33,"tag":217,"props":268,"children":269},{"style":257},[270],{"type":38,"value":271}," } }) ",{"type":33,"tag":217,"props":273,"children":274},{"style":224},[275],{"type":38,"value":276},"=>",{"type":33,"tag":217,"props":278,"children":279},{"style":257},[280],{"type":38,"value":281}," {\n",{"type":33,"tag":217,"props":283,"children":285},{"class":219,"line":284},2,[286,291,296,301,306,311],{"type":33,"tag":217,"props":287,"children":288},{"style":224},[289],{"type":38,"value":290},"  if",{"type":33,"tag":217,"props":292,"children":293},{"style":257},[294],{"type":38,"value":295}," (",{"type":33,"tag":217,"props":297,"children":298},{"style":224},[299],{"type":38,"value":300},"!",{"type":33,"tag":217,"props":302,"children":303},{"style":257},[304],{"type":38,"value":305},"user) ",{"type":33,"tag":217,"props":307,"children":308},{"style":224},[309],{"type":38,"value":310},"return",{"type":33,"tag":217,"props":312,"children":314},{"style":313},"--shiki-default:#BD93F9",[315],{"type":38,"value":316}," false\n",{"type":33,"tag":217,"props":318,"children":320},{"class":219,"line":319},3,[321,325,329,334,339,343],{"type":33,"tag":217,"props":322,"children":323},{"style":224},[324],{"type":38,"value":290},{"type":33,"tag":217,"props":326,"children":327},{"style":257},[328],{"type":38,"value":295},{"type":33,"tag":217,"props":330,"children":331},{"style":235},[332],{"type":38,"value":333},"isOperator",{"type":33,"tag":217,"props":335,"children":336},{"style":257},[337],{"type":38,"value":338},"(user)) ",{"type":33,"tag":217,"props":340,"children":341},{"style":224},[342],{"type":38,"value":310},{"type":33,"tag":217,"props":344,"children":345},{"style":313},[346],{"type":38,"value":347}," true\n",{"type":33,"tag":217,"props":349,"children":351},{"class":219,"line":350},4,[352],{"type":33,"tag":217,"props":353,"children":355},{"emptyLinePlaceholder":354},true,[356],{"type":38,"value":357},"\n",{"type":33,"tag":217,"props":359,"children":361},{"class":219,"line":360},5,[362,367,372,377,382],{"type":33,"tag":217,"props":363,"children":364},{"style":224},[365],{"type":38,"value":366},"  const",{"type":33,"tag":217,"props":368,"children":369},{"style":257},[370],{"type":38,"value":371}," hostId ",{"type":33,"tag":217,"props":373,"children":374},{"style":224},[375],{"type":38,"value":376},"=",{"type":33,"tag":217,"props":378,"children":379},{"style":235},[380],{"type":38,"value":381}," getUserHostId",{"type":33,"tag":217,"props":383,"children":384},{"style":257},[385],{"type":38,"value":386},"(user)\n",{"type":33,"tag":217,"props":388,"children":390},{"class":219,"line":389},6,[391,395,399,403,408,412],{"type":33,"tag":217,"props":392,"children":393},{"style":224},[394],{"type":38,"value":290},{"type":33,"tag":217,"props":396,"children":397},{"style":257},[398],{"type":38,"value":295},{"type":33,"tag":217,"props":400,"children":401},{"style":224},[402],{"type":38,"value":300},{"type":33,"tag":217,"props":404,"children":405},{"style":257},[406],{"type":38,"value":407},"hostId) ",{"type":33,"tag":217,"props":409,"children":410},{"style":224},[411],{"type":38,"value":310},{"type":33,"tag":217,"props":413,"children":414},{"style":313},[415],{"type":38,"value":316},{"type":33,"tag":217,"props":417,"children":419},{"class":219,"line":418},7,[420],{"type":33,"tag":217,"props":421,"children":422},{"emptyLinePlaceholder":354},[423],{"type":38,"value":357},{"type":33,"tag":217,"props":425,"children":427},{"class":219,"line":426},8,[428],{"type":33,"tag":217,"props":429,"children":431},{"style":430},"--shiki-default:#6272A4",[432],{"type":38,"value":433},"  // Hosts only see sites that belong to them\n",{"type":33,"tag":217,"props":435,"children":437},{"class":219,"line":436},9,[438,443,448,452,457,461],{"type":33,"tag":217,"props":439,"children":440},{"style":224},[441],{"type":38,"value":442},"  return",{"type":33,"tag":217,"props":444,"children":445},{"style":257},[446],{"type":38,"value":447}," { host",{"type":33,"tag":217,"props":449,"children":450},{"style":224},[451],{"type":38,"value":243},{"type":33,"tag":217,"props":453,"children":454},{"style":257},[455],{"type":38,"value":456}," { equals",{"type":33,"tag":217,"props":458,"children":459},{"style":224},[460],{"type":38,"value":243},{"type":33,"tag":217,"props":462,"children":463},{"style":257},[464],{"type":38,"value":465}," hostId } }\n",{"type":33,"tag":217,"props":467,"children":469},{"class":219,"line":468},10,[470],{"type":33,"tag":217,"props":471,"children":472},{"style":257},[473],{"type":38,"value":474},"}\n",{"type":33,"tag":34,"props":476,"children":477},{},[478,480,486,488,494],{"type":38,"value":479},"Die Funktion gibt entweder ",{"type":33,"tag":114,"props":481,"children":483},{"className":482},[],[484],{"type":38,"value":485},"true",{"type":38,"value":487},"/",{"type":33,"tag":114,"props":489,"children":491},{"className":490},[],[492],{"type":38,"value":493},"false",{"type":38,"value":495}," oder einen Filter zurück, den Payload direkt in die Datenbankabfrage übernimmt. Für ein Multi-Tenant-System wie Hostcraft ist das sehr praktisch.",{"type":33,"tag":34,"props":497,"children":498},{},[499],{"type":38,"value":500},"Weil man die Local API auch außerhalb des Admin-Panels nutzen kann, sind Payload und die eigene App nicht getrennt. Das öffentliche Frontend, das Gastgeber-Dashboard und die Buchungslogik lesen und schreiben direkt in dieselben Collections. Das Admin-Panel selbst nutze ich nur als Betreiber. Die Gastgeber bekommen ein eigenes, einfacheres Dashboard, das ich selbst gebaut habe.",{"type":33,"tag":102,"props":502,"children":504},{"id":503},"ki-kompatibilität",[505],{"type":38,"value":506},"KI-Kompatibilität",{"type":33,"tag":34,"props":508,"children":509},{},[510],{"type":38,"value":511},"Auch hier hat mich der Code-First-Ansatz überzeugt. Das ganze Datenmodell steht in TypeScript-Dateien im Repository. Ein KI-Assistent im Editor sieht Collections, Felder, Access Control und Hooks, ohne dass er ein Backend bedienen oder eine Datenbank untersuchen muss. Neue Felder, Collections oder Berechtigungen lassen sich per Prompt ergänzen, und alles ist als Git-Diff nachvollziehbar.",{"type":33,"tag":34,"props":513,"children":514},{},[515,517,523,525,531],{"type":38,"value":516},"Dazu kommt ",{"type":33,"tag":114,"props":518,"children":520},{"className":519},[],[521],{"type":38,"value":522},"payload generate:types",{"type":38,"value":524},": Aus der Konfiguration entsteht eine ",{"type":33,"tag":114,"props":526,"children":528},{"className":527},[],[529],{"type":38,"value":530},"payload-types.ts",{"type":38,"value":532}," mit allen Typen. Der Assistent bekommt damit präzises Feedback vom TypeScript-Compiler, wenn er ein Feld falsch benutzt. Das ist ein großer Unterschied zu CMS-Systemen, bei denen das Schema irgendwo in der Datenbank steckt.",{"type":33,"tag":34,"props":534,"children":535},{},[536,538,545],{"type":38,"value":537},"Außerdem gibt es ein offizielles ",{"type":33,"tag":41,"props":539,"children":542},{"href":540,":target":44,"rel":541},"https://payloadcms.com/docs/plugins/mcp",[46],[543],{"type":38,"value":544},"MCP-Plugin",{"type":38,"value":546},", über das KI-Clients Inhalte lesen und anlegen können, natürlich unter Beachtung der Access Control. Das habe ich bisher nicht ausprobiert, es ist aber ein gutes Zeichen, dass Payload den Weg ernsthaft weitergeht.",{"type":33,"tag":102,"props":548,"children":550},{"id":549},"kostenlos-ohne-lizenzmodell",[551],{"type":38,"value":552},"Kostenlos, ohne Lizenzmodell",{"type":33,"tag":34,"props":554,"children":555},{},[556],{"type":38,"value":557},"Payload ist MIT-lizenziert. Es gibt keine Pro-Version, keine Preise pro Site und keine Einschränkung auf einen Benutzer. Für ein SaaS-Produkt, bei dem viele Gastgeber auf derselben Installation arbeiten, ist das ein echtes Argument.",{"type":33,"tag":70,"props":559,"children":561},{"id":560},"nachteile",[562],{"type":38,"value":563},"Nachteile",{"type":33,"tag":102,"props":565,"children":567},{"id":566},"serveranforderungen",[568],{"type":38,"value":569},"Serveranforderungen",{"type":33,"tag":34,"props":571,"children":572},{},[573],{"type":38,"value":574},"Payload ist keine statische Seite und kein klassisches PHP-CMS. Es braucht einen dauerhaft laufenden Node.js-Prozess und eine Datenbank. Billiges Shared Hosting ist damit raus, ein VPS (bei Hostcraft ein Server bei Hetzner) ist das Minimum.",{"type":33,"tag":139,"props":576,"children":577},{},[578,583,588,593,606],{"type":33,"tag":143,"props":579,"children":580},{},[581],{"type":38,"value":582},"Node.js 22, bei mir mit pm2 als Prozess-Manager",{"type":33,"tag":143,"props":584,"children":585},{},[586],{"type":38,"value":587},"Postgres (oder MongoDB bzw. SQLite)",{"type":33,"tag":143,"props":589,"children":590},{},[591],{"type":38,"value":592},"Ein Reverse Proxy, der SSL übernimmt",{"type":33,"tag":143,"props":594,"children":595},{},[596,598,604],{"type":38,"value":597},"Genug Arbeitsspeicher für ",{"type":33,"tag":114,"props":599,"children":601},{"className":600},[],[602],{"type":38,"value":603},"next build",{"type":38,"value":605},", denn bei mir wird auf dem Server gebaut und das Admin-Panel kommt zum Build noch dazu",{"type":33,"tag":143,"props":607,"children":608},{},[609,611,617],{"type":38,"value":610},"Persistenter Speicher für hochgeladene Dateien (bei mir ein ",{"type":33,"tag":114,"props":612,"children":614},{"className":613},[],[615],{"type":38,"value":616},"media/",{"type":38,"value":618},"-Ordner), solange man keinen S3-Speicher anbindet",{"type":33,"tag":34,"props":620,"children":621},{},[622,624,630],{"type":38,"value":623},"Auch lokal ist der Aufwand höher als bei einer Markdown-basierten Seite. Ich starte Postgres per Container, und allein die ",{"type":33,"tag":114,"props":625,"children":627},{"className":626},[],[628],{"type":38,"value":629},"node_modules",{"type":38,"value":631}," sind rund 2 GB groß. Für eine kleine Visitenkarten-Seite ist Payload deshalb überdimensioniert.",{"type":33,"tag":102,"props":633,"children":635},{"id":634},"deploy-ein-bedingter-nachteil",[636],{"type":38,"value":637},"Deploy – ein bedingter Nachteil",{"type":33,"tag":34,"props":639,"children":640},{},[641],{"type":38,"value":642},"Im Alltag läuft das Deployment bei mir per GitHub Actions: Code holen, Abhängigkeiten installieren, Datenbank sichern, Migrationen ausführen, bauen, Prozess neu laden. Das ist kein Payload-spezifisches Problem, sondern normaler Alltag bei einer Node-App mit Datenbank. Trotzdem gab es Punkte, die man kennen sollte:",{"type":33,"tag":139,"props":644,"children":645},{},[646,671,704,729],{"type":33,"tag":143,"props":647,"children":648},{},[649,654,656,662,663,669],{"type":33,"tag":147,"props":650,"children":651},{},[652],{"type":38,"value":653},"Schema-Push vs. Migrationen:",{"type":38,"value":655}," Im Entwicklungsmodus gleicht Payload die Datenbank automatisch an die Konfiguration an. Produktion braucht dagegen echte Migrationen (",{"type":33,"tag":114,"props":657,"children":659},{"className":658},[],[660],{"type":38,"value":661},"payload migrate:create",{"type":38,"value":153},{"type":33,"tag":114,"props":664,"children":666},{"className":665},[],[667],{"type":38,"value":668},"payload migrate",{"type":38,"value":670},"). Wer das vergisst, merkt es erst beim Deploy.",{"type":33,"tag":143,"props":672,"children":673},{},[674,679,681,687,689,695,697,702],{"type":33,"tag":147,"props":675,"children":676},{},[677],{"type":38,"value":678},"Der Marker aus dem Dev-Push:",{"type":38,"value":680}," Der lokale Push hinterlässt einen Eintrag in ",{"type":33,"tag":114,"props":682,"children":684},{"className":683},[],[685],{"type":38,"value":686},"payload_migrations",{"type":38,"value":688}," (mit ",{"type":33,"tag":114,"props":690,"children":692},{"className":691},[],[693],{"type":38,"value":694},"batch = -1",{"type":38,"value":696},"). Danach fragt ",{"type":33,"tag":114,"props":698,"children":700},{"className":699},[],[701],{"type":38,"value":668},{"type":38,"value":703}," interaktiv nach einer Bestätigung und hängt im SSH-Deploy, bis der Timeout greift. Bei mir entfernt das Deploy-Skript diesen Eintrag vor der Migration.",{"type":33,"tag":143,"props":705,"children":706},{},[707,712,714,719,721,727],{"type":33,"tag":147,"props":708,"children":709},{},[710],{"type":38,"value":711},"Inhalte gehören zur Datenbank:",{"type":38,"value":713}," Anders als bei einem Flat-File-CMS lassen sich Inhalte nicht per Git verschieben. Für den Start habe ich ein Skript, das Datenbank und ",{"type":33,"tag":114,"props":715,"children":717},{"className":716},[],[718],{"type":38,"value":616},{"type":38,"value":720},"-Ordner lokal sichert und auf den Server überträgt. Dafür müssen Git-Revision und ",{"type":33,"tag":114,"props":722,"children":724},{"className":723},[],[725],{"type":38,"value":726},"PAYLOAD_SECRET",{"type":38,"value":728}," zusammenpassen.",{"type":33,"tag":143,"props":730,"children":731},{},[732,737,739,745,747,753],{"type":33,"tag":147,"props":733,"children":734},{},[735],{"type":38,"value":736},"Content Security Policy:",{"type":38,"value":738}," Das Admin-Panel braucht in Produktion ",{"type":33,"tag":114,"props":740,"children":742},{"className":741},[],[743],{"type":38,"value":744},"unsafe-eval",{"type":38,"value":746},". Die strenge CSP für die öffentliche Seite muss man für ",{"type":33,"tag":114,"props":748,"children":750},{"className":749},[],[751],{"type":38,"value":752},"/admin",{"type":38,"value":754}," deshalb getrennt konfigurieren.",{"type":33,"tag":34,"props":756,"children":757},{},[758],{"type":38,"value":759},"Hat man das einmal sauber aufgesetzt, läuft es zuverlässig. Neue Projekte sollten Migrationen aber von Anfang an einplanen und nicht erst vor dem ersten Release.",{"type":33,"tag":102,"props":761,"children":763},{"id":762},"abhängigkeit-von-nextjs",[764],{"type":38,"value":765},"Abhängigkeit von Next.js",{"type":33,"tag":34,"props":767,"children":768},{},[769,771,777,779,785],{"type":38,"value":770},"Payload 3 ist eng mit Next.js verzahnt. Das Admin-Panel ist eine Next-App, die Konfiguration wird über ",{"type":33,"tag":114,"props":772,"children":774},{"className":773},[],[775],{"type":38,"value":776},"withPayload",{"type":38,"value":778}," in ",{"type":33,"tag":114,"props":780,"children":782},{"className":781},[],[783],{"type":38,"value":784},"next.config.ts",{"type":38,"value":786}," eingebunden, und die Versionen von Payload und Next müssen zusammenpassen. Dadurch gilt:",{"type":33,"tag":139,"props":788,"children":789},{},[790,800,810],{"type":33,"tag":143,"props":791,"children":792},{},[793,798],{"type":33,"tag":147,"props":794,"children":795},{},[796],{"type":38,"value":797},"Next-Updates und Payload-Updates müssen zusammenpassen.",{"type":38,"value":799}," Next bringt regelmäßig Breaking Changes mit, und Payload veröffentlicht sehr häufig neue Versionen. Updates sollte man deshalb bewusst einplanen.",{"type":33,"tag":143,"props":801,"children":802},{},[803,808],{"type":33,"tag":147,"props":804,"children":805},{},[806],{"type":38,"value":807},"React ist Pflicht.",{"type":38,"value":809}," Wer sonst Vue und Nuxt nutzt, so wie ich bei den meisten Projekten, kann Payload zwar headless verwenden, betreibt dann aber trotzdem eine Next-App nur für das Backend.",{"type":33,"tag":143,"props":811,"children":812},{},[813,818],{"type":33,"tag":147,"props":814,"children":815},{},[816],{"type":38,"value":817},"Der Lock-in ist spürbar.",{"type":38,"value":819}," Die Local API und die Admin-Komponenten sind eng mit der Next-App verzahnt. Ein späterer Wechsel des Frontends ist möglich, aber nicht trivial.",{"type":33,"tag":34,"props":821,"children":822},{},[823],{"type":38,"value":824},"Wer ohnehin mit Next.js arbeitet, hat davon dagegen fast nur Vorteile: ein Repository, ein Deployment, geteilte Typen.",{"type":33,"tag":102,"props":826,"children":828},{"id":827},"unsicherheit-durch-die-übernahme-von-figma",[829],{"type":38,"value":830},"Unsicherheit durch die Übernahme von Figma",{"type":33,"tag":34,"props":832,"children":833},{},[834,836,843,845,852],{"type":38,"value":835},"Im Juni 2025 hat Figma das Payload-Team übernommen (",{"type":33,"tag":41,"props":837,"children":840},{"href":838,":target":44,"rel":839},"https://www.figma.com/blog/payload-joins-figma/",[46],[841],{"type":38,"value":842},"Ankündigung von Figma",{"type":38,"value":844},", ",{"type":33,"tag":41,"props":846,"children":849},{"href":847,":target":44,"rel":848},"https://payloadcms.com/posts/blog/payload-is-joining-figma",[46],[850],{"type":38,"value":851},"Ankündigung von Payload",{"type":38,"value":853},"). Beide Seiten versprechen, dass Payload Open Source und selbst hostbar bleibt, dass das Team weiter an Payload arbeitet und dass sich für bestehende Nutzer zunächst nichts ändert.",{"type":33,"tag":34,"props":855,"children":856},{},[857],{"type":38,"value":858},"Das ist beruhigend, aber „zunächst“ ist das entscheidende Wort. Figma entwickelt ein eigenes CMS, und Payload soll dafür die Grundlage liefern. Die Roadmap von Payload hängt damit künftig auch von den Interessen eines großen Unternehmens ab, und das lässt sich von außen nicht einschätzen:",{"type":33,"tag":139,"props":860,"children":861},{},[862,867,872],{"type":33,"tag":143,"props":863,"children":864},{},[865],{"type":38,"value":866},"Entwickelt Figma den Open-Source-Kern weiter oder wandert der Fokus in kommerzielle Produkte?",{"type":33,"tag":143,"props":868,"children":869},{},[870],{"type":38,"value":871},"Bleibt die MIT-Lizenz auf Dauer bestehen?",{"type":33,"tag":143,"props":873,"children":874},{},[875],{"type":38,"value":876},"Wie lange werden Funktionen, die ich heute nutze, im Kern weiterentwickelt?",{"type":33,"tag":34,"props":878,"children":879},{},[880],{"type":38,"value":881},"Bisher gibt es keinen Grund zur Panik, denn der Kern ist weiterhin MIT-lizenziert und wird aktiv gepflegt. Trotzdem sollte man diese Unsicherheit bei der Wahl für ein langlebiges Projekt mit einkalkulieren. Das Risiko ist überschaubar, weil Daten in Postgres und die Konfiguration in TypeScript liegen und sich im Zweifel auch ohne Payload weiterverwenden lassen. Aufwand wäre ein Wechsel trotzdem.",{"type":33,"tag":70,"props":883,"children":885},{"id":884},"fazit",[886],{"type":38,"value":887},"Fazit",{"type":33,"tag":34,"props":889,"children":890},{},[891],{"type":38,"value":892},"Payload ist für mich das CMS, das am besten zu Next.js-Projekten passt und das ich für Web-Apps mit echter Logik, Benutzerrollen und mehreren Mandanten wieder einsetzen würde. Das Admin-Panel ist modern, das Datenmodell lässt sich beliebig anpassen, und weil alles in TypeScript liegt, arbeitet man hervorragend mit KI-Assistenten.",{"type":33,"tag":34,"props":894,"children":895},{},[896],{"type":38,"value":897},"Die Nachteile sind überschaubar, aber real: ein eigener Server mit Node.js und Datenbank, ein Deployment mit sauberen Migrationen, die enge Bindung an Next.js und die offene Frage, wohin sich Payload unter Figma entwickelt. Für einfache Seiten, bei denen die Redaktion nur ein paar Texte ändert, gibt es leichtere Lösungen. Für ein Produkt wie Hostcraft war Payload die richtige Wahl.",{"type":33,"tag":899,"props":900,"children":901},"style",{},[902],{"type":38,"value":903},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":284,"depth":284,"links":905},[906,907,913,919],{"id":72,"depth":284,"text":75},{"id":97,"depth":284,"text":100,"children":908},[909,910,911,912],{"id":104,"depth":319,"text":107},{"id":129,"depth":319,"text":132},{"id":503,"depth":319,"text":506},{"id":549,"depth":319,"text":552},{"id":560,"depth":284,"text":563,"children":914},[915,916,917,918],{"id":566,"depth":319,"text":569},{"id":634,"depth":319,"text":637},{"id":762,"depth":319,"text":765},{"id":827,"depth":319,"text":830},{"id":884,"depth":284,"text":887},"markdown","content:blog:payload.md","content","blog/payload.md","md",1791545016478]