[{"data":1,"prerenderedAt":260},["ShallowReactive",2],{"blog-de-nextjs-13-app-router":3},{"id":4,"title":5,"body":6,"cover":244,"date":245,"description":246,"draft":247,"extension":248,"locale":249,"meta":250,"navigation":251,"path":252,"seo":253,"stem":254,"tags":255,"__hash__":259},"blog\u002Fblog\u002Fde\u002Fnextjs-13-app-router.md","Next.js 13: der App Router verändert alles",{"type":7,"value":8,"toc":240},"minimark",[9,18,23,54,60,63,67,74,227,230,233,236],[10,11,12,13,17],"p",{},"Next.js 13 ist da, und das neue ",[14,15,16],"code",{},"app","-Verzeichnis ist mehr als nur ein weiteres Feature. Es ist ein Bruch mit Gewohnheiten, die ich jahrelang gepflegt habe. Noch ist vieles Beta, und ich gehe behutsam damit um — aber die Richtung ist unverkennbar.",[19,20,22],"h2",{"id":21},"ein-neues-mentales-modell","Ein neues mentales Modell",[10,24,25,26,29,30,33,34,37,38,41,42,45,46,49,50,53],{},"Jahrelang war ",[14,27,28],{},"pages\u002F"," mein Zuhause. Eine Datei, eine Route, dazu ",[14,31,32],{},"getServerSideProps"," oder ",[14,35,36],{},"getStaticProps"," als Datenschicht. Das funktionierte, aber es trennte Dinge, die eigentlich zusammengehören. Der App Router denkt anders. Routen werden zu Ordnern, und in jedem davon leben Bausteine mit klaren Aufgaben: ",[14,39,40],{},"page"," für den Inhalt, ",[14,43,44],{},"layout"," für den Rahmen, ",[14,47,48],{},"loading"," und ",[14,51,52],{},"error"," für die Zustände dazwischen.",[55,56,57],"blockquote",{},[10,58,59],{},"Verschachtelte Layouts sind die stille Revolution: Was umschließt, bleibt bestehen, während sich der Inhalt darin bewegt.",[10,61,62],{},"Diese verschachtelten Layouts sind für mich der eigentliche Gewinn. Eine Navigation, ein Sidebar-Zustand, ein Scrollkontext — all das bleibt erhalten, während der Nutzer zwischen Unterseiten wechselt. Kein Neuaufbau, kein Flackern. Das fühlt sich endlich nach der App an, die ich immer bauen wollte.",[19,64,66],{"id":65},"server-components-ändern-die-statik","Server Components ändern die Statik",[10,68,69,70,73],{},"Der größere Sprung sind die React Server Components. Komponenten rendern standardmäßig auf dem Server, holen ihre Daten direkt dort und schicken nur das Ergebnis ans Frontend. Erst wenn ich Interaktivität brauche, markiere ich eine Komponente mit ",[14,71,72],{},"\"use client\"",".",[75,76,81],"pre",{"className":77,"code":78,"language":79,"meta":80,"style":80},"language-jsx shiki shiki-themes github-light github-dark","\u002F\u002F app\u002Fprojekte\u002Fpage.js — läuft auf dem Server\nasync function Projekte() {\n  const projekte = await getProjekte();\n  return (\n    \u003Cul>\n      {projekte.map((p) => (\n        \u003Cli key={p.id}>{p.titel}\u003C\u002Fli>\n      ))}\n    \u003C\u002Ful>\n  );\n}\n","jsx","",[14,82,83,92,110,132,141,154,177,199,205,215,221],{"__ignoreMap":80},[84,85,88],"span",{"class":86,"line":87},"line",1,[84,89,91],{"class":90},"sJ8bj","\u002F\u002F app\u002Fprojekte\u002Fpage.js — läuft auf dem Server\n",[84,93,95,99,102,106],{"class":86,"line":94},2,[84,96,98],{"class":97},"szBVR","async",[84,100,101],{"class":97}," function",[84,103,105],{"class":104},"sScJk"," Projekte",[84,107,109],{"class":108},"sVt8B","() {\n",[84,111,113,116,120,123,126,129],{"class":86,"line":112},3,[84,114,115],{"class":97},"  const",[84,117,119],{"class":118},"sj4cs"," projekte",[84,121,122],{"class":97}," =",[84,124,125],{"class":97}," await",[84,127,128],{"class":104}," getProjekte",[84,130,131],{"class":108},"();\n",[84,133,135,138],{"class":86,"line":134},4,[84,136,137],{"class":97},"  return",[84,139,140],{"class":108}," (\n",[84,142,144,147,151],{"class":86,"line":143},5,[84,145,146],{"class":108},"    \u003C",[84,148,150],{"class":149},"s9eBZ","ul",[84,152,153],{"class":108},">\n",[84,155,157,160,163,166,169,172,175],{"class":86,"line":156},6,[84,158,159],{"class":108},"      {projekte.",[84,161,162],{"class":104},"map",[84,164,165],{"class":108},"((",[84,167,10],{"class":168},"s4XuR",[84,170,171],{"class":108},") ",[84,173,174],{"class":97},"=>",[84,176,140],{"class":108},[84,178,180,183,186,189,192,195,197],{"class":86,"line":179},7,[84,181,182],{"class":108},"        \u003C",[84,184,185],{"class":149},"li",[84,187,188],{"class":104}," key",[84,190,191],{"class":97},"=",[84,193,194],{"class":108},"{p.id}>{p.titel}\u003C\u002F",[84,196,185],{"class":149},[84,198,153],{"class":108},[84,200,202],{"class":86,"line":201},8,[84,203,204],{"class":108},"      ))}\n",[84,206,208,211,213],{"class":86,"line":207},9,[84,209,210],{"class":108},"    \u003C\u002F",[84,212,150],{"class":149},[84,214,153],{"class":108},[84,216,218],{"class":86,"line":217},10,[84,219,220],{"class":108},"  );\n",[84,222,224],{"class":86,"line":223},11,[84,225,226],{"class":108},"}\n",[10,228,229],{},"Kein separater Data-Fetching-Mechanismus, kein API-Umweg für etwas, das ohnehin auf dem Server lebt. Das Datenholen wandert dorthin, wo die Daten sind. Das weniger JavaScript beim Client ankommt, ist ein angenehmer Nebeneffekt — für die animationslastigen Seiten, die ich gern baue, zählt jedes Kilobyte.",[10,231,232],{},"Ehrlich gesagt sortiere ich meinen Kopf gerade neu. Wann Server, wann Client? Wo verläuft die Grenze? Das braucht Übung, und manche Bibliotheken hinken noch hinterher. Ich würde heute keinen kritischen Kundenrelaunch blind darauf setzen.",[10,234,235],{},"Aber als Ausblick ist das überzeugend. Next.js 13 fragt nicht, wie ich Seiten anders organisiere — es fragt, wo Code eigentlich laufen sollte. Diese Frage wird uns die nächsten Jahre begleiten.",[237,238,239],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}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);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":80,"searchDepth":94,"depth":94,"links":241},[242,243],{"id":21,"depth":94,"text":22},{"id":65,"depth":94,"text":66},null,"2022-10-25","Mit Next.js 13 kommt der App Router und mit ihm React Server Components — ein neues mentales Modell, das meine Sicht auf Routing und Rendering verschiebt.",false,"md","de",{},true,"\u002Fblog\u002Fde\u002Fnextjs-13-app-router",{"title":5,"description":246},"blog\u002Fde\u002Fnextjs-13-app-router",[256,257,258],"Next.js","React","Web","9mn6LgkWEPKlKGGZUy4ycS2KDe3HYNQi1YmEbFMOq_I",1781691286846]