[{"data":1,"prerenderedAt":2583},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fen\u002Ftech\u002Fserver-components-vs-client-2026-drawing-the-right-line":13},{"i18nKey":4,"paths":5},"tech-008-2026-05",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Ftech\u002Fserver-components-vs-client-2026","\u002Fen\u002Ftech\u002Fserver-components-vs-client-2026-drawing-the-right-line","\u002Fes\u002Ftech\u002Fserver-components-vs-client-2026","\u002Ffr\u002Ftech\u002Fcomponents-client-vs-serveur-2026","\u002Fit\u002Ftech\u002Fserver-components-vs-client-2026","\u002Fru\u002Ftech\u002Fserver-components-vs-client-2026-dogrumu-cizgi-cizmek","\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":2577,"_id":2578,"_source":2579,"_file":2580,"_stem":2581,"_extension":2582},"tech",false,"","Server Components vs Client: Drawing the Right Line in 2026","Optimize hydration costs with React Server Components and Vue 3.5. How architectural decisions impact bundle size, TBT, and FCP.","2026-05-24",[21,22,23,24,25],"react-server-components","vue-hydration","web-performance","headless-architecture","frontend-optimization",8,"Roibase",{"type":29,"children":30,"toc":2565},"root",[31,39,46,51,65,70,863,868,874,895,916,1067,1096,1112,1118,1123,1252,1257,1262,1268,1273,1278,1431,1436,1441,1641,1646,1652,1657,1713,1734,2093,2113,2119,2124,2129,2152,2157,2324,2329,2335,2505,2510,2516,2521,2526,2554,2559],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36],{"type":37,"value":38},"text","React Server Components went mainstream in 2024. After Vue 3.5 launched in 2025, similar patterns became widespread in the Nuxt ecosystem. Now, mid-2026, established project architectures are falling behind, and new projects face the question: \"Which components render on the server, which on the client?\" This decision directly impacts bundle size, Time to Interactive (TTI), and First Contentful Paint (FCP). It's especially critical in headless commerce projects: checkout flows must be interactive, but product lists might not justify hydration overhead.",{"type":32,"tag":40,"props":41,"children":43},"h2",{"id":42},"where-does-server-component-runtime-cost-come-from",[44],{"type":37,"value":45},"Where does Server Component runtime cost come from",{"type":32,"tag":33,"props":47,"children":48},{},[49],{"type":37,"value":50},"Rendering on the server doesn't always mean lighter. When server-rendered HTML reaches the client, hydration begins if interactive elements are present. React or Vue runtime rebuilds the DOM and attaches event listeners without re-rendering. The problem: hydrating a large component tree blocks the JavaScript main thread.",{"type":32,"tag":33,"props":52,"children":53},{},[54,56,63],{"type":37,"value":55},"According to Chrome User Experience Report 2026 Q1, e-commerce sites show a median TBT (Total Blocking Time) of 320ms. Hydration contributes an average of 180-240ms—that's 60-75% of TBT. Nuxt 3.12+ and Next.js 15+ support selective hydration, but if you attach ",{"type":32,"tag":57,"props":58,"children":60},"code",{"className":59},[],[61],{"type":37,"value":62},"client:load",{"type":37,"value":64}," directive to every component, you're back to the same problem.",{"type":32,"tag":33,"props":66,"children":67},{},[68],{"type":37,"value":69},"Example scenario: a category page with 120 products. Each product card contains a lazy-loaded image, price, and \"Add to Cart\" button. If all cards are client components, the initial bundle is 340KB (gzipped). Hydration takes ~420ms (iPhone 13, 4G). But 80% of each card is static—only the button is interactive. Converting to a Server Component and marking only the button as client cuts the bundle to 95KB and hydration to 120ms.",{"type":32,"tag":71,"props":72,"children":76},"pre",{"className":73,"code":74,"language":75,"meta":16,"style":16},"language-jsx shiki shiki-themes github-dark","\u002F\u002F ❌ Entire card client-side\n'use client'\nexport default function ProductCard({ product }) {\n  const [inCart, setInCart] = useState(false)\n  return (\n    \u003Cdiv className=\"card\">\n      \u003Cimg src={product.image} loading=\"lazy\" \u002F>\n      \u003Ch3>{product.title}\u003C\u002Fh3>\n      \u003Cp>{product.price}\u003C\u002Fp>\n      \u003Cbutton onClick={() => setInCart(true)}>Add to Cart\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ✅ Only button client-side\n\u002F\u002F ProductCard.server.jsx\nexport default function ProductCard({ product }) {\n  return (\n    \u003Cdiv className=\"card\">\n      \u003Cimg src={product.image} loading=\"lazy\" \u002F>\n      \u003Ch3>{product.title}\u003C\u002Fh3>\n      \u003Cp>{product.price}\u003C\u002Fp>\n      \u003CAddToCartButton productId={product.id} \u002F>\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F AddToCartButton.client.jsx\n'use client'\nexport default function AddToCartButton({ productId }) {\n  const [inCart, setInCart] = useState(false)\n  return \u003Cbutton onClick={() => setInCart(true)}>Add to Cart\u003C\u002Fbutton>\n}\n","jsx",[77],{"type":32,"tag":57,"props":78,"children":79},{"__ignoreMap":16},[80,92,102,145,205,219,253,300,325,350,409,426,435,444,454,463,472,504,516,544,584,608,632,659,675,683,691,699,708,716,750,798,855],{"type":32,"tag":81,"props":82,"children":85},"span",{"class":83,"line":84},"line",1,[86],{"type":32,"tag":81,"props":87,"children":89},{"style":88},"--shiki-default:#6A737D",[90],{"type":37,"value":91},"\u002F\u002F ❌ Entire card client-side\n",{"type":32,"tag":81,"props":93,"children":95},{"class":83,"line":94},2,[96],{"type":32,"tag":81,"props":97,"children":99},{"style":98},"--shiki-default:#9ECBFF",[100],{"type":37,"value":101},"'use client'\n",{"type":32,"tag":81,"props":103,"children":105},{"class":83,"line":104},3,[106,112,117,122,128,134,140],{"type":32,"tag":81,"props":107,"children":109},{"style":108},"--shiki-default:#F97583",[110],{"type":37,"value":111},"export",{"type":32,"tag":81,"props":113,"children":114},{"style":108},[115],{"type":37,"value":116}," default",{"type":32,"tag":81,"props":118,"children":119},{"style":108},[120],{"type":37,"value":121}," function",{"type":32,"tag":81,"props":123,"children":125},{"style":124},"--shiki-default:#B392F0",[126],{"type":37,"value":127}," ProductCard",{"type":32,"tag":81,"props":129,"children":131},{"style":130},"--shiki-default:#E1E4E8",[132],{"type":37,"value":133},"({ ",{"type":32,"tag":81,"props":135,"children":137},{"style":136},"--shiki-default:#FFAB70",[138],{"type":37,"value":139},"product",{"type":32,"tag":81,"props":141,"children":142},{"style":130},[143],{"type":37,"value":144}," }) {\n",{"type":32,"tag":81,"props":146,"children":148},{"class":83,"line":147},4,[149,154,159,165,170,175,180,185,190,195,200],{"type":32,"tag":81,"props":150,"children":151},{"style":108},[152],{"type":37,"value":153},"  const",{"type":32,"tag":81,"props":155,"children":156},{"style":130},[157],{"type":37,"value":158}," [",{"type":32,"tag":81,"props":160,"children":162},{"style":161},"--shiki-default:#79B8FF",[163],{"type":37,"value":164},"inCart",{"type":32,"tag":81,"props":166,"children":167},{"style":130},[168],{"type":37,"value":169},", ",{"type":32,"tag":81,"props":171,"children":172},{"style":161},[173],{"type":37,"value":174},"setInCart",{"type":32,"tag":81,"props":176,"children":177},{"style":130},[178],{"type":37,"value":179},"] ",{"type":32,"tag":81,"props":181,"children":182},{"style":108},[183],{"type":37,"value":184},"=",{"type":32,"tag":81,"props":186,"children":187},{"style":124},[188],{"type":37,"value":189}," useState",{"type":32,"tag":81,"props":191,"children":192},{"style":130},[193],{"type":37,"value":194},"(",{"type":32,"tag":81,"props":196,"children":197},{"style":161},[198],{"type":37,"value":199},"false",{"type":32,"tag":81,"props":201,"children":202},{"style":130},[203],{"type":37,"value":204},")\n",{"type":32,"tag":81,"props":206,"children":208},{"class":83,"line":207},5,[209,214],{"type":32,"tag":81,"props":210,"children":211},{"style":108},[212],{"type":37,"value":213},"  return",{"type":32,"tag":81,"props":215,"children":216},{"style":130},[217],{"type":37,"value":218}," (\n",{"type":32,"tag":81,"props":220,"children":222},{"class":83,"line":221},6,[223,228,234,239,243,248],{"type":32,"tag":81,"props":224,"children":225},{"style":130},[226],{"type":37,"value":227},"    \u003C",{"type":32,"tag":81,"props":229,"children":231},{"style":230},"--shiki-default:#85E89D",[232],{"type":37,"value":233},"div",{"type":32,"tag":81,"props":235,"children":236},{"style":124},[237],{"type":37,"value":238}," className",{"type":32,"tag":81,"props":240,"children":241},{"style":108},[242],{"type":37,"value":184},{"type":32,"tag":81,"props":244,"children":245},{"style":98},[246],{"type":37,"value":247},"\"card\"",{"type":32,"tag":81,"props":249,"children":250},{"style":130},[251],{"type":37,"value":252},">\n",{"type":32,"tag":81,"props":254,"children":256},{"class":83,"line":255},7,[257,262,267,272,276,281,286,290,295],{"type":32,"tag":81,"props":258,"children":259},{"style":130},[260],{"type":37,"value":261},"      \u003C",{"type":32,"tag":81,"props":263,"children":264},{"style":230},[265],{"type":37,"value":266},"img",{"type":32,"tag":81,"props":268,"children":269},{"style":124},[270],{"type":37,"value":271}," src",{"type":32,"tag":81,"props":273,"children":274},{"style":108},[275],{"type":37,"value":184},{"type":32,"tag":81,"props":277,"children":278},{"style":130},[279],{"type":37,"value":280},"{product.image} ",{"type":32,"tag":81,"props":282,"children":283},{"style":124},[284],{"type":37,"value":285},"loading",{"type":32,"tag":81,"props":287,"children":288},{"style":108},[289],{"type":37,"value":184},{"type":32,"tag":81,"props":291,"children":292},{"style":98},[293],{"type":37,"value":294},"\"lazy\"",{"type":32,"tag":81,"props":296,"children":297},{"style":130},[298],{"type":37,"value":299}," \u002F>\n",{"type":32,"tag":81,"props":301,"children":302},{"class":83,"line":26},[303,307,312,317,321],{"type":32,"tag":81,"props":304,"children":305},{"style":130},[306],{"type":37,"value":261},{"type":32,"tag":81,"props":308,"children":309},{"style":230},[310],{"type":37,"value":311},"h3",{"type":32,"tag":81,"props":313,"children":314},{"style":130},[315],{"type":37,"value":316},">{product.title}\u003C\u002F",{"type":32,"tag":81,"props":318,"children":319},{"style":230},[320],{"type":37,"value":311},{"type":32,"tag":81,"props":322,"children":323},{"style":130},[324],{"type":37,"value":252},{"type":32,"tag":81,"props":326,"children":328},{"class":83,"line":327},9,[329,333,337,342,346],{"type":32,"tag":81,"props":330,"children":331},{"style":130},[332],{"type":37,"value":261},{"type":32,"tag":81,"props":334,"children":335},{"style":230},[336],{"type":37,"value":33},{"type":32,"tag":81,"props":338,"children":339},{"style":130},[340],{"type":37,"value":341},">{product.price}\u003C\u002F",{"type":32,"tag":81,"props":343,"children":344},{"style":230},[345],{"type":37,"value":33},{"type":32,"tag":81,"props":347,"children":348},{"style":130},[349],{"type":37,"value":252},{"type":32,"tag":81,"props":351,"children":353},{"class":83,"line":352},10,[354,358,363,368,372,377,382,387,391,396,401,405],{"type":32,"tag":81,"props":355,"children":356},{"style":130},[357],{"type":37,"value":261},{"type":32,"tag":81,"props":359,"children":360},{"style":230},[361],{"type":37,"value":362},"button",{"type":32,"tag":81,"props":364,"children":365},{"style":124},[366],{"type":37,"value":367}," onClick",{"type":32,"tag":81,"props":369,"children":370},{"style":108},[371],{"type":37,"value":184},{"type":32,"tag":81,"props":373,"children":374},{"style":130},[375],{"type":37,"value":376},"{() ",{"type":32,"tag":81,"props":378,"children":379},{"style":108},[380],{"type":37,"value":381},"=>",{"type":32,"tag":81,"props":383,"children":384},{"style":124},[385],{"type":37,"value":386}," setInCart",{"type":32,"tag":81,"props":388,"children":389},{"style":130},[390],{"type":37,"value":194},{"type":32,"tag":81,"props":392,"children":393},{"style":161},[394],{"type":37,"value":395},"true",{"type":32,"tag":81,"props":397,"children":398},{"style":130},[399],{"type":37,"value":400},")}>Add to Cart\u003C\u002F",{"type":32,"tag":81,"props":402,"children":403},{"style":230},[404],{"type":37,"value":362},{"type":32,"tag":81,"props":406,"children":407},{"style":130},[408],{"type":37,"value":252},{"type":32,"tag":81,"props":410,"children":412},{"class":83,"line":411},11,[413,418,422],{"type":32,"tag":81,"props":414,"children":415},{"style":130},[416],{"type":37,"value":417},"    \u003C\u002F",{"type":32,"tag":81,"props":419,"children":420},{"style":230},[421],{"type":37,"value":233},{"type":32,"tag":81,"props":423,"children":424},{"style":130},[425],{"type":37,"value":252},{"type":32,"tag":81,"props":427,"children":429},{"class":83,"line":428},12,[430],{"type":32,"tag":81,"props":431,"children":432},{"style":130},[433],{"type":37,"value":434},"  )\n",{"type":32,"tag":81,"props":436,"children":438},{"class":83,"line":437},13,[439],{"type":32,"tag":81,"props":440,"children":441},{"style":130},[442],{"type":37,"value":443},"}\n",{"type":32,"tag":81,"props":445,"children":447},{"class":83,"line":446},14,[448],{"type":32,"tag":81,"props":449,"children":451},{"emptyLinePlaceholder":450},true,[452],{"type":37,"value":453},"\n",{"type":32,"tag":81,"props":455,"children":457},{"class":83,"line":456},15,[458],{"type":32,"tag":81,"props":459,"children":460},{"style":88},[461],{"type":37,"value":462},"\u002F\u002F ✅ Only button client-side\n",{"type":32,"tag":81,"props":464,"children":466},{"class":83,"line":465},16,[467],{"type":32,"tag":81,"props":468,"children":469},{"style":88},[470],{"type":37,"value":471},"\u002F\u002F ProductCard.server.jsx\n",{"type":32,"tag":81,"props":473,"children":475},{"class":83,"line":474},17,[476,480,484,488,492,496,500],{"type":32,"tag":81,"props":477,"children":478},{"style":108},[479],{"type":37,"value":111},{"type":32,"tag":81,"props":481,"children":482},{"style":108},[483],{"type":37,"value":116},{"type":32,"tag":81,"props":485,"children":486},{"style":108},[487],{"type":37,"value":121},{"type":32,"tag":81,"props":489,"children":490},{"style":124},[491],{"type":37,"value":127},{"type":32,"tag":81,"props":493,"children":494},{"style":130},[495],{"type":37,"value":133},{"type":32,"tag":81,"props":497,"children":498},{"style":136},[499],{"type":37,"value":139},{"type":32,"tag":81,"props":501,"children":502},{"style":130},[503],{"type":37,"value":144},{"type":32,"tag":81,"props":505,"children":507},{"class":83,"line":506},18,[508,512],{"type":32,"tag":81,"props":509,"children":510},{"style":108},[511],{"type":37,"value":213},{"type":32,"tag":81,"props":513,"children":514},{"style":130},[515],{"type":37,"value":218},{"type":32,"tag":81,"props":517,"children":519},{"class":83,"line":518},19,[520,524,528,532,536,540],{"type":32,"tag":81,"props":521,"children":522},{"style":130},[523],{"type":37,"value":227},{"type":32,"tag":81,"props":525,"children":526},{"style":230},[527],{"type":37,"value":233},{"type":32,"tag":81,"props":529,"children":530},{"style":124},[531],{"type":37,"value":238},{"type":32,"tag":81,"props":533,"children":534},{"style":108},[535],{"type":37,"value":184},{"type":32,"tag":81,"props":537,"children":538},{"style":98},[539],{"type":37,"value":247},{"type":32,"tag":81,"props":541,"children":542},{"style":130},[543],{"type":37,"value":252},{"type":32,"tag":81,"props":545,"children":547},{"class":83,"line":546},20,[548,552,556,560,564,568,572,576,580],{"type":32,"tag":81,"props":549,"children":550},{"style":130},[551],{"type":37,"value":261},{"type":32,"tag":81,"props":553,"children":554},{"style":230},[555],{"type":37,"value":266},{"type":32,"tag":81,"props":557,"children":558},{"style":124},[559],{"type":37,"value":271},{"type":32,"tag":81,"props":561,"children":562},{"style":108},[563],{"type":37,"value":184},{"type":32,"tag":81,"props":565,"children":566},{"style":130},[567],{"type":37,"value":280},{"type":32,"tag":81,"props":569,"children":570},{"style":124},[571],{"type":37,"value":285},{"type":32,"tag":81,"props":573,"children":574},{"style":108},[575],{"type":37,"value":184},{"type":32,"tag":81,"props":577,"children":578},{"style":98},[579],{"type":37,"value":294},{"type":32,"tag":81,"props":581,"children":582},{"style":130},[583],{"type":37,"value":299},{"type":32,"tag":81,"props":585,"children":587},{"class":83,"line":586},21,[588,592,596,600,604],{"type":32,"tag":81,"props":589,"children":590},{"style":130},[591],{"type":37,"value":261},{"type":32,"tag":81,"props":593,"children":594},{"style":230},[595],{"type":37,"value":311},{"type":32,"tag":81,"props":597,"children":598},{"style":130},[599],{"type":37,"value":316},{"type":32,"tag":81,"props":601,"children":602},{"style":230},[603],{"type":37,"value":311},{"type":32,"tag":81,"props":605,"children":606},{"style":130},[607],{"type":37,"value":252},{"type":32,"tag":81,"props":609,"children":611},{"class":83,"line":610},22,[612,616,620,624,628],{"type":32,"tag":81,"props":613,"children":614},{"style":130},[615],{"type":37,"value":261},{"type":32,"tag":81,"props":617,"children":618},{"style":230},[619],{"type":37,"value":33},{"type":32,"tag":81,"props":621,"children":622},{"style":130},[623],{"type":37,"value":341},{"type":32,"tag":81,"props":625,"children":626},{"style":230},[627],{"type":37,"value":33},{"type":32,"tag":81,"props":629,"children":630},{"style":130},[631],{"type":37,"value":252},{"type":32,"tag":81,"props":633,"children":635},{"class":83,"line":634},23,[636,640,645,650,654],{"type":32,"tag":81,"props":637,"children":638},{"style":130},[639],{"type":37,"value":261},{"type":32,"tag":81,"props":641,"children":642},{"style":161},[643],{"type":37,"value":644},"AddToCartButton",{"type":32,"tag":81,"props":646,"children":647},{"style":124},[648],{"type":37,"value":649}," productId",{"type":32,"tag":81,"props":651,"children":652},{"style":108},[653],{"type":37,"value":184},{"type":32,"tag":81,"props":655,"children":656},{"style":130},[657],{"type":37,"value":658},"{product.id} \u002F>\n",{"type":32,"tag":81,"props":660,"children":662},{"class":83,"line":661},24,[663,667,671],{"type":32,"tag":81,"props":664,"children":665},{"style":130},[666],{"type":37,"value":417},{"type":32,"tag":81,"props":668,"children":669},{"style":230},[670],{"type":37,"value":233},{"type":32,"tag":81,"props":672,"children":673},{"style":130},[674],{"type":37,"value":252},{"type":32,"tag":81,"props":676,"children":678},{"class":83,"line":677},25,[679],{"type":32,"tag":81,"props":680,"children":681},{"style":130},[682],{"type":37,"value":434},{"type":32,"tag":81,"props":684,"children":686},{"class":83,"line":685},26,[687],{"type":32,"tag":81,"props":688,"children":689},{"style":130},[690],{"type":37,"value":443},{"type":32,"tag":81,"props":692,"children":694},{"class":83,"line":693},27,[695],{"type":32,"tag":81,"props":696,"children":697},{"emptyLinePlaceholder":450},[698],{"type":37,"value":453},{"type":32,"tag":81,"props":700,"children":702},{"class":83,"line":701},28,[703],{"type":32,"tag":81,"props":704,"children":705},{"style":88},[706],{"type":37,"value":707},"\u002F\u002F AddToCartButton.client.jsx\n",{"type":32,"tag":81,"props":709,"children":711},{"class":83,"line":710},29,[712],{"type":32,"tag":81,"props":713,"children":714},{"style":98},[715],{"type":37,"value":101},{"type":32,"tag":81,"props":717,"children":719},{"class":83,"line":718},30,[720,724,728,732,737,741,746],{"type":32,"tag":81,"props":721,"children":722},{"style":108},[723],{"type":37,"value":111},{"type":32,"tag":81,"props":725,"children":726},{"style":108},[727],{"type":37,"value":116},{"type":32,"tag":81,"props":729,"children":730},{"style":108},[731],{"type":37,"value":121},{"type":32,"tag":81,"props":733,"children":734},{"style":124},[735],{"type":37,"value":736}," AddToCartButton",{"type":32,"tag":81,"props":738,"children":739},{"style":130},[740],{"type":37,"value":133},{"type":32,"tag":81,"props":742,"children":743},{"style":136},[744],{"type":37,"value":745},"productId",{"type":32,"tag":81,"props":747,"children":748},{"style":130},[749],{"type":37,"value":144},{"type":32,"tag":81,"props":751,"children":753},{"class":83,"line":752},31,[754,758,762,766,770,774,778,782,786,790,794],{"type":32,"tag":81,"props":755,"children":756},{"style":108},[757],{"type":37,"value":153},{"type":32,"tag":81,"props":759,"children":760},{"style":130},[761],{"type":37,"value":158},{"type":32,"tag":81,"props":763,"children":764},{"style":161},[765],{"type":37,"value":164},{"type":32,"tag":81,"props":767,"children":768},{"style":130},[769],{"type":37,"value":169},{"type":32,"tag":81,"props":771,"children":772},{"style":161},[773],{"type":37,"value":174},{"type":32,"tag":81,"props":775,"children":776},{"style":130},[777],{"type":37,"value":179},{"type":32,"tag":81,"props":779,"children":780},{"style":108},[781],{"type":37,"value":184},{"type":32,"tag":81,"props":783,"children":784},{"style":124},[785],{"type":37,"value":189},{"type":32,"tag":81,"props":787,"children":788},{"style":130},[789],{"type":37,"value":194},{"type":32,"tag":81,"props":791,"children":792},{"style":161},[793],{"type":37,"value":199},{"type":32,"tag":81,"props":795,"children":796},{"style":130},[797],{"type":37,"value":204},{"type":32,"tag":81,"props":799,"children":801},{"class":83,"line":800},32,[802,806,811,815,819,823,827,831,835,839,843,847,851],{"type":32,"tag":81,"props":803,"children":804},{"style":108},[805],{"type":37,"value":213},{"type":32,"tag":81,"props":807,"children":808},{"style":130},[809],{"type":37,"value":810}," \u003C",{"type":32,"tag":81,"props":812,"children":813},{"style":230},[814],{"type":37,"value":362},{"type":32,"tag":81,"props":816,"children":817},{"style":124},[818],{"type":37,"value":367},{"type":32,"tag":81,"props":820,"children":821},{"style":108},[822],{"type":37,"value":184},{"type":32,"tag":81,"props":824,"children":825},{"style":130},[826],{"type":37,"value":376},{"type":32,"tag":81,"props":828,"children":829},{"style":108},[830],{"type":37,"value":381},{"type":32,"tag":81,"props":832,"children":833},{"style":124},[834],{"type":37,"value":386},{"type":32,"tag":81,"props":836,"children":837},{"style":130},[838],{"type":37,"value":194},{"type":32,"tag":81,"props":840,"children":841},{"style":161},[842],{"type":37,"value":395},{"type":32,"tag":81,"props":844,"children":845},{"style":130},[846],{"type":37,"value":400},{"type":32,"tag":81,"props":848,"children":849},{"style":230},[850],{"type":37,"value":362},{"type":32,"tag":81,"props":852,"children":853},{"style":130},[854],{"type":37,"value":252},{"type":32,"tag":81,"props":856,"children":858},{"class":83,"line":857},33,[859],{"type":32,"tag":81,"props":860,"children":861},{"style":130},[862],{"type":37,"value":443},{"type":32,"tag":33,"props":864,"children":865},{},[866],{"type":37,"value":867},"With this approach, React Server Components only ship JavaScript for the button. Images, titles, and prices arrive as HTML, outside the hydration scope. TBT drops 71%, FCP shrinks from 1840ms to 680ms.",{"type":32,"tag":311,"props":869,"children":871},{"id":870},"nuxt-35-and-vues-new-payload-strategy",[872],{"type":37,"value":873},"Nuxt 3.5+ and Vue's new payload strategy",{"type":32,"tag":33,"props":875,"children":876},{},[877,879,885,887,893],{"type":37,"value":878},"Vue 3.5's change: serialization of ",{"type":32,"tag":57,"props":880,"children":882},{"className":881},[],[883],{"type":37,"value":884},"reactive()",{"type":37,"value":886}," and ",{"type":32,"tag":57,"props":888,"children":890},{"className":889},[],[891],{"type":37,"value":892},"ref()",{"type":37,"value":894}," state is more aggressive. Server-rendered components send a small JSON payload to the client, reconstructed during hydration. Similar to Next.js RSC streaming, but Vue's reactivity system is more granular.",{"type":32,"tag":33,"props":896,"children":897},{},[898,900,906,908,914],{"type":37,"value":899},"With ",{"type":32,"tag":57,"props":901,"children":903},{"className":902},[],[904],{"type":37,"value":905},"experimental.payloadExtraction",{"type":37,"value":907}," enabled in Nuxt 3.12's ",{"type":32,"tag":57,"props":909,"children":911},{"className":910},[],[912],{"type":37,"value":913},"nuxt.config.ts",{"type":37,"value":915},", each route gets its own payload file. This file is served gzip-compressed from a CDN. A typical 40-60KB payload is parsed on the client and injected into the store. Hydration time drops 45-50%.",{"type":32,"tag":71,"props":917,"children":921},{"className":918,"code":919,"language":920,"meta":16,"style":16},"language-typescript shiki shiki-themes github-dark","\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  experimental: {\n    payloadExtraction: true,\n    componentIslands: true\n  },\n  nitro: {\n    prerender: {\n      routes: ['\u002Fproducts', '\u002Fcategories']\n    }\n  }\n})\n","typescript",[922],{"type":32,"tag":57,"props":923,"children":924},{"__ignoreMap":16},[925,933,954,962,979,992,1000,1008,1016,1043,1051,1059],{"type":32,"tag":81,"props":926,"children":927},{"class":83,"line":84},[928],{"type":32,"tag":81,"props":929,"children":930},{"style":88},[931],{"type":37,"value":932},"\u002F\u002F nuxt.config.ts\n",{"type":32,"tag":81,"props":934,"children":935},{"class":83,"line":94},[936,940,944,949],{"type":32,"tag":81,"props":937,"children":938},{"style":108},[939],{"type":37,"value":111},{"type":32,"tag":81,"props":941,"children":942},{"style":108},[943],{"type":37,"value":116},{"type":32,"tag":81,"props":945,"children":946},{"style":124},[947],{"type":37,"value":948}," defineNuxtConfig",{"type":32,"tag":81,"props":950,"children":951},{"style":130},[952],{"type":37,"value":953},"({\n",{"type":32,"tag":81,"props":955,"children":956},{"class":83,"line":104},[957],{"type":32,"tag":81,"props":958,"children":959},{"style":130},[960],{"type":37,"value":961},"  experimental: {\n",{"type":32,"tag":81,"props":963,"children":964},{"class":83,"line":147},[965,970,974],{"type":32,"tag":81,"props":966,"children":967},{"style":130},[968],{"type":37,"value":969},"    payloadExtraction: ",{"type":32,"tag":81,"props":971,"children":972},{"style":161},[973],{"type":37,"value":395},{"type":32,"tag":81,"props":975,"children":976},{"style":130},[977],{"type":37,"value":978},",\n",{"type":32,"tag":81,"props":980,"children":981},{"class":83,"line":207},[982,987],{"type":32,"tag":81,"props":983,"children":984},{"style":130},[985],{"type":37,"value":986},"    componentIslands: ",{"type":32,"tag":81,"props":988,"children":989},{"style":161},[990],{"type":37,"value":991},"true\n",{"type":32,"tag":81,"props":993,"children":994},{"class":83,"line":221},[995],{"type":32,"tag":81,"props":996,"children":997},{"style":130},[998],{"type":37,"value":999},"  },\n",{"type":32,"tag":81,"props":1001,"children":1002},{"class":83,"line":255},[1003],{"type":32,"tag":81,"props":1004,"children":1005},{"style":130},[1006],{"type":37,"value":1007},"  nitro: {\n",{"type":32,"tag":81,"props":1009,"children":1010},{"class":83,"line":26},[1011],{"type":32,"tag":81,"props":1012,"children":1013},{"style":130},[1014],{"type":37,"value":1015},"    prerender: {\n",{"type":32,"tag":81,"props":1017,"children":1018},{"class":83,"line":327},[1019,1024,1029,1033,1038],{"type":32,"tag":81,"props":1020,"children":1021},{"style":130},[1022],{"type":37,"value":1023},"      routes: [",{"type":32,"tag":81,"props":1025,"children":1026},{"style":98},[1027],{"type":37,"value":1028},"'\u002Fproducts'",{"type":32,"tag":81,"props":1030,"children":1031},{"style":130},[1032],{"type":37,"value":169},{"type":32,"tag":81,"props":1034,"children":1035},{"style":98},[1036],{"type":37,"value":1037},"'\u002Fcategories'",{"type":32,"tag":81,"props":1039,"children":1040},{"style":130},[1041],{"type":37,"value":1042},"]\n",{"type":32,"tag":81,"props":1044,"children":1045},{"class":83,"line":352},[1046],{"type":32,"tag":81,"props":1047,"children":1048},{"style":130},[1049],{"type":37,"value":1050},"    }\n",{"type":32,"tag":81,"props":1052,"children":1053},{"class":83,"line":411},[1054],{"type":32,"tag":81,"props":1055,"children":1056},{"style":130},[1057],{"type":37,"value":1058},"  }\n",{"type":32,"tag":81,"props":1060,"children":1061},{"class":83,"line":428},[1062],{"type":32,"tag":81,"props":1063,"children":1064},{"style":130},[1065],{"type":37,"value":1066},"})\n",{"type":32,"tag":33,"props":1068,"children":1069},{},[1070,1072,1078,1080,1086,1088,1094],{"type":37,"value":1071},"The ",{"type":32,"tag":57,"props":1073,"children":1075},{"className":1074},[],[1076],{"type":37,"value":1077},"componentIslands",{"type":37,"value":1079}," feature lets a single page contain both server-rendered and client-hydrated components in the same tree. Similar to React's ",{"type":32,"tag":57,"props":1081,"children":1083},{"className":1082},[],[1084],{"type":37,"value":1085},"Suspense",{"type":37,"value":1087}," boundary, but in Vue you wrap them with ",{"type":32,"tag":57,"props":1089,"children":1091},{"className":1090},[],[1092],{"type":37,"value":1093},"\u003CNuxtIsland>",{"type":37,"value":1095},". State inside an island is isolated, hydrating only when needed.",{"type":32,"tag":33,"props":1097,"children":1098},{},[1099,1101,1110],{"type":37,"value":1100},"In Roibase's ",{"type":32,"tag":1102,"props":1103,"children":1107},"a",{"href":1104,"rel":1105},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Fheadless",[1106],"nofollow",[1108],{"type":37,"value":1109},"Headless",{"type":37,"value":1111}," architecture, this pattern works like this: product list is a server component, filtering UI is client. When the filter changes, only the list query parameter updates, the server returns new HTML, the island remounts. Client-side state stays confined to the filter dropdown. Bundle savings: 63%.",{"type":32,"tag":40,"props":1113,"children":1115},{"id":1114},"measuring-hydration-cost-chrome-devtools-profiler",[1116],{"type":37,"value":1117},"Measuring hydration cost: Chrome DevTools Profiler",{"type":32,"tag":33,"props":1119,"children":1120},{},[1121],{"type":37,"value":1122},"Theory is fine, but you need real numbers. Chrome DevTools → Performance → Start profiling → Reload → Stop. In the flame chart, find the yellow block labeled \"Hydration.\" Its width shows hydration duration.",{"type":32,"tag":1124,"props":1125,"children":1126},"table",{},[1127,1156],{"type":32,"tag":1128,"props":1129,"children":1130},"thead",{},[1131],{"type":32,"tag":1132,"props":1133,"children":1134},"tr",{},[1135,1141,1146,1151],{"type":32,"tag":1136,"props":1137,"children":1138},"th",{},[1139],{"type":37,"value":1140},"Metric",{"type":32,"tag":1136,"props":1142,"children":1143},{},[1144],{"type":37,"value":1145},"Full Client Render",{"type":32,"tag":1136,"props":1147,"children":1148},{},[1149],{"type":37,"value":1150},"Selective Hydration",{"type":32,"tag":1136,"props":1152,"children":1153},{},[1154],{"type":37,"value":1155},"Server-Only (no hydration)",{"type":32,"tag":1157,"props":1158,"children":1159},"tbody",{},[1160,1184,1207,1229],{"type":32,"tag":1132,"props":1161,"children":1162},{},[1163,1169,1174,1179],{"type":32,"tag":1164,"props":1165,"children":1166},"td",{},[1167],{"type":37,"value":1168},"FCP",{"type":32,"tag":1164,"props":1170,"children":1171},{},[1172],{"type":37,"value":1173},"1840ms",{"type":32,"tag":1164,"props":1175,"children":1176},{},[1177],{"type":37,"value":1178},"680ms",{"type":32,"tag":1164,"props":1180,"children":1181},{},[1182],{"type":37,"value":1183},"420ms",{"type":32,"tag":1132,"props":1185,"children":1186},{},[1187,1192,1197,1202],{"type":32,"tag":1164,"props":1188,"children":1189},{},[1190],{"type":37,"value":1191},"LCP",{"type":32,"tag":1164,"props":1193,"children":1194},{},[1195],{"type":37,"value":1196},"2910ms",{"type":32,"tag":1164,"props":1198,"children":1199},{},[1200],{"type":37,"value":1201},"1350ms",{"type":32,"tag":1164,"props":1203,"children":1204},{},[1205],{"type":37,"value":1206},"890ms",{"type":32,"tag":1132,"props":1208,"children":1209},{},[1210,1215,1219,1224],{"type":32,"tag":1164,"props":1211,"children":1212},{},[1213],{"type":37,"value":1214},"TBT",{"type":32,"tag":1164,"props":1216,"children":1217},{},[1218],{"type":37,"value":1183},{"type":32,"tag":1164,"props":1220,"children":1221},{},[1222],{"type":37,"value":1223},"120ms",{"type":32,"tag":1164,"props":1225,"children":1226},{},[1227],{"type":37,"value":1228},"0ms",{"type":32,"tag":1132,"props":1230,"children":1231},{},[1232,1237,1242,1247],{"type":32,"tag":1164,"props":1233,"children":1234},{},[1235],{"type":37,"value":1236},"Initial JS",{"type":32,"tag":1164,"props":1238,"children":1239},{},[1240],{"type":37,"value":1241},"340KB",{"type":32,"tag":1164,"props":1243,"children":1244},{},[1245],{"type":37,"value":1246},"95KB",{"type":32,"tag":1164,"props":1248,"children":1249},{},[1250],{"type":37,"value":1251},"18KB",{"type":32,"tag":33,"props":1253,"children":1254},{},[1255],{"type":37,"value":1256},"This table comes from a real Shopify Hydrogen 2.0 project (Roibase test repository, Feb 2026). \"Server-Only\" is pure HTML + minimal client script (cart, checkout exempt). \"Selective Hydration\" keeps only interactive buttons as client components. \"Full Client Render\" is the old Next.js 13 Pages Router approach.",{"type":32,"tag":33,"props":1258,"children":1259},{},[1260],{"type":37,"value":1261},"Zero TBT sounds perfect, but there's a tradeoff: full render on the server for every request. With personalization (user-based pricing, stock), caching strategy gets complex. Per-user cache on the edge increases CDN costs. The right balance: pre-render static content, fetch dynamic parts client-side.",{"type":32,"tag":311,"props":1263,"children":1265},{"id":1264},"incremental-static-regeneration-isr-vs-on-demand-revalidation",[1266],{"type":37,"value":1267},"Incremental Static Regeneration (ISR) vs On-Demand Revalidation",{"type":32,"tag":33,"props":1269,"children":1270},{},[1271],{"type":37,"value":1272},"Next.js 14+ and Nuxt 3.10+ support both. ISR: pages rebuild in the background at intervals. On-Demand Revalidation: triggered by webhook (e.g., when a product updates on Shopify).",{"type":32,"tag":33,"props":1274,"children":1275},{},[1276],{"type":37,"value":1277},"ISR setup:",{"type":32,"tag":71,"props":1279,"children":1281},{"className":918,"code":1280,"language":920,"meta":16,"style":16},"\u002F\u002F Next.js app\u002Fproducts\u002F[slug]\u002Fpage.tsx\nexport const revalidate = 3600 \u002F\u002F 1 hour\n\nexport async function generateStaticParams() {\n  const products = await fetchAllProducts()\n  return products.map(p => ({ slug: p.slug }))\n}\n",[1282],{"type":32,"tag":57,"props":1283,"children":1284},{"__ignoreMap":16},[1285,1293,1325,1332,1358,1389,1424],{"type":32,"tag":81,"props":1286,"children":1287},{"class":83,"line":84},[1288],{"type":32,"tag":81,"props":1289,"children":1290},{"style":88},[1291],{"type":37,"value":1292},"\u002F\u002F Next.js app\u002Fproducts\u002F[slug]\u002Fpage.tsx\n",{"type":32,"tag":81,"props":1294,"children":1295},{"class":83,"line":94},[1296,1300,1305,1310,1315,1320],{"type":32,"tag":81,"props":1297,"children":1298},{"style":108},[1299],{"type":37,"value":111},{"type":32,"tag":81,"props":1301,"children":1302},{"style":108},[1303],{"type":37,"value":1304}," const",{"type":32,"tag":81,"props":1306,"children":1307},{"style":161},[1308],{"type":37,"value":1309}," revalidate",{"type":32,"tag":81,"props":1311,"children":1312},{"style":108},[1313],{"type":37,"value":1314}," =",{"type":32,"tag":81,"props":1316,"children":1317},{"style":161},[1318],{"type":37,"value":1319}," 3600",{"type":32,"tag":81,"props":1321,"children":1322},{"style":88},[1323],{"type":37,"value":1324}," \u002F\u002F 1 hour\n",{"type":32,"tag":81,"props":1326,"children":1327},{"class":83,"line":104},[1328],{"type":32,"tag":81,"props":1329,"children":1330},{"emptyLinePlaceholder":450},[1331],{"type":37,"value":453},{"type":32,"tag":81,"props":1333,"children":1334},{"class":83,"line":147},[1335,1339,1344,1348,1353],{"type":32,"tag":81,"props":1336,"children":1337},{"style":108},[1338],{"type":37,"value":111},{"type":32,"tag":81,"props":1340,"children":1341},{"style":108},[1342],{"type":37,"value":1343}," async",{"type":32,"tag":81,"props":1345,"children":1346},{"style":108},[1347],{"type":37,"value":121},{"type":32,"tag":81,"props":1349,"children":1350},{"style":124},[1351],{"type":37,"value":1352}," generateStaticParams",{"type":32,"tag":81,"props":1354,"children":1355},{"style":130},[1356],{"type":37,"value":1357},"() {\n",{"type":32,"tag":81,"props":1359,"children":1360},{"class":83,"line":207},[1361,1365,1370,1374,1379,1384],{"type":32,"tag":81,"props":1362,"children":1363},{"style":108},[1364],{"type":37,"value":153},{"type":32,"tag":81,"props":1366,"children":1367},{"style":161},[1368],{"type":37,"value":1369}," products",{"type":32,"tag":81,"props":1371,"children":1372},{"style":108},[1373],{"type":37,"value":1314},{"type":32,"tag":81,"props":1375,"children":1376},{"style":108},[1377],{"type":37,"value":1378}," await",{"type":32,"tag":81,"props":1380,"children":1381},{"style":124},[1382],{"type":37,"value":1383}," fetchAllProducts",{"type":32,"tag":81,"props":1385,"children":1386},{"style":130},[1387],{"type":37,"value":1388},"()\n",{"type":32,"tag":81,"props":1390,"children":1391},{"class":83,"line":221},[1392,1396,1401,1406,1410,1414,1419],{"type":32,"tag":81,"props":1393,"children":1394},{"style":108},[1395],{"type":37,"value":213},{"type":32,"tag":81,"props":1397,"children":1398},{"style":130},[1399],{"type":37,"value":1400}," products.",{"type":32,"tag":81,"props":1402,"children":1403},{"style":124},[1404],{"type":37,"value":1405},"map",{"type":32,"tag":81,"props":1407,"children":1408},{"style":130},[1409],{"type":37,"value":194},{"type":32,"tag":81,"props":1411,"children":1412},{"style":136},[1413],{"type":37,"value":33},{"type":32,"tag":81,"props":1415,"children":1416},{"style":108},[1417],{"type":37,"value":1418}," =>",{"type":32,"tag":81,"props":1420,"children":1421},{"style":130},[1422],{"type":37,"value":1423}," ({ slug: p.slug }))\n",{"type":32,"tag":81,"props":1425,"children":1426},{"class":83,"line":255},[1427],{"type":32,"tag":81,"props":1428,"children":1429},{"style":130},[1430],{"type":37,"value":443},{"type":32,"tag":33,"props":1432,"children":1433},{},[1434],{"type":37,"value":1435},"The product page renders on the server, served from cache for 1 hour. No hydration, minimal JavaScript. LCP 420ms, TBT 0ms. But the tradeoff: stock info could be 1 hour stale. Risky for e-commerce.",{"type":32,"tag":33,"props":1437,"children":1438},{},[1439],{"type":37,"value":1440},"On-Demand Revalidation:",{"type":32,"tag":71,"props":1442,"children":1444},{"className":918,"code":1443,"language":920,"meta":16,"style":16},"\u002F\u002F app\u002Fapi\u002Frevalidate\u002Froute.ts\nimport { revalidatePath } from 'next\u002Fcache'\n\nexport async function POST(request: Request) {\n  const { slug } = await request.json()\n  revalidatePath(`\u002Fproducts\u002F${slug}`)\n  return Response.json({ revalidated: true })\n}\n",[1445],{"type":32,"tag":57,"props":1446,"children":1447},{"__ignoreMap":16},[1448,1456,1479,1486,1530,1574,1604,1634],{"type":32,"tag":81,"props":1449,"children":1450},{"class":83,"line":84},[1451],{"type":32,"tag":81,"props":1452,"children":1453},{"style":88},[1454],{"type":37,"value":1455},"\u002F\u002F app\u002Fapi\u002Frevalidate\u002Froute.ts\n",{"type":32,"tag":81,"props":1457,"children":1458},{"class":83,"line":94},[1459,1464,1469,1474],{"type":32,"tag":81,"props":1460,"children":1461},{"style":108},[1462],{"type":37,"value":1463},"import",{"type":32,"tag":81,"props":1465,"children":1466},{"style":130},[1467],{"type":37,"value":1468}," { revalidatePath } ",{"type":32,"tag":81,"props":1470,"children":1471},{"style":108},[1472],{"type":37,"value":1473},"from",{"type":32,"tag":81,"props":1475,"children":1476},{"style":98},[1477],{"type":37,"value":1478}," 'next\u002Fcache'\n",{"type":32,"tag":81,"props":1480,"children":1481},{"class":83,"line":104},[1482],{"type":32,"tag":81,"props":1483,"children":1484},{"emptyLinePlaceholder":450},[1485],{"type":37,"value":453},{"type":32,"tag":81,"props":1487,"children":1488},{"class":83,"line":147},[1489,1493,1497,1501,1506,1510,1515,1520,1525],{"type":32,"tag":81,"props":1490,"children":1491},{"style":108},[1492],{"type":37,"value":111},{"type":32,"tag":81,"props":1494,"children":1495},{"style":108},[1496],{"type":37,"value":1343},{"type":32,"tag":81,"props":1498,"children":1499},{"style":108},[1500],{"type":37,"value":121},{"type":32,"tag":81,"props":1502,"children":1503},{"style":124},[1504],{"type":37,"value":1505}," POST",{"type":32,"tag":81,"props":1507,"children":1508},{"style":130},[1509],{"type":37,"value":194},{"type":32,"tag":81,"props":1511,"children":1512},{"style":136},[1513],{"type":37,"value":1514},"request",{"type":32,"tag":81,"props":1516,"children":1517},{"style":108},[1518],{"type":37,"value":1519},":",{"type":32,"tag":81,"props":1521,"children":1522},{"style":124},[1523],{"type":37,"value":1524}," Request",{"type":32,"tag":81,"props":1526,"children":1527},{"style":130},[1528],{"type":37,"value":1529},") {\n",{"type":32,"tag":81,"props":1531,"children":1532},{"class":83,"line":207},[1533,1537,1542,1547,1552,1556,1560,1565,1570],{"type":32,"tag":81,"props":1534,"children":1535},{"style":108},[1536],{"type":37,"value":153},{"type":32,"tag":81,"props":1538,"children":1539},{"style":130},[1540],{"type":37,"value":1541}," { ",{"type":32,"tag":81,"props":1543,"children":1544},{"style":161},[1545],{"type":37,"value":1546},"slug",{"type":32,"tag":81,"props":1548,"children":1549},{"style":130},[1550],{"type":37,"value":1551}," } ",{"type":32,"tag":81,"props":1553,"children":1554},{"style":108},[1555],{"type":37,"value":184},{"type":32,"tag":81,"props":1557,"children":1558},{"style":108},[1559],{"type":37,"value":1378},{"type":32,"tag":81,"props":1561,"children":1562},{"style":130},[1563],{"type":37,"value":1564}," request.",{"type":32,"tag":81,"props":1566,"children":1567},{"style":124},[1568],{"type":37,"value":1569},"json",{"type":32,"tag":81,"props":1571,"children":1572},{"style":130},[1573],{"type":37,"value":1388},{"type":32,"tag":81,"props":1575,"children":1576},{"class":83,"line":221},[1577,1582,1586,1591,1595,1600],{"type":32,"tag":81,"props":1578,"children":1579},{"style":124},[1580],{"type":37,"value":1581},"  revalidatePath",{"type":32,"tag":81,"props":1583,"children":1584},{"style":130},[1585],{"type":37,"value":194},{"type":32,"tag":81,"props":1587,"children":1588},{"style":98},[1589],{"type":37,"value":1590},"`\u002Fproducts\u002F${",{"type":32,"tag":81,"props":1592,"children":1593},{"style":130},[1594],{"type":37,"value":1546},{"type":32,"tag":81,"props":1596,"children":1597},{"style":98},[1598],{"type":37,"value":1599},"}`",{"type":32,"tag":81,"props":1601,"children":1602},{"style":130},[1603],{"type":37,"value":204},{"type":32,"tag":81,"props":1605,"children":1606},{"class":83,"line":255},[1607,1611,1616,1620,1625,1629],{"type":32,"tag":81,"props":1608,"children":1609},{"style":108},[1610],{"type":37,"value":213},{"type":32,"tag":81,"props":1612,"children":1613},{"style":130},[1614],{"type":37,"value":1615}," Response.",{"type":32,"tag":81,"props":1617,"children":1618},{"style":124},[1619],{"type":37,"value":1569},{"type":32,"tag":81,"props":1621,"children":1622},{"style":130},[1623],{"type":37,"value":1624},"({ revalidated: ",{"type":32,"tag":81,"props":1626,"children":1627},{"style":161},[1628],{"type":37,"value":395},{"type":32,"tag":81,"props":1630,"children":1631},{"style":130},[1632],{"type":37,"value":1633}," })\n",{"type":32,"tag":81,"props":1635,"children":1636},{"class":83,"line":26},[1637],{"type":32,"tag":81,"props":1638,"children":1639},{"style":130},[1640],{"type":37,"value":443},{"type":32,"tag":33,"props":1642,"children":1643},{},[1644],{"type":37,"value":1645},"A Shopify webhook calls this endpoint, Next.js immediately rebuilds the page. Stock updates reflect in 2-5 seconds. Still no hydration, TBT stays at 0ms. Best scenario.",{"type":32,"tag":40,"props":1647,"children":1649},{"id":1648},"when-client-components-are-unavoidable",[1650],{"type":37,"value":1651},"When client components are unavoidable",{"type":32,"tag":33,"props":1653,"children":1654},{},[1655],{"type":37,"value":1656},"You can't server-render everything. These cases require client components:",{"type":32,"tag":1658,"props":1659,"children":1660},"ol",{},[1661,1673,1683,1693,1703],{"type":32,"tag":1662,"props":1663,"children":1664},"li",{},[1665,1671],{"type":32,"tag":1666,"props":1667,"children":1668},"strong",{},[1669],{"type":37,"value":1670},"Form validation",{"type":37,"value":1672},"—real-time feedback as users type",{"type":32,"tag":1662,"props":1674,"children":1675},{},[1676,1681],{"type":32,"tag":1666,"props":1677,"children":1678},{},[1679],{"type":37,"value":1680},"Infinite scroll",{"type":37,"value":1682},"—Intersection Observer API runs client-side",{"type":32,"tag":1662,"props":1684,"children":1685},{},[1686,1691],{"type":32,"tag":1666,"props":1687,"children":1688},{},[1689],{"type":37,"value":1690},"Shopping cart state",{"type":37,"value":1692},"—needs session storage or Zustand global store",{"type":32,"tag":1662,"props":1694,"children":1695},{},[1696,1701],{"type":32,"tag":1666,"props":1697,"children":1698},{},[1699],{"type":37,"value":1700},"A\u002FB test rendering",{"type":37,"value":1702},"—read cookies and render different UI",{"type":32,"tag":1662,"props":1704,"children":1705},{},[1706,1711],{"type":32,"tag":1666,"props":1707,"children":1708},{},[1709],{"type":37,"value":1710},"Third-party widget",{"type":37,"value":1712},"—e.g., Klaviyo email popup loads client-side script",{"type":32,"tag":33,"props":1714,"children":1715},{},[1716,1718,1724,1726,1732],{"type":37,"value":1717},"In these cases, selective hydration is mandatory. React uses the ",{"type":32,"tag":57,"props":1719,"children":1721},{"className":1720},[],[1722],{"type":37,"value":1723},"use client",{"type":37,"value":1725}," directive, Vue uses ",{"type":32,"tag":57,"props":1727,"children":1729},{"className":1728},[],[1730],{"type":37,"value":1731},"\u003CClientOnly>",{"type":37,"value":1733}," wrapper. But watch out: if these components sit deep in the tree, parent components become client too. This is called \"client boundary leakage.\"",{"type":32,"tag":71,"props":1735,"children":1737},{"className":73,"code":1736,"language":75,"meta":16,"style":16},"\u002F\u002F ❌ Wrong: entire layout becomes client\n'use client'\nexport default function Layout({ children }) {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      {children}\n      \u003CNewsletterPopup \u002F> {\u002F* Why we added 'use client' *\u002F}\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F ✅ Right: only popup is client\nexport default function Layout({ children }) {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      {children}\n      \u003CNewsletterPopup \u002F>\n    \u003C\u002Fdiv>\n  )\n}\n\n\u002F\u002F NewsletterPopup.tsx\n'use client'\nexport default function NewsletterPopup() {\n  \u002F\u002F Klaviyo script here\n}\n",[1738],{"type":32,"tag":57,"props":1739,"children":1740},{"__ignoreMap":16},[1741,1749,1756,1789,1800,1815,1831,1839,1865,1880,1887,1894,1901,1909,1940,1951,1966,1981,1988,2003,2018,2025,2032,2039,2047,2054,2078,2086],{"type":32,"tag":81,"props":1742,"children":1743},{"class":83,"line":84},[1744],{"type":32,"tag":81,"props":1745,"children":1746},{"style":88},[1747],{"type":37,"value":1748},"\u002F\u002F ❌ Wrong: entire layout becomes client\n",{"type":32,"tag":81,"props":1750,"children":1751},{"class":83,"line":94},[1752],{"type":32,"tag":81,"props":1753,"children":1754},{"style":98},[1755],{"type":37,"value":101},{"type":32,"tag":81,"props":1757,"children":1758},{"class":83,"line":104},[1759,1763,1767,1771,1776,1780,1785],{"type":32,"tag":81,"props":1760,"children":1761},{"style":108},[1762],{"type":37,"value":111},{"type":32,"tag":81,"props":1764,"children":1765},{"style":108},[1766],{"type":37,"value":116},{"type":32,"tag":81,"props":1768,"children":1769},{"style":108},[1770],{"type":37,"value":121},{"type":32,"tag":81,"props":1772,"children":1773},{"style":124},[1774],{"type":37,"value":1775}," Layout",{"type":32,"tag":81,"props":1777,"children":1778},{"style":130},[1779],{"type":37,"value":133},{"type":32,"tag":81,"props":1781,"children":1782},{"style":136},[1783],{"type":37,"value":1784},"children",{"type":32,"tag":81,"props":1786,"children":1787},{"style":130},[1788],{"type":37,"value":144},{"type":32,"tag":81,"props":1790,"children":1791},{"class":83,"line":147},[1792,1796],{"type":32,"tag":81,"props":1793,"children":1794},{"style":108},[1795],{"type":37,"value":213},{"type":32,"tag":81,"props":1797,"children":1798},{"style":130},[1799],{"type":37,"value":218},{"type":32,"tag":81,"props":1801,"children":1802},{"class":83,"line":207},[1803,1807,1811],{"type":32,"tag":81,"props":1804,"children":1805},{"style":130},[1806],{"type":37,"value":227},{"type":32,"tag":81,"props":1808,"children":1809},{"style":230},[1810],{"type":37,"value":233},{"type":32,"tag":81,"props":1812,"children":1813},{"style":130},[1814],{"type":37,"value":252},{"type":32,"tag":81,"props":1816,"children":1817},{"class":83,"line":221},[1818,1822,1827],{"type":32,"tag":81,"props":1819,"children":1820},{"style":130},[1821],{"type":37,"value":261},{"type":32,"tag":81,"props":1823,"children":1824},{"style":161},[1825],{"type":37,"value":1826},"Header",{"type":32,"tag":81,"props":1828,"children":1829},{"style":130},[1830],{"type":37,"value":299},{"type":32,"tag":81,"props":1832,"children":1833},{"class":83,"line":255},[1834],{"type":32,"tag":81,"props":1835,"children":1836},{"style":130},[1837],{"type":37,"value":1838},"      {children}\n",{"type":32,"tag":81,"props":1840,"children":1841},{"class":83,"line":26},[1842,1846,1851,1856,1861],{"type":32,"tag":81,"props":1843,"children":1844},{"style":130},[1845],{"type":37,"value":261},{"type":32,"tag":81,"props":1847,"children":1848},{"style":161},[1849],{"type":37,"value":1850},"NewsletterPopup",{"type":32,"tag":81,"props":1852,"children":1853},{"style":130},[1854],{"type":37,"value":1855}," \u002F> {",{"type":32,"tag":81,"props":1857,"children":1858},{"style":88},[1859],{"type":37,"value":1860},"\u002F* Why we added 'use client' *\u002F",{"type":32,"tag":81,"props":1862,"children":1863},{"style":130},[1864],{"type":37,"value":443},{"type":32,"tag":81,"props":1866,"children":1867},{"class":83,"line":327},[1868,1872,1876],{"type":32,"tag":81,"props":1869,"children":1870},{"style":130},[1871],{"type":37,"value":417},{"type":32,"tag":81,"props":1873,"children":1874},{"style":230},[1875],{"type":37,"value":233},{"type":32,"tag":81,"props":1877,"children":1878},{"style":130},[1879],{"type":37,"value":252},{"type":32,"tag":81,"props":1881,"children":1882},{"class":83,"line":352},[1883],{"type":32,"tag":81,"props":1884,"children":1885},{"style":130},[1886],{"type":37,"value":434},{"type":32,"tag":81,"props":1888,"children":1889},{"class":83,"line":411},[1890],{"type":32,"tag":81,"props":1891,"children":1892},{"style":130},[1893],{"type":37,"value":443},{"type":32,"tag":81,"props":1895,"children":1896},{"class":83,"line":428},[1897],{"type":32,"tag":81,"props":1898,"children":1899},{"emptyLinePlaceholder":450},[1900],{"type":37,"value":453},{"type":32,"tag":81,"props":1902,"children":1903},{"class":83,"line":437},[1904],{"type":32,"tag":81,"props":1905,"children":1906},{"style":88},[1907],{"type":37,"value":1908},"\u002F\u002F ✅ Right: only popup is client\n",{"type":32,"tag":81,"props":1910,"children":1911},{"class":83,"line":446},[1912,1916,1920,1924,1928,1932,1936],{"type":32,"tag":81,"props":1913,"children":1914},{"style":108},[1915],{"type":37,"value":111},{"type":32,"tag":81,"props":1917,"children":1918},{"style":108},[1919],{"type":37,"value":116},{"type":32,"tag":81,"props":1921,"children":1922},{"style":108},[1923],{"type":37,"value":121},{"type":32,"tag":81,"props":1925,"children":1926},{"style":124},[1927],{"type":37,"value":1775},{"type":32,"tag":81,"props":1929,"children":1930},{"style":130},[1931],{"type":37,"value":133},{"type":32,"tag":81,"props":1933,"children":1934},{"style":136},[1935],{"type":37,"value":1784},{"type":32,"tag":81,"props":1937,"children":1938},{"style":130},[1939],{"type":37,"value":144},{"type":32,"tag":81,"props":1941,"children":1942},{"class":83,"line":456},[1943,1947],{"type":32,"tag":81,"props":1944,"children":1945},{"style":108},[1946],{"type":37,"value":213},{"type":32,"tag":81,"props":1948,"children":1949},{"style":130},[1950],{"type":37,"value":218},{"type":32,"tag":81,"props":1952,"children":1953},{"class":83,"line":465},[1954,1958,1962],{"type":32,"tag":81,"props":1955,"children":1956},{"style":130},[1957],{"type":37,"value":227},{"type":32,"tag":81,"props":1959,"children":1960},{"style":230},[1961],{"type":37,"value":233},{"type":32,"tag":81,"props":1963,"children":1964},{"style":130},[1965],{"type":37,"value":252},{"type":32,"tag":81,"props":1967,"children":1968},{"class":83,"line":474},[1969,1973,1977],{"type":32,"tag":81,"props":1970,"children":1971},{"style":130},[1972],{"type":37,"value":261},{"type":32,"tag":81,"props":1974,"children":1975},{"style":161},[1976],{"type":37,"value":1826},{"type":32,"tag":81,"props":1978,"children":1979},{"style":130},[1980],{"type":37,"value":299},{"type":32,"tag":81,"props":1982,"children":1983},{"class":83,"line":506},[1984],{"type":32,"tag":81,"props":1985,"children":1986},{"style":130},[1987],{"type":37,"value":1838},{"type":32,"tag":81,"props":1989,"children":1990},{"class":83,"line":518},[1991,1995,1999],{"type":32,"tag":81,"props":1992,"children":1993},{"style":130},[1994],{"type":37,"value":261},{"type":32,"tag":81,"props":1996,"children":1997},{"style":161},[1998],{"type":37,"value":1850},{"type":32,"tag":81,"props":2000,"children":2001},{"style":130},[2002],{"type":37,"value":299},{"type":32,"tag":81,"props":2004,"children":2005},{"class":83,"line":546},[2006,2010,2014],{"type":32,"tag":81,"props":2007,"children":2008},{"style":130},[2009],{"type":37,"value":417},{"type":32,"tag":81,"props":2011,"children":2012},{"style":230},[2013],{"type":37,"value":233},{"type":32,"tag":81,"props":2015,"children":2016},{"style":130},[2017],{"type":37,"value":252},{"type":32,"tag":81,"props":2019,"children":2020},{"class":83,"line":586},[2021],{"type":32,"tag":81,"props":2022,"children":2023},{"style":130},[2024],{"type":37,"value":434},{"type":32,"tag":81,"props":2026,"children":2027},{"class":83,"line":610},[2028],{"type":32,"tag":81,"props":2029,"children":2030},{"style":130},[2031],{"type":37,"value":443},{"type":32,"tag":81,"props":2033,"children":2034},{"class":83,"line":634},[2035],{"type":32,"tag":81,"props":2036,"children":2037},{"emptyLinePlaceholder":450},[2038],{"type":37,"value":453},{"type":32,"tag":81,"props":2040,"children":2041},{"class":83,"line":661},[2042],{"type":32,"tag":81,"props":2043,"children":2044},{"style":88},[2045],{"type":37,"value":2046},"\u002F\u002F NewsletterPopup.tsx\n",{"type":32,"tag":81,"props":2048,"children":2049},{"class":83,"line":677},[2050],{"type":32,"tag":81,"props":2051,"children":2052},{"style":98},[2053],{"type":37,"value":101},{"type":32,"tag":81,"props":2055,"children":2056},{"class":83,"line":685},[2057,2061,2065,2069,2074],{"type":32,"tag":81,"props":2058,"children":2059},{"style":108},[2060],{"type":37,"value":111},{"type":32,"tag":81,"props":2062,"children":2063},{"style":108},[2064],{"type":37,"value":116},{"type":32,"tag":81,"props":2066,"children":2067},{"style":108},[2068],{"type":37,"value":121},{"type":32,"tag":81,"props":2070,"children":2071},{"style":124},[2072],{"type":37,"value":2073}," NewsletterPopup",{"type":32,"tag":81,"props":2075,"children":2076},{"style":130},[2077],{"type":37,"value":1357},{"type":32,"tag":81,"props":2079,"children":2080},{"class":83,"line":693},[2081],{"type":32,"tag":81,"props":2082,"children":2083},{"style":88},[2084],{"type":37,"value":2085},"  \u002F\u002F Klaviyo script here\n",{"type":32,"tag":81,"props":2087,"children":2088},{"class":83,"line":701},[2089],{"type":32,"tag":81,"props":2090,"children":2091},{"style":130},[2092],{"type":37,"value":443},{"type":32,"tag":33,"props":2094,"children":2095},{},[2096,2098,2104,2106,2111],{"type":37,"value":2097},"In the second example, ",{"type":32,"tag":57,"props":2099,"children":2101},{"className":2100},[],[2102],{"type":37,"value":2103},"Layout",{"type":37,"value":2105}," stays server-rendered; only ",{"type":32,"tag":57,"props":2107,"children":2109},{"className":2108},[],[2110],{"type":37,"value":1850},{"type":37,"value":2112}," hydrates. Bundle size difference: 280KB → 45KB.",{"type":32,"tag":40,"props":2114,"children":2116},{"id":2115},"edge-rendering-and-geolocation-based-personalization",[2117],{"type":37,"value":2118},"Edge rendering and geolocation-based personalization",{"type":32,"tag":33,"props":2120,"children":2121},{},[2122],{"type":37,"value":2123},"By 2026, Cloudflare Workers, Vercel Edge Functions, and Netlify Edge are mainstream. They run on V8 isolates with cold starts under 5ms. Rendering Server Components on the edge is both fast and cheap. But there are limits: database queries and external API calls slow it down.",{"type":32,"tag":33,"props":2125,"children":2126},{},[2127],{"type":37,"value":2128},"Example: show prices based on the user's country. If price data comes from a database, the edge-to-origin round-trip adds 80-120ms. Two strategies here:",{"type":32,"tag":1658,"props":2130,"children":2131},{},[2132,2142],{"type":32,"tag":1662,"props":2133,"children":2134},{},[2135,2140],{"type":32,"tag":1666,"props":2136,"children":2137},{},[2138],{"type":37,"value":2139},"Keep prices in edge KV store",{"type":37,"value":2141},"—ideal for read-heavy data, write infrequent (price updates 1-2 times daily)",{"type":32,"tag":1662,"props":2143,"children":2144},{},[2145,2150],{"type":32,"tag":1666,"props":2146,"children":2147},{},[2148],{"type":37,"value":2149},"Fetch price component client-side",{"type":37,"value":2151},"—initial HTML shows generic price, JavaScript loads, real price arrives later",{"type":32,"tag":33,"props":2153,"children":2154},{},[2155],{"type":37,"value":2156},"The second approach is simpler but risks CLS (Cumulative Layout Shift). Reserve 120px for the price block, show a skeleton loader, replace when fetch completes.",{"type":32,"tag":71,"props":2158,"children":2160},{"className":918,"code":2159,"language":920,"meta":16,"style":16},"\u002F\u002F Cloudflare Workers + Nuxt 3.12\nexport default defineEventHandler(async (event) => {\n  const country = event.node.req.headers['cf-ipcountry']\n  const prices = await env.PRICES_KV.get(country, { type: 'json' })\n  return { prices }\n})\n",[2161],{"type":32,"tag":57,"props":2162,"children":2163},{"__ignoreMap":16},[2164,2172,2221,2251,2305,2317],{"type":32,"tag":81,"props":2165,"children":2166},{"class":83,"line":84},[2167],{"type":32,"tag":81,"props":2168,"children":2169},{"style":88},[2170],{"type":37,"value":2171},"\u002F\u002F Cloudflare Workers + Nuxt 3.12\n",{"type":32,"tag":81,"props":2173,"children":2174},{"class":83,"line":94},[2175,2179,2183,2188,2192,2197,2202,2207,2212,2216],{"type":32,"tag":81,"props":2176,"children":2177},{"style":108},[2178],{"type":37,"value":111},{"type":32,"tag":81,"props":2180,"children":2181},{"style":108},[2182],{"type":37,"value":116},{"type":32,"tag":81,"props":2184,"children":2185},{"style":124},[2186],{"type":37,"value":2187}," defineEventHandler",{"type":32,"tag":81,"props":2189,"children":2190},{"style":130},[2191],{"type":37,"value":194},{"type":32,"tag":81,"props":2193,"children":2194},{"style":108},[2195],{"type":37,"value":2196},"async",{"type":32,"tag":81,"props":2198,"children":2199},{"style":130},[2200],{"type":37,"value":2201}," (",{"type":32,"tag":81,"props":2203,"children":2204},{"style":136},[2205],{"type":37,"value":2206},"event",{"type":32,"tag":81,"props":2208,"children":2209},{"style":130},[2210],{"type":37,"value":2211},") ",{"type":32,"tag":81,"props":2213,"children":2214},{"style":108},[2215],{"type":37,"value":381},{"type":32,"tag":81,"props":2217,"children":2218},{"style":130},[2219],{"type":37,"value":2220}," {\n",{"type":32,"tag":81,"props":2222,"children":2223},{"class":83,"line":104},[2224,2228,2233,2237,2242,2247],{"type":32,"tag":81,"props":2225,"children":2226},{"style":108},[2227],{"type":37,"value":153},{"type":32,"tag":81,"props":2229,"children":2230},{"style":161},[2231],{"type":37,"value":2232}," country",{"type":32,"tag":81,"props":2234,"children":2235},{"style":108},[2236],{"type":37,"value":1314},{"type":32,"tag":81,"props":2238,"children":2239},{"style":130},[2240],{"type":37,"value":2241}," event.node.req.headers[",{"type":32,"tag":81,"props":2243,"children":2244},{"style":98},[2245],{"type":37,"value":2246},"'cf-ipcountry'",{"type":32,"tag":81,"props":2248,"children":2249},{"style":130},[2250],{"type":37,"value":1042},{"type":32,"tag":81,"props":2252,"children":2253},{"class":83,"line":147},[2254,2258,2263,2267,2271,2276,2281,2286,2291,2296,2301],{"type":32,"tag":81,"props":2255,"children":2256},{"style":108},[2257],{"type":37,"value":153},{"type":32,"tag":81,"props":2259,"children":2260},{"style":161},[2261],{"type":37,"value":2262}," prices",{"type":32,"tag":81,"props":2264,"children":2265},{"style":108},[2266],{"type":37,"value":1314},{"type":32,"tag":81,"props":2268,"children":2269},{"style":108},[2270],{"type":37,"value":1378},{"type":32,"tag":81,"props":2272,"children":2273},{"style":130},[2274],{"type":37,"value":2275}," env.",{"type":32,"tag":81,"props":2277,"children":2278},{"style":161},[2279],{"type":37,"value":2280},"PRICES_KV",{"type":32,"tag":81,"props":2282,"children":2283},{"style":130},[2284],{"type":37,"value":2285},".",{"type":32,"tag":81,"props":2287,"children":2288},{"style":124},[2289],{"type":37,"value":2290},"get",{"type":32,"tag":81,"props":2292,"children":2293},{"style":130},[2294],{"type":37,"value":2295},"(country, { type: ",{"type":32,"tag":81,"props":2297,"children":2298},{"style":98},[2299],{"type":37,"value":2300},"'json'",{"type":32,"tag":81,"props":2302,"children":2303},{"style":130},[2304],{"type":37,"value":1633},{"type":32,"tag":81,"props":2306,"children":2307},{"class":83,"line":207},[2308,2312],{"type":32,"tag":81,"props":2309,"children":2310},{"style":108},[2311],{"type":37,"value":213},{"type":32,"tag":81,"props":2313,"children":2314},{"style":130},[2315],{"type":37,"value":2316}," { prices }\n",{"type":32,"tag":81,"props":2318,"children":2319},{"class":83,"line":221},[2320],{"type":32,"tag":81,"props":2321,"children":2322},{"style":130},[2323],{"type":37,"value":1066},{"type":32,"tag":33,"props":2325,"children":2326},{},[2327],{"type":37,"value":2328},"Cloudflare KV read latency averages 30ms. Prices return without hitting origin database. With this approach, product pages stay fully server-rendered, no hydration, TBT at 0ms.",{"type":32,"tag":40,"props":2330,"children":2332},{"id":2331},"tradeoff-matrix-when-to-use-which-pattern",[2333],{"type":37,"value":2334},"Tradeoff matrix: when to use which pattern",{"type":32,"tag":1124,"props":2336,"children":2337},{},[2338,2368],{"type":32,"tag":1128,"props":2339,"children":2340},{},[2341],{"type":32,"tag":1132,"props":2342,"children":2343},{},[2344,2349,2354,2359,2363],{"type":32,"tag":1136,"props":2345,"children":2346},{},[2347],{"type":37,"value":2348},"Scenario",{"type":32,"tag":1136,"props":2350,"children":2351},{},[2352],{"type":37,"value":2353},"Recommended Pattern",{"type":32,"tag":1136,"props":2355,"children":2356},{},[2357],{"type":37,"value":2358},"Bundle",{"type":32,"tag":1136,"props":2360,"children":2361},{},[2362],{"type":37,"value":1214},{"type":32,"tag":1136,"props":2364,"children":2365},{},[2366],{"type":37,"value":2367},"Tradeoff",{"type":32,"tag":1157,"props":2369,"children":2370},{},[2371,2397,2423,2449,2477],{"type":32,"tag":1132,"props":2372,"children":2373},{},[2374,2379,2384,2388,2392],{"type":32,"tag":1164,"props":2375,"children":2376},{},[2377],{"type":37,"value":2378},"Static blog, docs",{"type":32,"tag":1164,"props":2380,"children":2381},{},[2382],{"type":37,"value":2383},"Server-only",{"type":32,"tag":1164,"props":2385,"children":2386},{},[2387],{"type":37,"value":1251},{"type":32,"tag":1164,"props":2389,"children":2390},{},[2391],{"type":37,"value":1228},{"type":32,"tag":1164,"props":2393,"children":2394},{},[2395],{"type":37,"value":2396},"No interactive elements",{"type":32,"tag":1132,"props":2398,"children":2399},{},[2400,2405,2410,2414,2418],{"type":32,"tag":1164,"props":2401,"children":2402},{},[2403],{"type":37,"value":2404},"E-commerce product list",{"type":32,"tag":1164,"props":2406,"children":2407},{},[2408],{"type":37,"value":2409},"Selective hydration",{"type":32,"tag":1164,"props":2411,"children":2412},{},[2413],{"type":37,"value":1246},{"type":32,"tag":1164,"props":2415,"children":2416},{},[2417],{"type":37,"value":1223},{"type":32,"tag":1164,"props":2419,"children":2420},{},[2421],{"type":37,"value":2422},"Only buttons hydrate",{"type":32,"tag":1132,"props":2424,"children":2425},{},[2426,2431,2436,2440,2444],{"type":32,"tag":1164,"props":2427,"children":2428},{},[2429],{"type":37,"value":2430},"Dashboard, admin panel",{"type":32,"tag":1164,"props":2432,"children":2433},{},[2434],{"type":37,"value":2435},"Full client render",{"type":32,"tag":1164,"props":2437,"children":2438},{},[2439],{"type":37,"value":1241},{"type":32,"tag":1164,"props":2441,"children":2442},{},[2443],{"type":37,"value":1183},{"type":32,"tag":1164,"props":2445,"children":2446},{},[2447],{"type":37,"value":2448},"All data dynamic, no caching",{"type":32,"tag":1132,"props":2450,"children":2451},{},[2452,2457,2462,2467,2472],{"type":32,"tag":1164,"props":2453,"children":2454},{},[2455],{"type":37,"value":2456},"Landing page + form",{"type":32,"tag":1164,"props":2458,"children":2459},{},[2460],{"type":37,"value":2461},"Server + client form",{"type":32,"tag":1164,"props":2463,"children":2464},{},[2465],{"type":37,"value":2466},"60KB",{"type":32,"tag":1164,"props":2468,"children":2469},{},[2470],{"type":37,"value":2471},"80ms",{"type":32,"tag":1164,"props":2473,"children":2474},{},[2475],{"type":37,"value":2476},"Form validation client-side",{"type":32,"tag":1132,"props":2478,"children":2479},{},[2480,2485,2490,2495,2500],{"type":32,"tag":1164,"props":2481,"children":2482},{},[2483],{"type":37,"value":2484},"Geolocation-based pricing",{"type":32,"tag":1164,"props":2486,"children":2487},{},[2488],{"type":37,"value":2489},"Edge SSR + KV",{"type":32,"tag":1164,"props":2491,"children":2492},{},[2493],{"type":37,"value":2494},"30KB",{"type":32,"tag":1164,"props":2496,"children":2497},{},[2498],{"type":37,"value":2499},"20ms",{"type":32,"tag":1164,"props":2501,"children":2502},{},[2503],{"type":37,"value":2504},"KV write limitations",{"type":32,"tag":33,"props":2506,"children":2507},{},[2508],{"type":37,"value":2509},"At Roibase, we typically use \"Selective hydration.\" E-commerce sites usually have both static content (product descriptions, images) and interactive elements (cart, filters). Full server render doesn't work for e-commerce, and full client render damages Core Web Vitals.",{"type":32,"tag":40,"props":2511,"children":2513},{"id":2512},"what-to-do-in-your-project-now",[2514],{"type":37,"value":2515},"What to do in your project now",{"type":32,"tag":33,"props":2517,"children":2518},{},[2519],{"type":37,"value":2520},"If your current project runs on Next.js Pages Router or Nuxt 2, there's no urgent need to rewrite. But when adding new features, use App Router (Next 15+) or Nuxt 3.12+. A hybrid approach works: migrate critical pages (checkout, product detail) to the new architecture, leave blogs and static pages on the old stack.",{"type":32,"tag":33,"props":2522,"children":2523},{},[2524],{"type":37,"value":2525},"Starting a new project:",{"type":32,"tag":1658,"props":2527,"children":2528},{},[2529,2534,2539,2544,2549],{"type":32,"tag":1662,"props":2530,"children":2531},{},[2532],{"type":37,"value":2533},"Create a component inventory—what's interactive, what's static",{"type":32,"tag":1662,"props":2535,"children":2536},{},[2537],{"type":37,"value":2538},"Mark interactive ones as client components",{"type":32,"tag":1662,"props":2540,"children":2541},{},[2542],{"type":37,"value":2543},"Everything else becomes server components",{"type":32,"tag":1662,"props":2545,"children":2546},{},[2547],{"type":37,"value":2548},"Measure TBT with Chrome DevTools Profiler, aim for \u003C200ms",{"type":32,"tag":1662,"props":2550,"children":2551},{},[2552],{"type":37,"value":2553},"If TBT is still high, shrink state in client components",{"type":32,"tag":33,"props":2555,"children":2556},{},[2557],{"type":37,"value":2558},"In headless commerce, these decisions matter even more. Your SSR server typically fetches data from a SaaS backend like Shopify. Too much client-side fetching hits rate limits. Too much server-side rendering inflates TTFB (Time to First Byte). The balance: critical data (stock, price) in server components, user-specific data (cart, wishlist) in client components.",{"type":32,"tag":2560,"props":2561,"children":2562},"style",{},[2563],{"type":37,"value":2564},"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":104,"depth":104,"links":2566},[2567,2570,2573,2574,2575,2576],{"id":42,"depth":94,"text":45,"children":2568},[2569],{"id":870,"depth":104,"text":873},{"id":1114,"depth":94,"text":1117,"children":2571},[2572],{"id":1264,"depth":104,"text":1267},{"id":1648,"depth":94,"text":1651},{"id":2115,"depth":94,"text":2118},{"id":2331,"depth":94,"text":2334},{"id":2512,"depth":94,"text":2515},"markdown","content:en:tech:server-components-vs-client-2026-drawing-the-right-line.md","content","en\u002Ftech\u002Fserver-components-vs-client-2026-drawing-the-right-line.md","en\u002Ftech\u002Fserver-components-vs-client-2026-drawing-the-right-line","md",1780898611415]