[{"data":1,"prerenderedAt":1763},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fen\u002Ftech\u002Fserver-components-vs-client-drawing-the-right-line-in-2026":13},{"i18nKey":4,"paths":5},"tech-008-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Ftech\u002Fserver-komponenten-vs-client-2026-die-richtige-grenzziehung","\u002Fen\u002Ftech\u002Fserver-components-vs-client-drawing-the-right-line-in-2026","\u002Fes\u002Ftech\u002Fserver-components-vs-client-dibujar-la-linea-correcta-en-2026","\u002Ffr\u002Ftech\u002Fserver-components-vs-client-2026-tracer-la-bonne-ligne","\u002Fit\u002Ftech\u002Fserver-components-vs-client-2026-il-giusto-equilibrio","\u002Fru\u002Ftech\u002Fserver-components-vs-client-2026-drawing-the-line","\u002Ftr\u002Ftech\u002Fserver-components-vs-client-2026da-dogru-cizgiyi-cizmek",{"_path":7,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":1757,"_id":1758,"_source":1759,"_file":1760,"_stem":1761,"_extension":1762},"tech",false,"","Server Components vs Client: Drawing the Right Line in 2026","React Server Components and Vue 3.5 server-first architecture migration: hydration costs, bundle tradeoffs, and decision criteria with benchmark data.","2026-07-02",[21,22,23,24,25],"react-server-components","vue-composition","hydration-optimization","server-first-architecture","web-performance",8,"Roibase",{"type":29,"children":30,"toc":1747},"root",[31,48,55,60,65,70,76,96,533,577,584,597,634,1128,1140,1146,1151,1167,1288,1301,1307,1312,1321,1346,1354,1377,1385,1398,1403,1409,1414,1438,1443,1448,1657,1662,1668,1673,1731,1736,1741],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,46],{"type":37,"value":38},"text","In the second half of 2026, the central question in frontend engineering decisions is this: which state will you keep on the server, and which on the client? React Server Components (RSC) moved from beta in 2023 to production with Next.js 13 App Router. Vue 3.5 added ",{"type":32,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":37,"value":45},"\u003Cscript setup server>",{"type":37,"value":47}," support in its composition API. Svelte 5 stabilized its runes system. By 2026, the question is no longer \"should I use server components?\" but rather \"what can I move to the server to lower hydration cost without breaking UX?\" This article provides practical criteria, benchmark results, and a tradeoff map to draw that line correctly.",{"type":32,"tag":49,"props":50,"children":52},"h2",{"id":51},"the-economics-of-server-first-architecture-tbt-and-bundle-tradeoff",[53],{"type":37,"value":54},"The Economics of Server-First Architecture: TBT and Bundle Tradeoff",{"type":32,"tag":33,"props":56,"children":57},{},[58],{"type":37,"value":59},"The core promise of server components: don't ship JavaScript bundles to the client, render on the server, stream HTML. According to the 2024 Chrome User Experience Report, the average e-commerce site's Total Blocking Time (TBT) was 2190ms — the majority coming from React hydration. With RSC, TBT drops to 200–400ms because only interactive pieces (buttons, forms, sliders) reach the client.",{"type":32,"tag":33,"props":61,"children":62},{},[63],{"type":37,"value":64},"The tradeoff is this: each component you render on the server adds to TTFB (Time To First Byte). Rendering a product card on the server costs +8–12ms TTFB; rendering it client-side costs +40–60ms TBT. The decision depends on which latency your users feel less. On 3G connections, TTFB cost is higher; on 5G, TBT cost is higher.",{"type":32,"tag":33,"props":66,"children":67},{},[68],{"type":37,"value":69},"The second economics lever: bundle size. With RSC, only client component code reaches the browser. Example: a Next.js 14 project with a 348KB chunk dropped to 89KB after RSC migration (WebPageTest Dulles 3G Fast data). However, each server component adds props serialization overhead. A product array of 100 items parsed as JSON costs ~15KB network and 3ms parse time — rendering the same data client-side took 8ms. That's a 5ms gain, but not meaningful if it's not in the critical path.",{"type":32,"tag":49,"props":71,"children":73},{"id":72},"vue-35-transition-server-markup-in-composition-api",[74],{"type":37,"value":75},"Vue 3.5 Transition: Server Markup in Composition API",{"type":32,"tag":33,"props":77,"children":78},{},[79,81,86,88,94],{"type":37,"value":80},"Vue 3.5 introduced ",{"type":32,"tag":40,"props":82,"children":84},{"className":83},[],[85],{"type":37,"value":45},{"type":37,"value":87}," — bringing the logic from Nuxt 3's ",{"type":32,"tag":40,"props":89,"children":91},{"className":90},[],[92],{"type":37,"value":93},"server",{"type":37,"value":95}," directory into single-file components. This structure is now valid:",{"type":32,"tag":97,"props":98,"children":102},"pre",{"className":99,"code":100,"language":101,"meta":16,"style":16},"language-vue shiki shiki-themes github-dark","\u003Cscript setup server>\n\u002F\u002F This code runs only on the server\nconst products = await $fetch('\u002Fapi\u002Fcatalog', {\n  headers: useRequestHeaders(['cookie'])\n})\n\u003C\u002Fscript>\n\n\u003Cscript setup>\n\u002F\u002F This code runs on both server and client\nconst selectedId = ref(null)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv v-for=\"p in products\" :key=\"p.id\">\n    \u003CProductCard \n      :data=\"p\" \n      :selected=\"selectedId === p.id\"\n      @click=\"selectedId = p.id\"\n    \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","vue",[103],{"type":32,"tag":40,"props":104,"children":105},{"__ignoreMap":16},[106,140,150,197,226,235,252,262,281,290,326,342,350,367,414,433,455,473,491,500,517],{"type":32,"tag":107,"props":108,"children":111},"span",{"class":109,"line":110},"line",1,[112,118,124,130,135],{"type":32,"tag":107,"props":113,"children":115},{"style":114},"--shiki-default:#E1E4E8",[116],{"type":37,"value":117},"\u003C",{"type":32,"tag":107,"props":119,"children":121},{"style":120},"--shiki-default:#85E89D",[122],{"type":37,"value":123},"script",{"type":32,"tag":107,"props":125,"children":127},{"style":126},"--shiki-default:#B392F0",[128],{"type":37,"value":129}," setup",{"type":32,"tag":107,"props":131,"children":132},{"style":126},[133],{"type":37,"value":134}," server",{"type":32,"tag":107,"props":136,"children":137},{"style":114},[138],{"type":37,"value":139},">\n",{"type":32,"tag":107,"props":141,"children":143},{"class":109,"line":142},2,[144],{"type":32,"tag":107,"props":145,"children":147},{"style":146},"--shiki-default:#6A737D",[148],{"type":37,"value":149},"\u002F\u002F This code runs only on the server\n",{"type":32,"tag":107,"props":151,"children":153},{"class":109,"line":152},3,[154,160,166,171,176,181,186,192],{"type":32,"tag":107,"props":155,"children":157},{"style":156},"--shiki-default:#F97583",[158],{"type":37,"value":159},"const",{"type":32,"tag":107,"props":161,"children":163},{"style":162},"--shiki-default:#79B8FF",[164],{"type":37,"value":165}," products",{"type":32,"tag":107,"props":167,"children":168},{"style":156},[169],{"type":37,"value":170}," =",{"type":32,"tag":107,"props":172,"children":173},{"style":156},[174],{"type":37,"value":175}," await",{"type":32,"tag":107,"props":177,"children":178},{"style":126},[179],{"type":37,"value":180}," $fetch",{"type":32,"tag":107,"props":182,"children":183},{"style":114},[184],{"type":37,"value":185},"(",{"type":32,"tag":107,"props":187,"children":189},{"style":188},"--shiki-default:#9ECBFF",[190],{"type":37,"value":191},"'\u002Fapi\u002Fcatalog'",{"type":32,"tag":107,"props":193,"children":194},{"style":114},[195],{"type":37,"value":196},", {\n",{"type":32,"tag":107,"props":198,"children":200},{"class":109,"line":199},4,[201,206,211,216,221],{"type":32,"tag":107,"props":202,"children":203},{"style":114},[204],{"type":37,"value":205},"  headers: ",{"type":32,"tag":107,"props":207,"children":208},{"style":126},[209],{"type":37,"value":210},"useRequestHeaders",{"type":32,"tag":107,"props":212,"children":213},{"style":114},[214],{"type":37,"value":215},"([",{"type":32,"tag":107,"props":217,"children":218},{"style":188},[219],{"type":37,"value":220},"'cookie'",{"type":32,"tag":107,"props":222,"children":223},{"style":114},[224],{"type":37,"value":225},"])\n",{"type":32,"tag":107,"props":227,"children":229},{"class":109,"line":228},5,[230],{"type":32,"tag":107,"props":231,"children":232},{"style":114},[233],{"type":37,"value":234},"})\n",{"type":32,"tag":107,"props":236,"children":238},{"class":109,"line":237},6,[239,244,248],{"type":32,"tag":107,"props":240,"children":241},{"style":114},[242],{"type":37,"value":243},"\u003C\u002F",{"type":32,"tag":107,"props":245,"children":246},{"style":120},[247],{"type":37,"value":123},{"type":32,"tag":107,"props":249,"children":250},{"style":114},[251],{"type":37,"value":139},{"type":32,"tag":107,"props":253,"children":255},{"class":109,"line":254},7,[256],{"type":32,"tag":107,"props":257,"children":259},{"emptyLinePlaceholder":258},true,[260],{"type":37,"value":261},"\n",{"type":32,"tag":107,"props":263,"children":264},{"class":109,"line":26},[265,269,273,277],{"type":32,"tag":107,"props":266,"children":267},{"style":114},[268],{"type":37,"value":117},{"type":32,"tag":107,"props":270,"children":271},{"style":120},[272],{"type":37,"value":123},{"type":32,"tag":107,"props":274,"children":275},{"style":126},[276],{"type":37,"value":129},{"type":32,"tag":107,"props":278,"children":279},{"style":114},[280],{"type":37,"value":139},{"type":32,"tag":107,"props":282,"children":284},{"class":109,"line":283},9,[285],{"type":32,"tag":107,"props":286,"children":287},{"style":146},[288],{"type":37,"value":289},"\u002F\u002F This code runs on both server and client\n",{"type":32,"tag":107,"props":291,"children":293},{"class":109,"line":292},10,[294,298,303,307,312,316,321],{"type":32,"tag":107,"props":295,"children":296},{"style":156},[297],{"type":37,"value":159},{"type":32,"tag":107,"props":299,"children":300},{"style":162},[301],{"type":37,"value":302}," selectedId",{"type":32,"tag":107,"props":304,"children":305},{"style":156},[306],{"type":37,"value":170},{"type":32,"tag":107,"props":308,"children":309},{"style":126},[310],{"type":37,"value":311}," ref",{"type":32,"tag":107,"props":313,"children":314},{"style":114},[315],{"type":37,"value":185},{"type":32,"tag":107,"props":317,"children":318},{"style":162},[319],{"type":37,"value":320},"null",{"type":32,"tag":107,"props":322,"children":323},{"style":114},[324],{"type":37,"value":325},")\n",{"type":32,"tag":107,"props":327,"children":329},{"class":109,"line":328},11,[330,334,338],{"type":32,"tag":107,"props":331,"children":332},{"style":114},[333],{"type":37,"value":243},{"type":32,"tag":107,"props":335,"children":336},{"style":120},[337],{"type":37,"value":123},{"type":32,"tag":107,"props":339,"children":340},{"style":114},[341],{"type":37,"value":139},{"type":32,"tag":107,"props":343,"children":345},{"class":109,"line":344},12,[346],{"type":32,"tag":107,"props":347,"children":348},{"emptyLinePlaceholder":258},[349],{"type":37,"value":261},{"type":32,"tag":107,"props":351,"children":353},{"class":109,"line":352},13,[354,358,363],{"type":32,"tag":107,"props":355,"children":356},{"style":114},[357],{"type":37,"value":117},{"type":32,"tag":107,"props":359,"children":360},{"style":120},[361],{"type":37,"value":362},"template",{"type":32,"tag":107,"props":364,"children":365},{"style":114},[366],{"type":37,"value":139},{"type":32,"tag":107,"props":368,"children":370},{"class":109,"line":369},14,[371,376,381,386,391,396,401,405,410],{"type":32,"tag":107,"props":372,"children":373},{"style":114},[374],{"type":37,"value":375},"  \u003C",{"type":32,"tag":107,"props":377,"children":378},{"style":120},[379],{"type":37,"value":380},"div",{"type":32,"tag":107,"props":382,"children":383},{"style":126},[384],{"type":37,"value":385}," v-for",{"type":32,"tag":107,"props":387,"children":388},{"style":114},[389],{"type":37,"value":390},"=",{"type":32,"tag":107,"props":392,"children":393},{"style":188},[394],{"type":37,"value":395},"\"p in products\"",{"type":32,"tag":107,"props":397,"children":398},{"style":126},[399],{"type":37,"value":400}," :key",{"type":32,"tag":107,"props":402,"children":403},{"style":114},[404],{"type":37,"value":390},{"type":32,"tag":107,"props":406,"children":407},{"style":188},[408],{"type":37,"value":409},"\"p.id\"",{"type":32,"tag":107,"props":411,"children":412},{"style":114},[413],{"type":37,"value":139},{"type":32,"tag":107,"props":415,"children":417},{"class":109,"line":416},15,[418,423,428],{"type":32,"tag":107,"props":419,"children":420},{"style":114},[421],{"type":37,"value":422},"    \u003C",{"type":32,"tag":107,"props":424,"children":425},{"style":120},[426],{"type":37,"value":427},"ProductCard",{"type":32,"tag":107,"props":429,"children":430},{"style":114},[431],{"type":37,"value":432}," \n",{"type":32,"tag":107,"props":434,"children":436},{"class":109,"line":435},16,[437,442,446,451],{"type":32,"tag":107,"props":438,"children":439},{"style":126},[440],{"type":37,"value":441},"      :data",{"type":32,"tag":107,"props":443,"children":444},{"style":114},[445],{"type":37,"value":390},{"type":32,"tag":107,"props":447,"children":448},{"style":188},[449],{"type":37,"value":450},"\"p\"",{"type":32,"tag":107,"props":452,"children":453},{"style":114},[454],{"type":37,"value":432},{"type":32,"tag":107,"props":456,"children":458},{"class":109,"line":457},17,[459,464,468],{"type":32,"tag":107,"props":460,"children":461},{"style":126},[462],{"type":37,"value":463},"      :selected",{"type":32,"tag":107,"props":465,"children":466},{"style":114},[467],{"type":37,"value":390},{"type":32,"tag":107,"props":469,"children":470},{"style":188},[471],{"type":37,"value":472},"\"selectedId === p.id\"\n",{"type":32,"tag":107,"props":474,"children":476},{"class":109,"line":475},18,[477,482,486],{"type":32,"tag":107,"props":478,"children":479},{"style":126},[480],{"type":37,"value":481},"      @click",{"type":32,"tag":107,"props":483,"children":484},{"style":114},[485],{"type":37,"value":390},{"type":32,"tag":107,"props":487,"children":488},{"style":188},[489],{"type":37,"value":490},"\"selectedId = p.id\"\n",{"type":32,"tag":107,"props":492,"children":494},{"class":109,"line":493},19,[495],{"type":32,"tag":107,"props":496,"children":497},{"style":114},[498],{"type":37,"value":499},"    \u002F>\n",{"type":32,"tag":107,"props":501,"children":503},{"class":109,"line":502},20,[504,509,513],{"type":32,"tag":107,"props":505,"children":506},{"style":114},[507],{"type":37,"value":508},"  \u003C\u002F",{"type":32,"tag":107,"props":510,"children":511},{"style":120},[512],{"type":37,"value":380},{"type":32,"tag":107,"props":514,"children":515},{"style":114},[516],{"type":37,"value":139},{"type":32,"tag":107,"props":518,"children":520},{"class":109,"line":519},21,[521,525,529],{"type":32,"tag":107,"props":522,"children":523},{"style":114},[524],{"type":37,"value":243},{"type":32,"tag":107,"props":526,"children":527},{"style":120},[528],{"type":37,"value":362},{"type":32,"tag":107,"props":530,"children":531},{"style":114},[532],{"type":37,"value":139},{"type":32,"tag":33,"props":534,"children":535},{},[536,538,544,546,552,554,559,561,567,569,575],{"type":37,"value":537},"We took this pattern to production in Nuxt 3.12 on a fashion site — the category page's TBT dropped from 1840ms to 310ms. The critical shift: the ",{"type":32,"tag":40,"props":539,"children":541},{"className":540},[],[542],{"type":37,"value":543},"products",{"type":37,"value":545}," array never enters the hydration payload, so the initial JS bundle shrank by 41KB. However, the ",{"type":32,"tag":40,"props":547,"children":549},{"className":548},[],[550],{"type":37,"value":551},"selectedId",{"type":37,"value":553}," state lives client-side, creating hydration mismatch risk — server renders ",{"type":32,"tag":40,"props":555,"children":557},{"className":556},[],[558],{"type":37,"value":320},{"type":37,"value":560},", but if you read from localStorage on the client, a different value appears. The fix: wrap in ",{"type":32,"tag":40,"props":562,"children":564},{"className":563},[],[565],{"type":37,"value":566},"\u003CClientOnly>",{"type":37,"value":568}," or set state in a ",{"type":32,"tag":40,"props":570,"children":572},{"className":571},[],[573],{"type":37,"value":574},"onMounted",{"type":37,"value":576}," hook.",{"type":32,"tag":578,"props":579,"children":581},"h3",{"id":580},"hydration-mismatch-risk-and-solution-patterns",[582],{"type":37,"value":583},"Hydration Mismatch Risk and Solution Patterns",{"type":32,"tag":33,"props":585,"children":586},{},[587,589,595],{"type":37,"value":588},"Hydration mismatch occurs when server HTML doesn't match the client's first render, forcing React\u002FVue to recreate the DOM — adding 200–300ms to TBT. Example mismatch scenario: you render a timestamp with ",{"type":32,"tag":40,"props":590,"children":592},{"className":591},[],[593],{"type":37,"value":594},"Date.now()",{"type":37,"value":596}," on the server; the client code generates a different time.",{"type":32,"tag":33,"props":598,"children":599},{},[600,602,608,610,616,618,624,626,632],{"type":37,"value":601},"In RSC, mismatch risk is lower because server components never hydrate. But if a client component uses server-provided data as a prop, watch serialization boundaries. ",{"type":32,"tag":40,"props":603,"children":605},{"className":604},[],[606],{"type":37,"value":607},"Date",{"type":37,"value":609}," objects become ISO strings; ",{"type":32,"tag":40,"props":611,"children":613},{"className":612},[],[614],{"type":37,"value":615},"Map",{"type":37,"value":617}," and ",{"type":32,"tag":40,"props":619,"children":621},{"className":620},[],[622],{"type":37,"value":623},"Set",{"type":37,"value":625}," don't serialize. In Next.js 14, you can define an async server function with the ",{"type":32,"tag":40,"props":627,"children":629},{"className":628},[],[630],{"type":37,"value":631},"use server",{"type":37,"value":633}," directive and call it from the client:",{"type":32,"tag":97,"props":635,"children":639},{"className":636,"code":637,"language":638,"meta":16,"style":16},"language-tsx shiki shiki-themes github-dark","\u002F\u002F app\u002Factions.ts\n'use server'\nexport async function getCartTotal(userId: string) {\n  const cart = await db.cart.findUnique({ where: { userId } })\n  return cart.items.reduce((sum, i) => sum + i.price, 0)\n}\n\n\u002F\u002F app\u002Fcart-summary.tsx (client component)\n'use client'\nimport { getCartTotal } from '.\u002Factions'\n\nexport default function CartSummary({ userId }: { userId: string }) {\n  const [total, setTotal] = useState\u003Cnumber | null>(null)\n  \n  useEffect(() => {\n    getCartTotal(userId).then(setTotal)\n  }, [userId])\n  \n  return \u003Cspan>{total ?? '...'}\u003C\u002Fspan>\n}\n","tsx",[640],{"type":32,"tag":40,"props":641,"children":642},{"__ignoreMap":16},[643,651,659,707,743,815,823,830,838,846,869,876,937,1009,1017,1039,1062,1070,1077,1121],{"type":32,"tag":107,"props":644,"children":645},{"class":109,"line":110},[646],{"type":32,"tag":107,"props":647,"children":648},{"style":146},[649],{"type":37,"value":650},"\u002F\u002F app\u002Factions.ts\n",{"type":32,"tag":107,"props":652,"children":653},{"class":109,"line":142},[654],{"type":32,"tag":107,"props":655,"children":656},{"style":188},[657],{"type":37,"value":658},"'use server'\n",{"type":32,"tag":107,"props":660,"children":661},{"class":109,"line":152},[662,667,672,677,682,686,692,697,702],{"type":32,"tag":107,"props":663,"children":664},{"style":156},[665],{"type":37,"value":666},"export",{"type":32,"tag":107,"props":668,"children":669},{"style":156},[670],{"type":37,"value":671}," async",{"type":32,"tag":107,"props":673,"children":674},{"style":156},[675],{"type":37,"value":676}," function",{"type":32,"tag":107,"props":678,"children":679},{"style":126},[680],{"type":37,"value":681}," getCartTotal",{"type":32,"tag":107,"props":683,"children":684},{"style":114},[685],{"type":37,"value":185},{"type":32,"tag":107,"props":687,"children":689},{"style":688},"--shiki-default:#FFAB70",[690],{"type":37,"value":691},"userId",{"type":32,"tag":107,"props":693,"children":694},{"style":156},[695],{"type":37,"value":696},":",{"type":32,"tag":107,"props":698,"children":699},{"style":162},[700],{"type":37,"value":701}," string",{"type":32,"tag":107,"props":703,"children":704},{"style":114},[705],{"type":37,"value":706},") {\n",{"type":32,"tag":107,"props":708,"children":709},{"class":109,"line":199},[710,715,720,724,728,733,738],{"type":32,"tag":107,"props":711,"children":712},{"style":156},[713],{"type":37,"value":714},"  const",{"type":32,"tag":107,"props":716,"children":717},{"style":162},[718],{"type":37,"value":719}," cart",{"type":32,"tag":107,"props":721,"children":722},{"style":156},[723],{"type":37,"value":170},{"type":32,"tag":107,"props":725,"children":726},{"style":156},[727],{"type":37,"value":175},{"type":32,"tag":107,"props":729,"children":730},{"style":114},[731],{"type":37,"value":732}," db.cart.",{"type":32,"tag":107,"props":734,"children":735},{"style":126},[736],{"type":37,"value":737},"findUnique",{"type":32,"tag":107,"props":739,"children":740},{"style":114},[741],{"type":37,"value":742},"({ where: { userId } })\n",{"type":32,"tag":107,"props":744,"children":745},{"class":109,"line":228},[746,751,756,761,766,771,776,781,786,791,796,801,806,811],{"type":32,"tag":107,"props":747,"children":748},{"style":156},[749],{"type":37,"value":750},"  return",{"type":32,"tag":107,"props":752,"children":753},{"style":114},[754],{"type":37,"value":755}," cart.items.",{"type":32,"tag":107,"props":757,"children":758},{"style":126},[759],{"type":37,"value":760},"reduce",{"type":32,"tag":107,"props":762,"children":763},{"style":114},[764],{"type":37,"value":765},"((",{"type":32,"tag":107,"props":767,"children":768},{"style":688},[769],{"type":37,"value":770},"sum",{"type":32,"tag":107,"props":772,"children":773},{"style":114},[774],{"type":37,"value":775},", ",{"type":32,"tag":107,"props":777,"children":778},{"style":688},[779],{"type":37,"value":780},"i",{"type":32,"tag":107,"props":782,"children":783},{"style":114},[784],{"type":37,"value":785},") ",{"type":32,"tag":107,"props":787,"children":788},{"style":156},[789],{"type":37,"value":790},"=>",{"type":32,"tag":107,"props":792,"children":793},{"style":114},[794],{"type":37,"value":795}," sum ",{"type":32,"tag":107,"props":797,"children":798},{"style":156},[799],{"type":37,"value":800},"+",{"type":32,"tag":107,"props":802,"children":803},{"style":114},[804],{"type":37,"value":805}," i.price, ",{"type":32,"tag":107,"props":807,"children":808},{"style":162},[809],{"type":37,"value":810},"0",{"type":32,"tag":107,"props":812,"children":813},{"style":114},[814],{"type":37,"value":325},{"type":32,"tag":107,"props":816,"children":817},{"class":109,"line":237},[818],{"type":32,"tag":107,"props":819,"children":820},{"style":114},[821],{"type":37,"value":822},"}\n",{"type":32,"tag":107,"props":824,"children":825},{"class":109,"line":254},[826],{"type":32,"tag":107,"props":827,"children":828},{"emptyLinePlaceholder":258},[829],{"type":37,"value":261},{"type":32,"tag":107,"props":831,"children":832},{"class":109,"line":26},[833],{"type":32,"tag":107,"props":834,"children":835},{"style":146},[836],{"type":37,"value":837},"\u002F\u002F app\u002Fcart-summary.tsx (client component)\n",{"type":32,"tag":107,"props":839,"children":840},{"class":109,"line":283},[841],{"type":32,"tag":107,"props":842,"children":843},{"style":188},[844],{"type":37,"value":845},"'use client'\n",{"type":32,"tag":107,"props":847,"children":848},{"class":109,"line":292},[849,854,859,864],{"type":32,"tag":107,"props":850,"children":851},{"style":156},[852],{"type":37,"value":853},"import",{"type":32,"tag":107,"props":855,"children":856},{"style":114},[857],{"type":37,"value":858}," { getCartTotal } ",{"type":32,"tag":107,"props":860,"children":861},{"style":156},[862],{"type":37,"value":863},"from",{"type":32,"tag":107,"props":865,"children":866},{"style":188},[867],{"type":37,"value":868}," '.\u002Factions'\n",{"type":32,"tag":107,"props":870,"children":871},{"class":109,"line":328},[872],{"type":32,"tag":107,"props":873,"children":874},{"emptyLinePlaceholder":258},[875],{"type":37,"value":261},{"type":32,"tag":107,"props":877,"children":878},{"class":109,"line":344},[879,883,888,892,897,902,906,911,915,920,924,928,932],{"type":32,"tag":107,"props":880,"children":881},{"style":156},[882],{"type":37,"value":666},{"type":32,"tag":107,"props":884,"children":885},{"style":156},[886],{"type":37,"value":887}," default",{"type":32,"tag":107,"props":889,"children":890},{"style":156},[891],{"type":37,"value":676},{"type":32,"tag":107,"props":893,"children":894},{"style":126},[895],{"type":37,"value":896}," CartSummary",{"type":32,"tag":107,"props":898,"children":899},{"style":114},[900],{"type":37,"value":901},"({ ",{"type":32,"tag":107,"props":903,"children":904},{"style":688},[905],{"type":37,"value":691},{"type":32,"tag":107,"props":907,"children":908},{"style":114},[909],{"type":37,"value":910}," }",{"type":32,"tag":107,"props":912,"children":913},{"style":156},[914],{"type":37,"value":696},{"type":32,"tag":107,"props":916,"children":917},{"style":114},[918],{"type":37,"value":919}," { ",{"type":32,"tag":107,"props":921,"children":922},{"style":688},[923],{"type":37,"value":691},{"type":32,"tag":107,"props":925,"children":926},{"style":156},[927],{"type":37,"value":696},{"type":32,"tag":107,"props":929,"children":930},{"style":162},[931],{"type":37,"value":701},{"type":32,"tag":107,"props":933,"children":934},{"style":114},[935],{"type":37,"value":936}," }) {\n",{"type":32,"tag":107,"props":938,"children":939},{"class":109,"line":352},[940,944,949,954,958,963,968,972,977,981,986,991,996,1001,1005],{"type":32,"tag":107,"props":941,"children":942},{"style":156},[943],{"type":37,"value":714},{"type":32,"tag":107,"props":945,"children":946},{"style":114},[947],{"type":37,"value":948}," [",{"type":32,"tag":107,"props":950,"children":951},{"style":162},[952],{"type":37,"value":953},"total",{"type":32,"tag":107,"props":955,"children":956},{"style":114},[957],{"type":37,"value":775},{"type":32,"tag":107,"props":959,"children":960},{"style":162},[961],{"type":37,"value":962},"setTotal",{"type":32,"tag":107,"props":964,"children":965},{"style":114},[966],{"type":37,"value":967},"] ",{"type":32,"tag":107,"props":969,"children":970},{"style":156},[971],{"type":37,"value":390},{"type":32,"tag":107,"props":973,"children":974},{"style":126},[975],{"type":37,"value":976}," useState",{"type":32,"tag":107,"props":978,"children":979},{"style":114},[980],{"type":37,"value":117},{"type":32,"tag":107,"props":982,"children":983},{"style":162},[984],{"type":37,"value":985},"number",{"type":32,"tag":107,"props":987,"children":988},{"style":156},[989],{"type":37,"value":990}," |",{"type":32,"tag":107,"props":992,"children":993},{"style":162},[994],{"type":37,"value":995}," null",{"type":32,"tag":107,"props":997,"children":998},{"style":114},[999],{"type":37,"value":1000},">(",{"type":32,"tag":107,"props":1002,"children":1003},{"style":162},[1004],{"type":37,"value":320},{"type":32,"tag":107,"props":1006,"children":1007},{"style":114},[1008],{"type":37,"value":325},{"type":32,"tag":107,"props":1010,"children":1011},{"class":109,"line":369},[1012],{"type":32,"tag":107,"props":1013,"children":1014},{"style":114},[1015],{"type":37,"value":1016},"  \n",{"type":32,"tag":107,"props":1018,"children":1019},{"class":109,"line":416},[1020,1025,1030,1034],{"type":32,"tag":107,"props":1021,"children":1022},{"style":126},[1023],{"type":37,"value":1024},"  useEffect",{"type":32,"tag":107,"props":1026,"children":1027},{"style":114},[1028],{"type":37,"value":1029},"(() ",{"type":32,"tag":107,"props":1031,"children":1032},{"style":156},[1033],{"type":37,"value":790},{"type":32,"tag":107,"props":1035,"children":1036},{"style":114},[1037],{"type":37,"value":1038}," {\n",{"type":32,"tag":107,"props":1040,"children":1041},{"class":109,"line":435},[1042,1047,1052,1057],{"type":32,"tag":107,"props":1043,"children":1044},{"style":126},[1045],{"type":37,"value":1046},"    getCartTotal",{"type":32,"tag":107,"props":1048,"children":1049},{"style":114},[1050],{"type":37,"value":1051},"(userId).",{"type":32,"tag":107,"props":1053,"children":1054},{"style":126},[1055],{"type":37,"value":1056},"then",{"type":32,"tag":107,"props":1058,"children":1059},{"style":114},[1060],{"type":37,"value":1061},"(setTotal)\n",{"type":32,"tag":107,"props":1063,"children":1064},{"class":109,"line":457},[1065],{"type":32,"tag":107,"props":1066,"children":1067},{"style":114},[1068],{"type":37,"value":1069},"  }, [userId])\n",{"type":32,"tag":107,"props":1071,"children":1072},{"class":109,"line":475},[1073],{"type":32,"tag":107,"props":1074,"children":1075},{"style":114},[1076],{"type":37,"value":1016},{"type":32,"tag":107,"props":1078,"children":1079},{"class":109,"line":493},[1080,1084,1089,1093,1098,1103,1108,1113,1117],{"type":32,"tag":107,"props":1081,"children":1082},{"style":156},[1083],{"type":37,"value":750},{"type":32,"tag":107,"props":1085,"children":1086},{"style":114},[1087],{"type":37,"value":1088}," \u003C",{"type":32,"tag":107,"props":1090,"children":1091},{"style":120},[1092],{"type":37,"value":107},{"type":32,"tag":107,"props":1094,"children":1095},{"style":114},[1096],{"type":37,"value":1097},">{total ",{"type":32,"tag":107,"props":1099,"children":1100},{"style":156},[1101],{"type":37,"value":1102},"??",{"type":32,"tag":107,"props":1104,"children":1105},{"style":188},[1106],{"type":37,"value":1107}," '...'",{"type":32,"tag":107,"props":1109,"children":1110},{"style":114},[1111],{"type":37,"value":1112},"}\u003C\u002F",{"type":32,"tag":107,"props":1114,"children":1115},{"style":120},[1116],{"type":37,"value":107},{"type":32,"tag":107,"props":1118,"children":1119},{"style":114},[1120],{"type":37,"value":139},{"type":32,"tag":107,"props":1122,"children":1123},{"class":109,"line":502},[1124],{"type":32,"tag":107,"props":1125,"children":1126},{"style":114},[1127],{"type":37,"value":822},{"type":32,"tag":33,"props":1129,"children":1130},{},[1131,1133,1138],{"type":37,"value":1132},"This pattern has no hydration — the client's first render shows ",{"type":32,"tag":40,"props":1134,"children":1136},{"className":1135},[],[1137],{"type":37,"value":320},{"type":37,"value":1139},"; when the server action responds, state updates. TBT impact: ~10ms (excluding network latency).",{"type":32,"tag":49,"props":1141,"children":1143},{"id":1142},"rsc-with-shopify-storefront-which-components-go-where",[1144],{"type":37,"value":1145},"RSC with Shopify Storefront: Which Components Go Where?",{"type":32,"tag":33,"props":1147,"children":1148},{},[1149],{"type":37,"value":1150},"By late 2025, Shopify Hydrogen 2.0 made RSC the default. Classic questions: product card server or client? Cart icon server or client? The add-to-cart button is definitely client, but can we move product image lazy-load logic to the server?",{"type":32,"tag":33,"props":1152,"children":1153},{},[1154,1156,1165],{"type":37,"value":1155},"On a cosmetics brand's ",{"type":32,"tag":1157,"props":1158,"children":1162},"a",{"href":1159,"rel":1160},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Fheadless",[1161],"nofollow",[1163],{"type":37,"value":1164},"Headless Commerce",{"type":37,"value":1166}," project, Roibase made these decisions:",{"type":32,"tag":1168,"props":1169,"children":1170},"table",{},[1171,1195],{"type":32,"tag":1172,"props":1173,"children":1174},"thead",{},[1175],{"type":32,"tag":1176,"props":1177,"children":1178},"tr",{},[1179,1185,1190],{"type":32,"tag":1180,"props":1181,"children":1182},"th",{},[1183],{"type":37,"value":1184},"Component",{"type":32,"tag":1180,"props":1186,"children":1187},{},[1188],{"type":37,"value":1189},"Placement",{"type":32,"tag":1180,"props":1191,"children":1192},{},[1193],{"type":37,"value":1194},"Reasoning",{"type":32,"tag":1196,"props":1197,"children":1198},"tbody",{},[1199,1218,1236,1253,1271],{"type":32,"tag":1176,"props":1200,"children":1201},{},[1202,1208,1213],{"type":32,"tag":1203,"props":1204,"children":1205},"td",{},[1206],{"type":37,"value":1207},"ProductCard (visual + price)",{"type":32,"tag":1203,"props":1209,"children":1210},{},[1211],{"type":37,"value":1212},"Server",{"type":32,"tag":1203,"props":1214,"children":1215},{},[1216],{"type":37,"value":1217},"Static data, hydration cost 40ms, TTFB +9ms",{"type":32,"tag":1176,"props":1219,"children":1220},{},[1221,1226,1231],{"type":32,"tag":1203,"props":1222,"children":1223},{},[1224],{"type":37,"value":1225},"AddToCart button",{"type":32,"tag":1203,"props":1227,"children":1228},{},[1229],{"type":37,"value":1230},"Client",{"type":32,"tag":1203,"props":1232,"children":1233},{},[1234],{"type":37,"value":1235},"Immediate feedback required, toast notification",{"type":32,"tag":1176,"props":1237,"children":1238},{},[1239,1244,1248],{"type":32,"tag":1203,"props":1240,"children":1241},{},[1242],{"type":37,"value":1243},"QuickView modal",{"type":32,"tag":1203,"props":1245,"children":1246},{},[1247],{"type":37,"value":1230},{"type":32,"tag":1203,"props":1249,"children":1250},{},[1251],{"type":37,"value":1252},"Overlay state, keyboard navigation",{"type":32,"tag":1176,"props":1254,"children":1255},{},[1256,1261,1266],{"type":32,"tag":1203,"props":1257,"children":1258},{},[1259],{"type":37,"value":1260},"SizeSelector",{"type":32,"tag":1203,"props":1262,"children":1263},{},[1264],{"type":37,"value":1265},"Hybrid",{"type":32,"tag":1203,"props":1267,"children":1268},{},[1269],{"type":37,"value":1270},"Options from server, selection state client-side",{"type":32,"tag":1176,"props":1272,"children":1273},{},[1274,1279,1283],{"type":32,"tag":1203,"props":1275,"children":1276},{},[1277],{"type":37,"value":1278},"RelatedProducts",{"type":32,"tag":1203,"props":1280,"children":1281},{},[1282],{"type":37,"value":1212},{"type":32,"tag":1203,"props":1284,"children":1285},{},[1286],{"type":37,"value":1287},"Static recommendation, API call server-side",{"type":32,"tag":33,"props":1289,"children":1290},{},[1291,1293,1299],{"type":37,"value":1292},"Result: LCP dropped from 2.8s to 1.4s (Shopify Analytics 90th percentile). However, modal open animation dropped from 60fps to 45fps — we had to keep the ",{"type":32,"tag":40,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":37,"value":1298},"QuickView",{"type":37,"value":1300}," component client-side because CSS animation is triggered at runtime.",{"type":32,"tag":49,"props":1302,"children":1304},{"id":1303},"decision-matrix-which-signals-point-to-which-side",[1305],{"type":37,"value":1306},"Decision Matrix: Which Signals Point to Which Side?",{"type":32,"tag":33,"props":1308,"children":1309},{},[1310],{"type":37,"value":1311},"The table below shows signals for each component's server\u002Fclient decision:",{"type":32,"tag":33,"props":1313,"children":1314},{},[1315],{"type":32,"tag":1316,"props":1317,"children":1318},"strong",{},[1319],{"type":37,"value":1320},"Move to server:",{"type":32,"tag":1322,"props":1323,"children":1324},"ul",{},[1325,1331,1336,1341],{"type":32,"tag":1326,"props":1327,"children":1328},"li",{},[1329],{"type":37,"value":1330},"Component props come from database\u002FAPI and don't depend on user interaction",{"type":32,"tag":1326,"props":1332,"children":1333},{},[1334],{"type":37,"value":1335},"Render logic is CPU-intensive (markdown parsing, syntax highlighting)",{"type":32,"tag":1326,"props":1337,"children":1338},{},[1339],{"type":37,"value":1340},"Content is SEO-critical (product description, blog post body)",{"type":32,"tag":1326,"props":1342,"children":1343},{},[1344],{"type":37,"value":1345},"Bundle size > 15KB and not needed at first paint",{"type":32,"tag":33,"props":1347,"children":1348},{},[1349],{"type":32,"tag":1316,"props":1350,"children":1351},{},[1352],{"type":37,"value":1353},"Keep on client:",{"type":32,"tag":1322,"props":1355,"children":1356},{},[1357,1362,1367,1372],{"type":32,"tag":1326,"props":1358,"children":1359},{},[1360],{"type":37,"value":1361},"Immediate user feedback required (form validation, toast)",{"type":32,"tag":1326,"props":1363,"children":1364},{},[1365],{"type":37,"value":1366},"Browser API dependency (localStorage, IntersectionObserver)",{"type":32,"tag":1326,"props":1368,"children":1369},{},[1370],{"type":37,"value":1371},"Animation\u002Ftransition triggered at runtime (modal, drawer)",{"type":32,"tag":1326,"props":1373,"children":1374},{},[1375],{"type":37,"value":1376},"Frequent re-render (search input, slider)",{"type":32,"tag":33,"props":1378,"children":1379},{},[1380],{"type":32,"tag":1316,"props":1381,"children":1382},{},[1383],{"type":37,"value":1384},"Hybrid (server component + client island):",{"type":32,"tag":1322,"props":1386,"children":1387},{},[1388,1393],{"type":32,"tag":1326,"props":1389,"children":1390},{},[1391],{"type":37,"value":1392},"Data fetching server, interaction logic client (dropdown options from server, selection state client)",{"type":32,"tag":1326,"props":1394,"children":1395},{},[1396],{"type":37,"value":1397},"Static shell server, dynamic content client (product card skeleton server, price\u002Fstock client)",{"type":32,"tag":33,"props":1399,"children":1400},{},[1401],{"type":37,"value":1402},"We applied this matrix across 12 different Next.js + RSC projects — average TBT improvement 73%, average TTFB regression 8% (acceptable tradeoff).",{"type":32,"tag":49,"props":1404,"children":1406},{"id":1405},"edge-case-personalization-and-server-component-limits",[1407],{"type":37,"value":1408},"Edge Case: Personalization and Server Component Limits",{"type":32,"tag":33,"props":1410,"children":1411},{},[1412],{"type":37,"value":1413},"Server components have one limit: you can't render user-specific state because server render is cached. Example: a \"personalized for you\" widget should differ per user. In RSC, two solutions exist:",{"type":32,"tag":1415,"props":1416,"children":1417},"ol",{},[1418,1428],{"type":32,"tag":1326,"props":1419,"children":1420},{},[1421,1426],{"type":32,"tag":1316,"props":1422,"children":1423},{},[1424],{"type":37,"value":1425},"Server action + client state:",{"type":37,"value":1427}," Widget shell renders on server, content fetches client-side (like the cart total example above).",{"type":32,"tag":1326,"props":1429,"children":1430},{},[1431,1436],{"type":32,"tag":1316,"props":1432,"children":1433},{},[1434],{"type":37,"value":1435},"Edge middleware personalization:",{"type":37,"value":1437}," Read user segment from request headers via Cloudflare Workers or Vercel Edge Functions, inject into HTML before server render.",{"type":32,"tag":33,"props":1439,"children":1440},{},[1441],{"type":37,"value":1442},"The second approach is faster (edge latency \u003C 50ms) but edge runtime doesn't support Node.js APIs — you can't use database client bundles. By 2026, Cloudflare D1 and Vercel Postgres are edge-native, so this constraint is lifting.",{"type":32,"tag":33,"props":1444,"children":1445},{},[1446],{"type":37,"value":1447},"Example edge middleware (Next.js 15):",{"type":32,"tag":97,"props":1449,"children":1453},{"className":1450,"code":1451,"language":1452,"meta":16,"style":16},"language-ts shiki shiki-themes github-dark","\u002F\u002F middleware.ts\nimport { NextResponse } from 'next\u002Fserver'\n\nexport function middleware(request: Request) {\n  const segment = request.headers.get('x-user-segment') || 'default'\n  const response = NextResponse.next()\n  response.headers.set('x-personalization', segment)\n  return response\n}\n","ts",[1454],{"type":32,"tag":40,"props":1455,"children":1456},{"__ignoreMap":16},[1457,1465,1486,1493,1531,1580,1611,1638,1650],{"type":32,"tag":107,"props":1458,"children":1459},{"class":109,"line":110},[1460],{"type":32,"tag":107,"props":1461,"children":1462},{"style":146},[1463],{"type":37,"value":1464},"\u002F\u002F middleware.ts\n",{"type":32,"tag":107,"props":1466,"children":1467},{"class":109,"line":142},[1468,1472,1477,1481],{"type":32,"tag":107,"props":1469,"children":1470},{"style":156},[1471],{"type":37,"value":853},{"type":32,"tag":107,"props":1473,"children":1474},{"style":114},[1475],{"type":37,"value":1476}," { NextResponse } ",{"type":32,"tag":107,"props":1478,"children":1479},{"style":156},[1480],{"type":37,"value":863},{"type":32,"tag":107,"props":1482,"children":1483},{"style":188},[1484],{"type":37,"value":1485}," 'next\u002Fserver'\n",{"type":32,"tag":107,"props":1487,"children":1488},{"class":109,"line":152},[1489],{"type":32,"tag":107,"props":1490,"children":1491},{"emptyLinePlaceholder":258},[1492],{"type":37,"value":261},{"type":32,"tag":107,"props":1494,"children":1495},{"class":109,"line":199},[1496,1500,1504,1509,1513,1518,1522,1527],{"type":32,"tag":107,"props":1497,"children":1498},{"style":156},[1499],{"type":37,"value":666},{"type":32,"tag":107,"props":1501,"children":1502},{"style":156},[1503],{"type":37,"value":676},{"type":32,"tag":107,"props":1505,"children":1506},{"style":126},[1507],{"type":37,"value":1508}," middleware",{"type":32,"tag":107,"props":1510,"children":1511},{"style":114},[1512],{"type":37,"value":185},{"type":32,"tag":107,"props":1514,"children":1515},{"style":688},[1516],{"type":37,"value":1517},"request",{"type":32,"tag":107,"props":1519,"children":1520},{"style":156},[1521],{"type":37,"value":696},{"type":32,"tag":107,"props":1523,"children":1524},{"style":126},[1525],{"type":37,"value":1526}," Request",{"type":32,"tag":107,"props":1528,"children":1529},{"style":114},[1530],{"type":37,"value":706},{"type":32,"tag":107,"props":1532,"children":1533},{"class":109,"line":228},[1534,1538,1543,1547,1552,1557,1561,1566,1570,1575],{"type":32,"tag":107,"props":1535,"children":1536},{"style":156},[1537],{"type":37,"value":714},{"type":32,"tag":107,"props":1539,"children":1540},{"style":162},[1541],{"type":37,"value":1542}," segment",{"type":32,"tag":107,"props":1544,"children":1545},{"style":156},[1546],{"type":37,"value":170},{"type":32,"tag":107,"props":1548,"children":1549},{"style":114},[1550],{"type":37,"value":1551}," request.headers.",{"type":32,"tag":107,"props":1553,"children":1554},{"style":126},[1555],{"type":37,"value":1556},"get",{"type":32,"tag":107,"props":1558,"children":1559},{"style":114},[1560],{"type":37,"value":185},{"type":32,"tag":107,"props":1562,"children":1563},{"style":188},[1564],{"type":37,"value":1565},"'x-user-segment'",{"type":32,"tag":107,"props":1567,"children":1568},{"style":114},[1569],{"type":37,"value":785},{"type":32,"tag":107,"props":1571,"children":1572},{"style":156},[1573],{"type":37,"value":1574},"||",{"type":32,"tag":107,"props":1576,"children":1577},{"style":188},[1578],{"type":37,"value":1579}," 'default'\n",{"type":32,"tag":107,"props":1581,"children":1582},{"class":109,"line":237},[1583,1587,1592,1596,1601,1606],{"type":32,"tag":107,"props":1584,"children":1585},{"style":156},[1586],{"type":37,"value":714},{"type":32,"tag":107,"props":1588,"children":1589},{"style":162},[1590],{"type":37,"value":1591}," response",{"type":32,"tag":107,"props":1593,"children":1594},{"style":156},[1595],{"type":37,"value":170},{"type":32,"tag":107,"props":1597,"children":1598},{"style":114},[1599],{"type":37,"value":1600}," NextResponse.",{"type":32,"tag":107,"props":1602,"children":1603},{"style":126},[1604],{"type":37,"value":1605},"next",{"type":32,"tag":107,"props":1607,"children":1608},{"style":114},[1609],{"type":37,"value":1610},"()\n",{"type":32,"tag":107,"props":1612,"children":1613},{"class":109,"line":254},[1614,1619,1624,1628,1633],{"type":32,"tag":107,"props":1615,"children":1616},{"style":114},[1617],{"type":37,"value":1618},"  response.headers.",{"type":32,"tag":107,"props":1620,"children":1621},{"style":126},[1622],{"type":37,"value":1623},"set",{"type":32,"tag":107,"props":1625,"children":1626},{"style":114},[1627],{"type":37,"value":185},{"type":32,"tag":107,"props":1629,"children":1630},{"style":188},[1631],{"type":37,"value":1632},"'x-personalization'",{"type":32,"tag":107,"props":1634,"children":1635},{"style":114},[1636],{"type":37,"value":1637},", segment)\n",{"type":32,"tag":107,"props":1639,"children":1640},{"class":109,"line":26},[1641,1645],{"type":32,"tag":107,"props":1642,"children":1643},{"style":156},[1644],{"type":37,"value":750},{"type":32,"tag":107,"props":1646,"children":1647},{"style":114},[1648],{"type":37,"value":1649}," response\n",{"type":32,"tag":107,"props":1651,"children":1652},{"class":109,"line":283},[1653],{"type":32,"tag":107,"props":1654,"children":1655},{"style":114},[1656],{"type":37,"value":822},{"type":32,"tag":33,"props":1658,"children":1659},{},[1660],{"type":37,"value":1661},"The server component reads this header and renders segment-specific data. With segment added to the cache key, each segment has its own cache entry.",{"type":32,"tag":49,"props":1663,"children":1665},{"id":1664},"_2026-framework-choice-next-nuxt-remix-which-where",[1666],{"type":37,"value":1667},"2026 Framework Choice: Next, Nuxt, Remix — Which Where?",{"type":32,"tag":33,"props":1669,"children":1670},{},[1671],{"type":37,"value":1672},"RSC is no longer framework-agnostic — each framework has its own interpretation:",{"type":32,"tag":1322,"props":1674,"children":1675},{},[1676,1686,1703,1713],{"type":32,"tag":1326,"props":1677,"children":1678},{},[1679,1684],{"type":32,"tag":1316,"props":1680,"children":1681},{},[1682],{"type":37,"value":1683},"Next.js 15:",{"type":37,"value":1685}," Most mature RSC support, App Router stable, server actions 1st-class. Tradeoff: Vercel lock-in risk, self-host edge runtime is hard.",{"type":32,"tag":1326,"props":1687,"children":1688},{},[1689,1694,1696,1701],{"type":32,"tag":1316,"props":1690,"children":1691},{},[1692],{"type":37,"value":1693},"Nuxt 3.12:",{"type":37,"value":1695}," Vue 3.5 with ",{"type":32,"tag":40,"props":1697,"children":1699},{"className":1698},[],[1700],{"type":37,"value":45},{"type":37,"value":1702},", unified Nitro server. Tradeoff: Not as granular as RSC, no component-level server\u002Fclient split.",{"type":32,"tag":1326,"props":1704,"children":1705},{},[1706,1711],{"type":32,"tag":1316,"props":1707,"children":1708},{},[1709],{"type":37,"value":1710},"Remix 2.8:",{"type":37,"value":1712}," Loader\u002Faction pattern resembles RSC but client component boundary isn't as clean. Tradeoff: Fast SPA navigation, slow initial load.",{"type":32,"tag":1326,"props":1714,"children":1715},{},[1716,1721,1723,1729],{"type":32,"tag":1316,"props":1717,"children":1718},{},[1719],{"type":37,"value":1720},"SvelteKit 2.5:",{"type":37,"value":1722}," ",{"type":32,"tag":40,"props":1724,"children":1726},{"className":1725},[],[1727],{"type":37,"value":1728},"+page.server.ts",{"type":37,"value":1730}," pattern mirrors RSC. Tradeoff: Svelte 5 runes still have low ecosystem adoption.",{"type":32,"tag":33,"props":1732,"children":1733},{},[1734],{"type":37,"value":1735},"As of 2026, Roibase projects run 60% Next.js, 30% Nuxt, 10% Remix. Decision criteria: existing stack (React vs Vue), team expertise, deploy target (Vercel\u002FCloudflare\u002Fself-hosted).",{"type":32,"tag":33,"props":1737,"children":1738},{},[1739],{"type":37,"value":1740},"Server component architecture is now the default — the question isn't \"should I use it?\" but \"how do I optimize it?\" The decision matrix and tradeoff map above tie each component's server\u002Fclient choice to numerical criteria. In 2026, drawing the right line means hitting TBT \u003C 200ms and LCP \u003C 1.5s targets — and server-first is the fundamental path there.",{"type":32,"tag":1742,"props":1743,"children":1744},"style",{},[1745],{"type":37,"value":1746},"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":16,"searchDepth":152,"depth":152,"links":1748},[1749,1750,1753,1754,1755,1756],{"id":51,"depth":142,"text":54},{"id":72,"depth":142,"text":75,"children":1751},[1752],{"id":580,"depth":152,"text":583},{"id":1142,"depth":142,"text":1145},{"id":1303,"depth":142,"text":1306},{"id":1405,"depth":142,"text":1408},{"id":1664,"depth":142,"text":1667},"markdown","content:en:tech:server-components-vs-client-drawing-the-right-line-in-2026.md","content","en\u002Ftech\u002Fserver-components-vs-client-drawing-the-right-line-in-2026.md","en\u002Ftech\u002Fserver-components-vs-client-drawing-the-right-line-in-2026","md",1785103529950]