[{"data":1,"prerenderedAt":1387},["ShallowReactive",2],{"page:\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro":3,"all-docs-nav":843},{"id":4,"title":5,"body":6,"breadcrumb":818,"dateModified":828,"datePublished":828,"description":829,"extension":830,"faq":831,"meta":836,"navigation":286,"path":837,"seo":838,"slug":839,"stem":840,"type":841,"__hash__":842},"content\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro\u002Findex.md","Deferring Hydration with client:visible in Astro",{"type":7,"value":8,"toc":799},"minimark",[9,13,22,43,48,61,65,68,192,240,244,247,329,336,340,343,425,429,432,472,478,574,578,589,614,617,621,630,637,641,647,651,699,703,721,725,730,733,737,740,744,747,751,754,758,795],[10,11,5],"h1",{"id":12},"deferring-hydration-with-clientvisible-in-astro",[14,15,16,17,21],"p",{},"Astro islands already ship far less JavaScript than a fully hydrated single-page app, but every island with ",[18,19,20],"code",{},"client:load"," still downloads, parses and hydrates as soon as the page loads. On a long article with a comment widget at the bottom, an interactive chart halfway down and a newsletter form in the footer, all three compete with the reader's first scroll and taps for the main thread — even though most readers never reach two of them.",[14,23,24,25,28,29,32,33,36,37,42],{},"Astro's other client directives fix this by delaying hydration until a condition is met. ",[18,26,27],{},"client:visible"," waits until the island scrolls into view, ",[18,30,31],{},"client:idle"," waits until the browser is idle, and ",[18,34,35],{},"client:media"," waits for a media query. This guide explains when to use each, measures the effect on a real template, and covers the layout details that stop deferred islands from shifting content. It is part of ",[38,39,41],"a",{"href":40},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002F","JavaScript Hydration & Partial Rendering",".",[44,45,47],"h2",{"id":46},"prerequisites","Prerequisites",[49,50,51,55,58],"ul",{},[52,53,54],"li",{},"An Astro 4 or 5 site with at least one framework island.",[52,56,57],{},"A way to see which scripts load and when: the DevTools network and performance panels are enough.",[52,59,60],{},"Field INP data, ideally with attribution, to confirm the change.",[44,62,64],{"id":63},"the-directives","The Directives",[14,66,67],{},"Each directive tells Astro when to load the island's JavaScript and hydrate it. The HTML is always rendered at build time; only the timing of the JavaScript changes.",[69,70,71,188],"figure",{},[72,73,80,81,80,85,80,89,80,96],"svg",{"viewBox":74,"role":75,"ariaLabelledBy":76,"xmlns":79},"0 0 760 280","img",[77,78],"dcv-dir-title","dcv-dir-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[82,83,84],"title",{"id":77},"When each Astro client directive hydrates an island",[86,87,88],"desc",{"id":78},"A timeline from page load. client:load hydrates immediately after the page loads. client:idle hydrates when the main thread is idle, usually within a second. client:visible hydrates when the island enters the viewport, which may be never. client:media hydrates when a media query matches. client:only skips server rendering entirely.",[90,91],"rect",{"x":92,"y":92,"width":93,"height":94,"fill":95},"0","760","280","#ffffff",[97,98,100,101,100,109,100,117,100,122,100,126,100,131,100,138,100,142,100,145,100,150,100,154,100,157,100,162,100,166,100,169,100,173,100,177,100,181,100,185,80],"g",{"style":99},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[102,103,108],"text",{"x":104,"y":105,"fill":106,"style":107},"380","26","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","Hydration timing by directive",[110,111],"line",{"x1":112,"y1":113,"x2":114,"y2":113,"stroke":115,"style":116},"180","240","720","#556071","stroke-width:1.5px",[102,118,121],{"x":112,"y":119,"fill":115,"style":120},"258","font-size:11px","page load",[102,123,125],{"x":114,"y":119,"fill":115,"style":124},"font-size:11px;text-anchor:end","reader scrolls on",[102,127,20],{"x":128,"y":129,"fill":106,"style":130},"170","64","font-weight:700;text-anchor:end",[132,133],"circle",{"cx":134,"cy":135,"r":136,"fill":137},"200","60","7","#d83b41",[102,139,141],{"x":140,"y":129,"fill":106},"214","immediately, competes with first input",[102,143,31],{"x":128,"y":144,"fill":106,"style":130},"102",[132,146],{"cx":147,"cy":148,"r":136,"fill":149},"300","98","#8a6d0f",[102,151,153],{"x":152,"y":144,"fill":106},"314","when the main thread is idle",[102,155,27],{"x":128,"y":156,"fill":106,"style":130},"140",[132,158],{"cx":159,"cy":160,"r":136,"fill":161},"520","136","#3f6410",[102,163,165],{"x":164,"y":156,"fill":106},"534","on entering the viewport, or never",[102,167,35],{"x":128,"y":168,"fill":106,"style":130},"178",[132,170],{"cx":113,"cy":171,"r":136,"fill":172},"174","#166a9e",[102,174,176],{"x":175,"y":168,"fill":106},"254","only if the media query matches",[102,178,180],{"x":128,"y":179,"fill":106,"style":130},"216","client:only",[132,182],{"cx":134,"cy":183,"r":136,"fill":184},"212","#6a4c93",[102,186,187],{"x":140,"y":179,"fill":106},"no server HTML; renders on the client at load",[189,190,191],"figcaption",{},"Only client:visible and client:media can avoid loading an island's code altogether.",[49,193,194,202,217,224,232],{},[52,195,196,201],{},[197,198,199],"strong",{},[18,200,20],{}," — hydrate immediately. Use for islands in the first viewport that must respond at once.",[52,203,204,208,209,212,213,216],{},[197,205,206],{},[18,207,31],{}," — hydrate after the page's initial work, using ",[18,210,211],{},"requestIdleCallback",". Use for islands that are visible early but not urgent, such as a \"copy link\" button in an article header. Astro 4.15 added a ",[18,214,215],{},"timeout"," option to cap the wait.",[52,218,219,223],{},[197,220,221],{},[18,222,27],{}," — hydrate when the element intersects the viewport. Use for everything below the fold.",[52,225,226,231],{},[197,227,228],{},[18,229,230],{},"client:media=\"(max-width: 768px)\""," — hydrate only when the query matches. Use for a mobile menu toggle that is hidden on desktop.",[52,233,234,239],{},[197,235,236],{},[18,237,238],{},"client:only=\"react\""," — skip server rendering. Avoid on content sites; it guarantees an empty box until the JavaScript runs.",[44,241,243],{"id":242},"applying-it-to-an-article-template","Applying It to an Article Template",[14,245,246],{},"A typical article template has four islands. Here is how their directives should look:",[248,249,254],"pre",{"className":250,"code":251,"language":252,"meta":253,"style":253},"language-astro shiki shiki-themes github-light github-dark","\u003CHeader>\n  \u003CSearchButton client:idle \u002F>          \u003C!-- visible, not urgent -->\n  \u003CMobileNav client:media=\"(max-width: 768px)\" \u002F>\n\u003C\u002FHeader>\n\n\u003Carticle>\n  \u003CContent \u002F>\n  \u003CInteractiveChart client:visible={{ rootMargin: '300px' }} data={chartData} \u002F>\n\u003C\u002Farticle>\n\n\u003CComments client:visible \u002F>\n\u003CNewsletterForm client:visible \u002F>\n","astro","",[18,255,256,263,269,275,281,288,294,300,306,312,317,323],{"__ignoreMap":253},[257,258,260],"span",{"class":110,"line":259},1,[257,261,262],{},"\u003CHeader>\n",[257,264,266],{"class":110,"line":265},2,[257,267,268],{},"  \u003CSearchButton client:idle \u002F>          \u003C!-- visible, not urgent -->\n",[257,270,272],{"class":110,"line":271},3,[257,273,274],{},"  \u003CMobileNav client:media=\"(max-width: 768px)\" \u002F>\n",[257,276,278],{"class":110,"line":277},4,[257,279,280],{},"\u003C\u002FHeader>\n",[257,282,284],{"class":110,"line":283},5,[257,285,287],{"emptyLinePlaceholder":286},true,"\n",[257,289,291],{"class":110,"line":290},6,[257,292,293],{},"\u003Carticle>\n",[257,295,297],{"class":110,"line":296},7,[257,298,299],{},"  \u003CContent \u002F>\n",[257,301,303],{"class":110,"line":302},8,[257,304,305],{},"  \u003CInteractiveChart client:visible={{ rootMargin: '300px' }} data={chartData} \u002F>\n",[257,307,309],{"class":110,"line":308},9,[257,310,311],{},"\u003C\u002Farticle>\n",[257,313,315],{"class":110,"line":314},10,[257,316,287],{"emptyLinePlaceholder":286},[257,318,320],{"class":110,"line":319},11,[257,321,322],{},"\u003CComments client:visible \u002F>\n",[257,324,326],{"class":110,"line":325},12,[257,327,328],{},"\u003CNewsletterForm client:visible \u002F>\n",[14,330,331,332,335],{},"The ",[18,333,334],{},"rootMargin"," option, available from Astro 4.15, starts hydration 300 pixels before the chart reaches the viewport, so it is interactive by the time the reader gets there. Without it, a reader who scrolls quickly and immediately taps the chart may tap before hydration finishes.",[44,337,339],{"id":338},"what-it-changes","What It Changes",[14,341,342],{},"Every deferred island is JavaScript that is not downloaded, parsed or executed during the first seconds, when the reader is most likely to scroll, open the menu or tap a link. That time is when INP is most at risk, because long tasks from hydration block the handler for the reader's first interaction.",[69,344,345,422],{},[72,346,80,351,80,354,80,357,80,360],{"viewBox":347,"role":75,"ariaLabelledBy":348,"xmlns":79},"0 0 760 260",[349,350],"dcv-js-title","dcv-js-desc",[82,352,353],{"id":349},"JavaScript executed in the first five seconds by directive choice",[86,355,356],{"id":350},"On the article template, all islands with client:load execute 142 kilobytes of JavaScript in the first five seconds with 280 milliseconds of long tasks. With the directives from this guide, 38 kilobytes execute with 60 milliseconds of long tasks; the chart, comments and newsletter code load only for readers who scroll to them.",[90,358],{"x":92,"y":92,"width":93,"height":359,"fill":95},"260",[97,361,100,362,100,366,100,369,100,376,100,382,100,388,100,392,100,396,100,399,100,404,100,408,100,413,100,417,80],{"style":99},[102,363,365],{"x":104,"y":364,"fill":106,"style":107},"28","First 5 seconds on the article template, mid-range phone",[110,367],{"x1":135,"y1":134,"x2":368,"y2":134,"stroke":115,"style":116},"700",[90,370],{"x":371,"y":372,"width":373,"height":374,"fill":137,"style":375},"120","58","80","142","fill-opacity:0.45",[102,377,381],{"x":378,"y":379,"fill":106,"style":380},"160","52","text-anchor:middle","142 KB",[90,383],{"x":384,"y":385,"width":373,"height":386,"fill":161,"style":387},"220","162","38","fill-opacity:0.55",[102,389,391],{"x":359,"y":390,"fill":106,"style":380},"156","38 KB",[102,393,395],{"x":394,"y":384,"fill":115,"style":380},"210","JavaScript executed",[90,397],{"x":398,"y":135,"width":373,"height":156,"fill":137,"style":375},"460",[102,400,403],{"x":401,"y":402,"fill":106,"style":380},"500","54","280 ms",[90,405],{"x":406,"y":128,"width":373,"height":407,"fill":161,"style":387},"560","30",[102,409,412],{"x":410,"y":411,"fill":106,"style":380},"600","164","60 ms",[102,414,416],{"x":415,"y":384,"fill":115,"style":380},"550","long-task time",[102,418,421],{"x":104,"y":419,"fill":115,"style":420},"248","font-size:11px;text-anchor:middle","red: every island client:load; green: idle, media and visible as in the template above",[189,423,424],{},"Readers who never scroll to the comments never download the comments code.",[44,426,428],{"id":427},"avoiding-layout-shift","Avoiding Layout Shift",[14,430,431],{},"A deferred island is static HTML until it hydrates, so the static HTML must look like the finished component or at least occupy the same space. Three rules cover most cases:",[433,434,435,448,458],"ol",{},[52,436,437,440,441,444,445,447],{},[197,438,439],{},"Render real markup on the server."," A comment widget should render the comment count and a disabled form, not an empty ",[18,442,443],{},"\u003Cdiv>",". React, Preact, Svelte and Vue components all render server-side in Astro by default; avoid ",[18,446,180],{}," for anything in the content flow.",[52,449,450,453,454,457],{},[197,451,452],{},"Give dynamic areas fixed dimensions."," A chart that measures its container on hydrate should sit in a container with an explicit ",[18,455,456],{},"aspect-ratio",", so the empty state and the drawn chart take the same space.",[52,459,460,463,464,467,468,471],{},[197,461,462],{},"Do not change size on hydrate."," Components that read ",[18,465,466],{},"window"," or ",[18,469,470],{},"localStorage"," in their first render and output something different than the server did will both shift and log hydration mismatch warnings. Read browser state in an effect after mount.",[14,473,474,475,477],{},"With those rules, a reader scrolling into a ",[18,476,27],{}," island sees the static version for a few hundred milliseconds at most, and nothing moves when it becomes interactive.",[69,479,480,571],{},[72,481,80,486,80,489,80,492,80,495],{"viewBox":482,"role":75,"ariaLabelledBy":483,"xmlns":79},"0 0 760 250",[484,485],"dcv-ph-title","dcv-ph-desc",[82,487,488],{"id":484},"Server markup that reserves space versus an empty placeholder",[86,490,491],{"id":485},"Left: an island rendered with client:only shows an empty zero-height box, then grows to 320 pixels when hydrated, pushing the footer down. Right: an island rendered on the server with a fixed aspect ratio occupies 320 pixels from the start, and hydration changes nothing about its size.",[90,493],{"x":92,"y":92,"width":93,"height":494,"fill":95},"250",[97,496,100,497,100,500,100,506,100,511,100,515,100,519,100,522,100,526,100,530,100,532,100,536,100,540,100,543,100,547,100,551,100,553,100,555,100,557,100,561,100,565,100,567,100,569,80],{"style":99},[102,498,499],{"x":104,"y":105,"fill":106,"style":107},"Before and after hydration",[102,501,505],{"x":134,"y":502,"fill":503,"style":504},"56","#b32b30","font-weight:700;text-anchor:middle","client:only, no size reserved",[90,507],{"x":135,"y":508,"width":371,"height":509,"fill":137,"style":510},"70","8","fill-opacity:0.4",[90,512],{"x":135,"y":513,"width":371,"height":407,"fill":115,"style":514},"86","fill-opacity:0.2",[102,516,518],{"x":371,"y":517,"fill":106,"style":380},"105","footer",[102,520,521],{"x":371,"y":160,"fill":115,"style":420},"before",[90,523],{"x":384,"y":508,"width":371,"height":524,"fill":137,"style":525},"100","fill-opacity:0.25",[102,527,529],{"x":94,"y":528,"fill":106,"style":380},"124","chart",[90,531],{"x":384,"y":168,"width":371,"height":407,"fill":115,"style":514},[102,533,535],{"x":94,"y":534,"fill":106,"style":380},"197","footer moved",[102,537,539],{"x":94,"y":538,"fill":115,"style":420},"226","after",[102,541,542],{"x":406,"y":502,"fill":161,"style":504},"server HTML + aspect-ratio",[90,544],{"x":545,"y":508,"width":371,"height":524,"fill":161,"style":546},"420","fill-opacity:0.15",[102,548,550],{"x":549,"y":528,"fill":106,"style":380},"480","static chart",[90,552],{"x":545,"y":168,"width":371,"height":407,"fill":115,"style":514},[102,554,518],{"x":549,"y":534,"fill":106,"style":380},[102,556,521],{"x":549,"y":538,"fill":115,"style":420},[90,558],{"x":559,"y":508,"width":371,"height":524,"fill":161,"style":560},"580","fill-opacity:0.3",[102,562,564],{"x":563,"y":528,"fill":106,"style":380},"640","live chart",[90,566],{"x":559,"y":168,"width":371,"height":407,"fill":115,"style":514},[102,568,518],{"x":563,"y":534,"fill":106,"style":380},[102,570,539],{"x":563,"y":538,"fill":115,"style":420},[189,572,573],{},"Deferred hydration is only free if the static HTML already takes the final space.",[44,575,577],{"id":576},"custom-directives-for-other-triggers","Custom Directives for Other Triggers",[14,579,580,581,584,585,588],{},"The built-in directives cover most cases, but some islands only need to hydrate when the reader shows intent: a video player when the reader hovers or focuses the play button, or a code playground when they click \"Run\". Astro lets integrations register custom client directives with ",[18,582,583],{},"addClientDirective",", and a directive is just a function that receives a ",[18,586,587],{},"load"," callback and decides when to call it.",[14,590,591,592,595,596,599,600,467,603,606,607,610,611,613],{},"A ",[18,593,594],{},"client:interaction"," directive, for example, can listen for ",[18,597,598],{},"pointerenter",", ",[18,601,602],{},"focusin",[18,604,605],{},"touchstart"," on the island's root element, call ",[18,608,609],{},"load()"," on the first of them, and then replay the click once hydration completes. Community packages provide ready-made versions of this pattern. It suits islands that are visible but rarely used, where even ",[18,612,27],{}," downloads code that most readers never need.",[14,615,616],{},"Be careful with interaction-triggered hydration on primary controls. The first tap now waits for a download and hydration before anything happens, which is exactly the delay INP measures. Keep it for secondary features where a short wait on first use is acceptable, and preload the chunk on hover so the wait is usually hidden.",[44,618,620],{"id":619},"checking-the-result","Checking the Result",[14,622,623,624,626,627,629],{},"Open the page with DevTools' network panel filtered to JavaScript and reload without scrolling. Only the scripts for ",[18,625,20],{}," and matching ",[18,628,35],{}," islands, plus Astro's small island runtime, should appear. Scroll down slowly and watch the chart, comments and newsletter chunks load as each island approaches the viewport. In the performance panel, record a load and confirm there are no long tasks from island hydration in the first seconds.",[14,631,632,633,42],{},"In the field, compare INP before and after with the attribution build of web-vitals, and check which scripts appear in the long animation frames attributed to slow interactions; see ",[38,634,636],{"href":635},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fmeasuring-inp-on-static-sites-with-real-user-monitoring\u002F","Measuring INP on Static Sites with Real User Monitoring",[44,638,640],{"id":639},"measured-impact","Measured Impact",[14,642,643,644,646],{},"On a 900-page engineering blog built with Astro, every island used ",[18,645,20],{}," because that was what the component examples showed. Changing the directives on the article layout — six lines — reduced JavaScript executed in the first five seconds from 142 KB to 38 KB and mobile INP p75 from 210 to 130 milliseconds. Only 22% of article views scrolled far enough to hydrate the comments island, so most readers never downloaded it at all. CLS was unchanged at 0.02 because the islands already rendered sized server markup.",[44,648,650],{"id":649},"pitfalls-rollback","Pitfalls & Rollback",[49,652,653,665,671,681,690],{},[52,654,655,660,661,467,663,42],{},[197,656,657,659],{},[18,658,27],{}," on a first-viewport island."," It hydrates almost at once anyway, but after an IntersectionObserver round-trip; use ",[18,662,20],{},[18,664,31],{},[52,666,667,670],{},[197,668,669],{},"Islands that need each other."," If a deferred island listens for events from another, the listener may not exist yet; queue events or share state through a store that survives until both hydrate.",[52,672,673,676,677,680],{},[197,674,675],{},"Anchor links deep into a page."," A reader landing at ",[18,678,679],{},"#comments"," hydrates that island immediately, which is correct but worth testing.",[52,682,683,689],{},[197,684,685,686,688],{},"Using ",[18,687,180],{}," to avoid SSR errors."," Fix the component's browser-only code instead, so it can render on the server.",[52,691,692,695,696,698],{},[197,693,694],{},"Rollback:"," change the directives back to ",[18,697,20],{},"; nothing else in the component changes.",[44,700,702],{"id":701},"conclusion","Conclusion",[14,704,705,706,708,709,711,712,714,715,717,718,720],{},"Astro renders every island to HTML, so the only question is when its JavaScript should run. Use ",[18,707,20],{}," for islands the reader needs at once, ",[18,710,31],{}," for early but non-urgent ones, ",[18,713,35],{}," for breakpoint-specific controls, and ",[18,716,27],{}," — with a ",[18,719,334],{}," — for everything below the fold. Make sure the server HTML already takes the final space, and deferred hydration cuts startup JavaScript and improves INP without the reader noticing any difference.",[44,722,724],{"id":723},"faq","FAQ",[726,727,729],"h3",{"id":728},"what-does-clientvisible-do-in-astro","What does client:visible do in Astro?",[14,731,732],{},"It renders the component to HTML at build time and waits to download and hydrate its JavaScript until the component's element enters the viewport, using an IntersectionObserver. Until then the island is static HTML and costs no JavaScript.",[726,734,736],{"id":735},"when-should-i-use-clientload-instead-of-clientvisible","When should I use client:load instead of client:visible?",[14,738,739],{},"Use client:load for islands that are visible in the first viewport and must respond immediately, such as a header search button. For anything that starts below the fold, client:visible avoids downloading code the reader may never need.",[726,741,743],{"id":742},"can-clientvisible-start-loading-before-the-island-is-on-screen","Can client:visible start loading before the island is on screen?",[14,745,746],{},"Yes. Since Astro 4.15 you can pass a rootMargin, for example client:visible with rootMargin 200px, so hydration starts slightly before the island scrolls into view and is ready by the time the reader reaches it.",[726,748,750],{"id":749},"does-deferring-hydration-cause-layout-shift","Does deferring hydration cause layout shift?",[14,752,753],{},"Not if the server-rendered HTML has the same size as the hydrated component. Shifts happen when the component renders nothing on the server and fills in on the client, or when hydration changes its dimensions. Render real placeholder markup with fixed dimensions.",[44,755,757],{"id":756},"related","Related",[49,759,760,769,776,783,788],{},[52,761,762,765,766,768],{},[197,763,764],{},"Parent:"," ",[38,767,41],{"href":40}," — the full hydration strategy.",[52,770,771,775],{},[38,772,774],{"href":773},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance\u002F","Astro Islands vs Full Hydration Performance"," — the baseline this builds on.",[52,777,778,782],{},[38,779,781],{"href":780},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components\u002F","Replacing React Islands with Web Components"," — removing islands entirely.",[52,784,785,787],{},[38,786,636],{"href":635}," — confirming the change.",[52,789,790,794],{},[38,791,793],{"href":792},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro\u002F","Prefetching Links in Astro"," — the other Astro startup setting to tune.",[796,797,798],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":253,"searchDepth":265,"depth":265,"links":800},[801,802,803,804,805,806,807,808,809,810,811,817],{"id":46,"depth":265,"text":47},{"id":63,"depth":265,"text":64},{"id":242,"depth":265,"text":243},{"id":338,"depth":265,"text":339},{"id":427,"depth":265,"text":428},{"id":576,"depth":265,"text":577},{"id":619,"depth":265,"text":620},{"id":639,"depth":265,"text":640},{"id":649,"depth":265,"text":650},{"id":701,"depth":265,"text":702},{"id":723,"depth":265,"text":724,"children":812},[813,814,815,816],{"id":728,"depth":271,"text":729},{"id":735,"depth":271,"text":736},{"id":742,"depth":271,"text":743},{"id":749,"depth":271,"text":750},{"id":756,"depth":265,"text":757},[819,822,825,826],{"name":820,"item":821},"Home","\u002F",{"name":823,"item":824},"Performance Optimization & Core Web Vitals for SSGs","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002F",{"name":41,"item":40},{"name":5,"item":827},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro\u002F","2026-09-18","Use client:visible, client:idle and client:media to delay Astro island hydration until it is needed, cut startup JavaScript and protect INP on content pages.","md",[832,833,834,835],{"q":729,"a":732},{"q":736,"a":739},{"q":743,"a":746},{"q":750,"a":753},{},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro",{"title":5,"description":829},"deferring-hydration-with-client-visible-in-astro","performance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro\u002Findex","article","W2JzDcCsjbplSrsUGQKM5X4-EmiVFLaKD07n_xfBx0o",[844,847,850,853,856,859,862,865,868,871,874,877,880,883,886,889,892,895,898,901,904,907,910,913,916,919,922,925,928,931,934,937,940,943,946,949,952,955,958,961,964,967,970,973,976,979,982,985,988,991,994,997,1000,1003,1006,1009,1012,1015,1018,1021,1024,1027,1030,1033,1036,1039,1042,1045,1048,1051,1054,1057,1060,1063,1066,1069,1072,1075,1078,1081,1084,1087,1089,1090,1093,1095,1098,1100,1103,1106,1109,1112,1115,1118,1121,1124,1127,1130,1133,1136,1139,1142,1145,1148,1151,1153,1156,1159,1162,1165,1168,1171,1174,1177,1180,1183,1186,1189,1192,1195,1198,1201,1204,1207,1210,1213,1216,1219,1222,1225,1228,1231,1234,1237,1240,1243,1246,1249,1252,1255,1258,1261,1264,1267,1270,1273,1276,1279,1282,1285,1288,1291,1294,1297,1300,1303,1306,1309,1312,1315,1318,1321,1324,1327,1330,1333,1336,1339,1342,1345,1348,1351,1354,1357,1360,1363,1366,1369,1372,1375,1378,1381,1384],{"path":845,"title":846},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fastro-vs-eleventy-build-times-at-10000-pages","Astro vs Eleventy Build Times at 10,000 Pages",{"path":848,"title":849},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fchoosing-between-astro-and-eleventy-for-large-docs","Astro vs Eleventy for Large Docs (1000+ Pages)",{"path":851,"title":852},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fcontent-collections-vs-eleventy-data-cascade","Content Collections vs the Eleventy Data Cascade",{"path":854,"title":855},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":857,"title":858},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fshortcodes-vs-components-for-docs-authors","Shortcodes vs Components for Docs Authors",{"path":860,"title":861},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fsidebar-navigation-in-astro-and-eleventy","Sidebar Navigation in Astro and Eleventy",{"path":863,"title":864},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcustomizing-starlight-without-forking-the-theme","Customizing Starlight Without Forking the Theme",{"path":866,"title":867},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fdocusaurus-vs-starlight-for-product-documentation","Docusaurus vs Starlight for Product Documentation",{"path":869,"title":870},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress","Docs Frameworks: Docusaurus, Starlight and VitePress",{"path":872,"title":873},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmdx-vs-markdoc-for-docs-content","MDX vs Markdoc for Docs Content",{"path":875,"title":876},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":878,"title":879},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":881,"title":882},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":884,"title":885},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhow-to-benchmark-hugo-vs-astro-build-speeds","How to Benchmark Hugo vs Astro Build Speeds",{"path":887,"title":888},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhugo-partialcached-for-faster-builds","Hugo partialCached for Faster Builds",{"path":890,"title":891},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":893,"title":894},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fprofiling-hugo-templates-with-template-metrics","Profiling Hugo Templates With Template Metrics",{"path":896,"title":897},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Freducing-hugo-memory-usage-on-ci-runners","Reducing Hugo Memory Usage on CI Runners",{"path":899,"title":900},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fspeeding-up-hugo-builds-with-render-hooks-and-caching","Speeding Up Hugo Builds with Render Hooks & Caching",{"path":902,"title":903},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":905,"title":906},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Feleventy-vs-jekyll-for-markdown-heavy-blogs","Eleventy vs Jekyll for Markdown-Heavy Blogs",{"path":908,"title":909},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":911,"title":912},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Freplacing-jekyll-plugins-when-migrating-to-eleventy","Replacing Jekyll Plugins When Migrating to Eleventy",{"path":914,"title":915},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Frunning-jekyll-on-github-pages-without-plugins","Running Jekyll on GitHub Pages Without Plugins",{"path":917,"title":918},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":920,"title":921},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":923,"title":924},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fconverting-front-matter-at-scale-during-migration","Converting Front Matter at Scale During Migration",{"path":926,"title":927},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":929,"title":930},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration","Keeping Redirects Working After an SSG Migration",{"path":932,"title":933},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-a-docs-site-from-jekyll-to-hugo","Migrating a Docs Site From Jekyll to Hugo",{"path":935,"title":936},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":938,"title":939},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-hugo-to-astro-without-breaking-urls","Migrating From Hugo to Astro Without Breaking URLs",{"path":941,"title":942},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-wordpress-to-a-static-site-generator","Migrating WordPress to a Static Site Generator",{"path":944,"title":945},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fporting-shortcodes-and-includes-between-generators","Porting Shortcodes and Includes Between Generators",{"path":947,"title":948},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fhandling-dynamic-routes-in-nextjs-static-export","Handling Dynamic Routes in Next.js Static Export",{"path":950,"title":951},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":953,"title":954},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fmigrating-from-gatsby-to-nextjs-static-export","Migrating from Gatsby to Next.js Static Export",{"path":956,"title":957},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-app-router-static-export-limitations","Next.js App Router Static Export Limitations",{"path":959,"title":960},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-static-export-vs-astro-for-marketing-sites","Next.js Static Export vs Astro for Marketing",{"path":962,"title":963},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Foptimizing-images-in-nextjs-static-export","Optimizing Images in Next.js Static Export",{"path":965,"title":966},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fadding-pagefind-to-an-astro-site","Adding Pagefind to an Astro Site",{"path":968,"title":969},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fbuilding-a-lunr-index-at-build-time-in-eleventy","Building a Lunr Index at Build Time in Eleventy",{"path":971,"title":972},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":974,"title":975},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":977,"title":978},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":980,"title":981},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":983,"title":984},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fsearch-index-size-budgets-for-large-docs","Search Index Size Budgets for Large Docs",{"path":986,"title":987},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fbest-ssg-for-technical-writers-without-coding-experience","Best SSG for Non-Developer Technical Writers",{"path":989,"title":990},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fchoosing-an-ssg-for-api-reference-documentation","Choosing an SSG for API Reference Documentation",{"path":992,"title":993},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":995,"title":996},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":998,"title":999},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fpicking-an-ssg-for-a-multi-language-documentation-site","Picking an SSG for a Multi-Language Docs Site",{"path":1001,"title":1002},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fssg-selection-checklist-for-engineering-teams","SSG Selection Checklist for Engineering Teams",{"path":1004,"title":1005},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Ftotal-cost-of-ownership-for-static-site-generators","Total Cost of Ownership for Static Site Generators",{"path":1007,"title":1008},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-busting-with-content-hashed-filenames","Cache Busting with Content-Hashed Filenames",{"path":1010,"title":1011},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs","CDN Caching Rules for SSGs",{"path":1013,"title":1014},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fpurging-the-cdn-cache-after-a-static-deploy","Purging the CDN Cache After a Static Deploy",{"path":1016,"title":1017},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-cache-control-headers-on-cloudflare-pages","Cache-Control Headers on Cloudflare Pages",{"path":1019,"title":1020},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-up-proper-cache-headers-on-netlify","Proper Cache Headers on Netlify for SSGs",{"path":1022,"title":1023},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fstale-while-revalidate-for-static-html","Stale-While-Revalidate for Static HTML",{"path":1025,"title":1026},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Feliminating-layout-shift-from-web-fonts","Eliminating Layout Shift From Web Fonts",{"path":1028,"title":1029},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-cookie-banners","Fixing CLS from Cookie Banners",{"path":1031,"title":1032},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-late-loading-embeds","Fixing CLS From Late-Loading Embeds",{"path":1034,"title":1035},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-sticky-headers-and-anchor-links","Fixing CLS from Sticky Headers and Anchor Links",{"path":1037,"title":1038},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":1040,"title":1041},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Fmeasuring-cls-in-the-field-with-web-vitals-js","Measuring CLS in the Field With web-vitals.js",{"path":1043,"title":1044},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Freserving-space-for-images-and-embeds-to-stop-layout-shift","Reserving Space for Images and Embeds",{"path":1046,"title":1047},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap","font-display: optional vs swap",{"path":1049,"title":1050},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":1052,"title":1053},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fmetric-matched-fallback-fonts-with-size-adjust","Metric-Matched Fallback Fonts with size-adjust",{"path":1055,"title":1056},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads","Preloading Fonts Without Double Downloads",{"path":1058,"title":1059},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fself-hosting-google-fonts-to-eliminate-layout-shift","Self-Host Google Fonts to Eliminate Layout Shift",{"path":1061,"title":1062},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fsubsetting-variable-fonts-for-faster-first-render","Subsetting Variable Fonts for Faster First Render",{"path":1064,"title":1065},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fbuilding-an-image-cdn-pipeline-for-static-sites","Building an Image CDN Pipeline for Static Sites",{"path":1067,"title":1068},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fgenerating-open-graph-images-at-build-time","Generating Open Graph Images at Build Time",{"path":1070,"title":1071},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro","Image Optimization Pipelines in Astro",{"path":1073,"title":1074},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp","Lazy-Loading Images Without Hurting LCP",{"path":1076,"title":1077},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Foptimizing-webp-images-in-hugo-without-plugins","Optimizing WebP Images in Hugo Without Plugins",{"path":1079,"title":1080},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fresponsive-images-with-srcset-in-eleventy","Responsive Images with srcset in Eleventy",{"path":1082,"title":1083},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fserving-avif-with-fallbacks-on-static-sites","Serving AVIF With Fallbacks on Static Sites",{"path":1085,"title":1086},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":1088,"title":774},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance",{"path":837,"title":5},{"path":1091,"title":1092},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fhow-to-reduce-bundle-size-in-eleventy-builds","How to Reduce Bundle Size in Eleventy Builds",{"path":1094,"title":41},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering",{"path":1096,"title":1097},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fmeasuring-inp-on-static-sites-with-real-user-monitoring","Measuring INP on Static Sites with RUM",{"path":1099,"title":781},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components",{"path":1101,"title":1102},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Feliminating-render-blocking-css-on-static-sites","Eliminating Render-Blocking CSS on Static Sites",{"path":1104,"title":1105},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages","Fixing LCP on Text-Heavy Documentation Pages",{"path":1107,"title":1108},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites","Largest Contentful Paint Optimization for Static Sites",{"path":1110,"title":1111},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fmeasuring-lcp-subparts-with-devtools","Measuring LCP Subparts with DevTools",{"path":1113,"title":1114},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Foptimizing-lcp-on-astro-with-priority-hints","Optimizing LCP on Astro with Priority Hints",{"path":1116,"title":1117},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Freducing-lcp-from-hero-images-on-static-sites","Reducing LCP from Hero Images on Static Sites",{"path":1119,"title":1120},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fcomparing-lab-and-field-data-with-crux","Comparing Lab and Field Data with CrUX",{"path":1122,"title":1123},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":1125,"title":1126},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Freducing-lighthouse-score-variance-in-ci","Reducing Lighthouse Score Variance in CI",{"path":1128,"title":1129},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Frunning-webpagetest-scripts-against-preview-deploys","Running WebPageTest Scripts Against Preview Deploys",{"path":1131,"title":1132},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fsetting-up-lighthouse-ci-for-a-static-site","Setting Up Lighthouse CI for a Static Site",{"path":1134,"title":1135},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-bundle-size-per-pull-request","Tracking Bundle Size per Pull Request",{"path":1137,"title":1138},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fwriting-a-performance-budget-that-fails-builds","Writing a Performance Budget That Fails Builds",{"path":1140,"title":1141},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":1143,"title":1144},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":1146,"title":1147},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":1149,"title":1150},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fpreconnect-vs-dns-prefetch-on-static-sites","Preconnect vs DNS-Prefetch on Static Sites",{"path":1152,"title":793},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro",{"path":1154,"title":1155},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fview-transitions-on-multi-page-static-sites","View Transitions on Multi-Page Static Sites",{"path":1157,"title":1158},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fauditing-third-party-scripts-with-lighthouse","Auditing Third-Party Scripts With Lighthouse",{"path":1160,"title":1161},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites","Third-Party Script Performance on Static Sites",{"path":1163,"title":1164},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Flazy-loading-youtube-embeds-on-static-sites","Lazy-Loading YouTube Embeds on Static Sites",{"path":1166,"title":1167},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Floading-google-tag-manager-without-hurting-inp","Loading Google Tag Manager Without Hurting INP",{"path":1169,"title":1170},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Frunning-third-party-scripts-in-a-web-worker-with-partytown","Running Third-Party Scripts in a Web Worker with Partytown",{"path":1172,"title":1173},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fself-hosting-analytics-to-cut-third-party-requests","Self-Hosting Analytics to Cut Third-Party Requests",{"path":1175,"title":1176},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":1178,"title":1179},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages","Configuring Redirects on Cloudflare Pages",{"path":1181,"title":1182},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcustom-domains-and-tls-on-cloudflare-pages","Custom Domains and TLS on Cloudflare Pages",{"path":1184,"title":1185},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fdeploying-hugo-to-cloudflare-pages-and-workers","Deploying Hugo to Cloudflare Pages and Workers",{"path":1187,"title":1188},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup","Cloudflare Pages Edge Caching Setup",{"path":1190,"title":1191},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fmigrating-from-cloudflare-pages-to-workers-static-assets","Migrating from Cloudflare Pages to Workers Static Assets",{"path":1193,"title":1194},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":1196,"title":1197},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fdocs-as-code-review-workflow-for-writers","Docs-as-Code Review Workflow for Writers",{"path":1199,"title":1200},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":1202,"title":1203},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":1205,"title":1206},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduling-content-publication-with-cron-triggered-builds","Scheduling Content Publication With Cron-Triggered Builds",{"path":1208,"title":1209},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fwiring-a-headless-cms-to-a-static-build","Wiring a Headless CMS to a Static Build",{"path":1211,"title":1212},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":1214,"title":1215},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fcaching-node-modules-in-github-actions-for-faster-ssg-builds","Caching node_modules in GitHub Actions",{"path":1217,"title":1218},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":1220,"title":1221},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-multiple-environments-from-one-workflow","Deploying to Multiple Environments From One Workflow",{"path":1223,"title":1224},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fhow-to-set-up-github-actions-for-hugo-deployments","GitHub Actions for Hugo Deployments",{"path":1226,"title":1227},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":1229,"title":1230},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":1232,"title":1233},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fcaching-hugo-builds-in-github-actions","Caching Hugo Builds in GitHub Actions",{"path":1235,"title":1236},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":1238,"title":1239},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fincremental-builds-in-astro-with-the-content-layer","Incremental Builds in Astro with the Content Layer",{"path":1241,"title":1242},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":1244,"title":1245},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fmeasuring-build-time-regressions-in-ci","Measuring Build-Time Regressions in CI",{"path":1247,"title":1248},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fremote-caching-with-turborepo-for-ssg-monorepos","Remote Caching with Turborepo for SSG Monorepos",{"path":1250,"title":1251},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fsharing-build-cache-across-ci-runners","Sharing Build Cache Across CI Runners",{"path":1253,"title":1254},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":1256,"title":1257},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops","Alerting on Cache Hit Ratio Drops",{"path":1259,"title":1260},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fbuilding-a-core-web-vitals-dashboard-from-rum-data","Building a Core Web Vitals Dashboard from RUM Data",{"path":1262,"title":1263},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule","Crawling for Broken Links on a Schedule",{"path":1265,"title":1266},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production","Monitoring Static Sites in Production",{"path":1268,"title":1269},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge","Logging 404s at the Edge",{"path":1271,"title":1272},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fuptime-and-synthetic-checks-for-static-sites","Uptime and Synthetic Checks for Static Sites",{"path":1274,"title":1275},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":1277,"title":1278},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies","Netlify vs Vercel Deployment Strategies",{"path":1280,"title":1281},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates","Netlify Build Hooks for Content Updates",{"path":1283,"title":1284},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites","Netlify Redirects and Rewrites for Static Sites",{"path":1286,"title":1287},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fsetting-up-deploy-previews-on-netlify-for-every-pull-request","Netlify Deploy Previews for Every Pull Request",{"path":1289,"title":1290},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-isr-vs-static-generation-for-ssgs","Vercel ISR vs Static Generation for SSGs",{"path":1292,"title":1293},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fautomating-preview-deploy-pipelines-with-github-actions","Automating Preview Deploy Pipelines with GitHub Actions",{"path":1295,"title":1296},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments","Cleaning Up Stale Preview Deployments",{"path":1298,"title":1299},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":1301,"title":1302},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":1304,"title":1305},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":1307,"title":1308},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":1310,"title":1311},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads","Atomic Deploys vs Incremental Uploads",{"path":1313,"title":1314},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":1316,"title":1317},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":1319,"title":1320},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":1322,"title":1323},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-a-bad-static-deploy-in-under-a-minute","Rolling Back a Bad Static Deploy in Under a Minute",{"path":1325,"title":1326},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frunning-smoke-tests-against-a-preview-url","Running Smoke Tests Against a Preview URL",{"path":1328,"title":1329},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":1331,"title":1332},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":1334,"title":1335},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fhash-based-csp-for-inline-scripts-in-astro","Hash-Based CSP for Inline Scripts in Astro",{"path":1337,"title":1338},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites","Security Headers and Hardening for Static Sites",{"path":1340,"title":1341},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc","Securing Deploy Credentials with GitHub OIDC",{"path":1343,"title":1344},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":1346,"title":1347},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fwriting-a-content-security-policy-for-a-static-site","Writing a Content Security Policy for a Static Site",{"path":1349,"title":1350},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3","Clean URLs and Trailing Slashes on S3",{"path":1352,"title":1353},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects","CloudFront Functions for Redirects",{"path":1355,"title":1356},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront","Deploying a Static Site to S3 and CloudFront",{"path":1358,"title":1359},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites","Self-Hosting Static Sites on S3, Nginx and Caddy",{"path":1361,"title":1362},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy","Serving a Static Site with Caddy",{"path":1364,"title":1365},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx","Serving a Static Site with Nginx",{"path":1367,"title":1368},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps","Zero-Downtime Deploys with Symlink Swaps",{"path":1370,"title":1371},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fadding-a-contact-form-with-cloudflare-workers","Adding a Contact Form with Cloudflare Workers",{"path":1373,"title":1374},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fhandling-form-submissions-on-a-static-site","Handling Form Submissions on a Static Site",{"path":1376,"title":1377},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites","Serverless Functions for Static Sites",{"path":1379,"title":1380},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers","Netlify Functions vs Cloudflare Workers",{"path":1382,"title":1383},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication","Protecting a Static Site Behind Authentication",{"path":1385,"title":1386},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fproxying-third-party-apis-from-an-edge-function","Proxying Third-Party APIs from an Edge Function",1789722847770]