<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss/styles.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Rimrachai&apos;s Dev Notes</title><description>Notes on building software, one commit at a time.</description><link>https://devnotes.rimrachai.com/</link><language>en-us</language><item><title>Component-Level Error Handling in Next.js App Router with ErrorBoundary</title><link>https://devnotes.rimrachai.com/blogs/component-level-error-handling-nextjs-app-router/</link><guid isPermaLink="true">https://devnotes.rimrachai.com/blogs/component-level-error-handling-nextjs-app-router/</guid><description>error.tsx handles route-level failures, but a single misbehaving widget shouldn&apos;t take down the whole page. Here&apos;s a reusable ErrorBoundary pattern for Server Components, paired with Suspense, that gives you per-widget fallback UI and access to the real error object.</description><pubDate>Sun, 16 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Next.js gives you &lt;code&gt;error.tsx&lt;/code&gt; for handling errors at the route/segment level, and it works well for that. But it’s a blunt instrument one error anywhere in the segment, and the whole page’s fallback UI takes over.&lt;/p&gt;
&lt;p&gt;That’s too coarse for dashboards, charts, or any page built out of several independent widgets. If one widget’s data fetch fails, you don’t want to lose the rest of the page you want that one widget to show a fallback while everything else keeps working.&lt;/p&gt;
&lt;p&gt;The fix is the same one React has always had for this: an &lt;code&gt;ErrorBoundary&lt;/code&gt;, scoped to the component that might fail, paired with &lt;code&gt;Suspense&lt;/code&gt; for the loading state.&lt;/p&gt;
&lt;h2 id=&quot;the-errorboundary-component&quot;&gt;The ErrorBoundary component&lt;/h2&gt;
&lt;p&gt;This is a standard class-based error boundary (React doesn’t have a hook equivalent yet), built to support three levels of fallback flexibility no fallback prop, a static fallback node, or a function that receives the actual error.&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;/_astro/ec.szowa.css&quot;&gt;&lt;script type=&quot;module&quot; src=&quot;/_astro/ec.0vx5m.js&quot;&gt;&lt;/script&gt;&lt;figure class=&quot;frame has-title&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;src/components/error-boundary.tsx&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;use client&quot;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; React &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;Props&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;children&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ReactNode&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;?:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ReactNode &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ReactNode)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;onError&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;?:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;errorInfo&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ErrorInfo&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;interface&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;State&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;hasError&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;boolean&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; null&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;class&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;extends&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;Component&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;Props&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; State&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;constructor&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Props&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;super&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;(props)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;state &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; hasError&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EF9F76;--1:#A54107&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;getDerivedStateFromError&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;State&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; hasError&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EF9F76;--1:#A54107&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; error &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;componentDidCatch&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;errorInfo&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ErrorInfo&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;console&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;ErrorBoundary caught an error:&quot;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; errorInfo)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;onError) &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;onError&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;(error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; errorInfo)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;render&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;hasError &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error) &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;typeof&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;fallback &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;===&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;function&quot;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;fallback) &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--0fs:italic;--1:#5D5F6E;--1fs:italic&quot;&gt;// Default fallback UI&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;DefaultErrorFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;state&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EB9799;--1:#C00E34&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;props&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;children&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;DefaultErrorFallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;FC&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--0fs:italic;--1:#4C4F69;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; Error &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; (&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;flex items-start gap-3 py-4 px-5 bg-red-50 dark:bg-red-900/10 border border-red-200 dark:border-red-800 rounded-lg&quot;&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;svg&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;size-5 text-red-500 dark:text-red-400 shrink-0 mt-0.5&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fill&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;none&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;viewBox&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;0 0 24 24&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;stroke&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;currentColor&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;path&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;strokeLinecap&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;strokeLinejoin&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;round&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;strokeWidth&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#EF9F76;--1:#A54107&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;svg&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;flex-1 space-y-1&quot;&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;text-sm font-semibold text-red-800 dark:text-red-400&quot;&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;Something went wrong&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;className&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;text-xs text-red-600 dark:text-red-500&quot;&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;message &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;An unexpected error occurred&quot;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--1:#1A57D1&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&amp;#x22;use client&amp;#x22;;import React from &amp;#x22;react&amp;#x22;;interface Props {  children: React.ReactNode;  fallback?: React.ReactNode | ((error: Error) =&gt; React.ReactNode);  onError?: (error: Error, errorInfo: React.ErrorInfo) =&gt; void;}interface State {  hasError: boolean;  error: Error | null;}export class ErrorBoundary extends React.Component&lt;Props, State&gt; {  constructor(props: Props) {    super(props);    this.state = { hasError: false, error: null };  }  static getDerivedStateFromError(error: Error): State {    return { hasError: true, error };  }  componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void {    console.error(&amp;#x22;ErrorBoundary caught an error:&amp;#x22;, error, errorInfo);    if (this.props.onError) {      this.props.onError(error, errorInfo);    }  }  render() {    if (this.state.hasError &amp;#x26;&amp;#x26; this.state.error) {      if (typeof this.props.fallback === &amp;#x22;function&amp;#x22;) {        return this.props.fallback(this.state.error);      }      if (this.props.fallback) {        return this.props.fallback;      }      // Default fallback UI      return &lt;DefaultErrorFallback error={this.state.error} /&gt;;    }    return this.props.children;  }}const DefaultErrorFallback: React.FC&lt;{ error: Error }&gt; = ({ error }) =&gt; {  return (    &lt;div className=&amp;#x22;flex items-start gap-3 py-4 px-5 bg-red-50 dark:bg-red-900/10 border border-red-200 dark:border-red-800 rounded-lg&amp;#x22;&gt;      &lt;svg        className=&amp;#x22;size-5 text-red-500 dark:text-red-400 shrink-0 mt-0.5&amp;#x22;        fill=&amp;#x22;none&amp;#x22;        viewBox=&amp;#x22;0 0 24 24&amp;#x22;        stroke=&amp;#x22;currentColor&amp;#x22;      &gt;        &lt;path          strokeLinecap=&amp;#x22;round&amp;#x22;          strokeLinejoin=&amp;#x22;round&amp;#x22;          strokeWidth={2}          d=&amp;#x22;M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z&amp;#x22;        /&gt;      &lt;/svg&gt;      &lt;div className=&amp;#x22;flex-1 space-y-1&amp;#x22;&gt;        &lt;p className=&amp;#x22;text-sm font-semibold text-red-800 dark:text-red-400&amp;#x22;&gt;Something went wrong&lt;/p&gt;        &lt;p className=&amp;#x22;text-xs text-red-600 dark:text-red-500&amp;#x22;&gt;{error.message || &amp;#x22;An unexpected error occurred&amp;#x22;}&lt;/p&gt;      &lt;/div&gt;    &lt;/div&gt;  );};&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;That’s it one client component, no dependencies. Everything below is just usage patterns.&lt;/p&gt;
&lt;h2 id=&quot;usage-patterns&quot;&gt;Usage patterns&lt;/h2&gt;
&lt;h3 id=&quot;1-default-fallback&quot;&gt;1. Default fallback&lt;/h3&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;LoadingFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Widget&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--0fs:italic;--1:#5D5F6E;--1fs:italic&quot;&gt;/* Server Component with server action data fetch */&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&lt;ErrorBoundary&gt;  &lt;Suspense fallback={&lt;LoadingFallback /&gt;}&gt;    &lt;Widget /&gt; {/* Server Component with server action data fetch */}  &lt;/Suspense&gt;&lt;/ErrorBoundary&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Uses the internal &lt;code&gt;DefaultErrorFallback&lt;/code&gt;&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; No custom fallback UI&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Good enough when you just want a widget to fail gracefully without a custom design pass.&lt;/p&gt;
&lt;h3 id=&quot;2-custom-fallback-ui-as-a-static-node&quot;&gt;2. Custom fallback UI as a static node&lt;/h3&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;LoadingFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Widget&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--0fs:italic;--1:#5D5F6E;--1fs:italic&quot;&gt;/* Server Component with server action data fetch */&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&lt;ErrorBoundary fallback={&lt;ErrorFallback /&gt;}&gt;  &lt;Suspense fallback={&lt;LoadingFallback /&gt;}&gt;    &lt;Widget /&gt; {/* Server Component with server action data fetch */}  &lt;/Suspense&gt;&lt;/ErrorBoundary&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Good for custom fallback UI&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Cannot show dynamic error messages the node is static, so it has no way to reference what actually broke&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;3-custom-fallback-ui-as-a-function-recommended&quot;&gt;3. Custom fallback UI as a function (recommended)&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;ErrorBoundary&lt;/code&gt; is a Client Component, and its &lt;code&gt;fallback&lt;/code&gt; function needs to live in a Client Component too you can’t pass an inline arrow function as a prop from a Server Component. The clean way around that is a thin client wrapper:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame has-title&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;span class=&quot;title&quot;&gt;src/components/error-boundary-wrapper.tsx&lt;/span&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6D189;--1:#2C6E1E&quot;&gt;&quot;use client&quot;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#90ADEF;--0fs:italic;--1:#1A57D1;--1fs:italic&quot;&gt;ErrorBoundaryWrapper&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;FC&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--0fs:italic;--1:#4C4F69;--1fs:italic&quot;&gt;children&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; React&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt;ReactNode &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#99D1DB;--1:#03678F&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--0fs:italic;--1:#865511;--1fs:italic&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;({&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;children&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;})&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{(&lt;/span&gt;&lt;span style=&quot;--0:#EA999C;--0fs:italic;--1:#AD343E;--1fs:italic&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#CA9EE6;--1:#7B34D9&quot;&gt;=&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;error&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt;children&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundary&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;};&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&amp;#x22;use client&amp;#x22;;export const ErrorBoundaryWrapper: React.FC&lt;{ children: React.ReactNode }&gt; = ({ children }) =&gt; {  return &lt;ErrorBoundary fallback={(error) =&gt; &lt;ErrorFallback error={error} /&gt;}&gt;{children}&lt;/ErrorBoundary&gt;;};&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;Then use it directly from a Server Component page:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;tsx&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundaryWrapper&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#E5C890;--1:#865511&quot;&gt;fallback&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;LoadingFallback&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Widget&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;/&gt;&lt;/span&gt;&lt;span style=&quot;--0:#C6D0F5;--1:#4C4F69&quot;&gt; &lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--0fs:italic;--1:#5D5F6E;--1fs:italic&quot;&gt;/* Server Component with server action data fetch */&lt;/span&gt;&lt;span style=&quot;--0:#A6ADC7;--1:#5D5F6E&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span class=&quot;indent&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;Suspense&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;--0:#F4B8E4;--1:#8D477A&quot;&gt;ErrorBoundaryWrapper&lt;/span&gt;&lt;span style=&quot;--0:#81C8BE;--1:#116B70&quot;&gt;&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;&lt;ErrorBoundaryWrapper&gt;  &lt;Suspense fallback={&lt;LoadingFallback /&gt;}&gt;    &lt;Widget /&gt; {/* Server Component with server action data fetch */}  &lt;/Suspense&gt;&lt;/ErrorBoundaryWrapper&gt;&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Custom fallback UI&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Access to the actual error object&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Dynamic, per-error messages&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the pattern I reach for by default the wrapper is boilerplate you write once per fallback design, and every widget that uses it gets a real error message instead of a generic “something broke.”&lt;/p&gt;
&lt;h2 id=&quot;why-this-matters&quot;&gt;Why this matters&lt;/h2&gt;
&lt;p&gt;Component-level error handling means one failing widget degrades gracefully instead of taking the whole page down with it. For dashboards, charts, or any page assembled from several independent data-fetching widgets, that’s the difference between “one chart is down” and “the entire page is broken.”&lt;/p&gt;
&lt;p&gt;&lt;code&gt;error.tsx&lt;/code&gt; still has its place for route-level failures. This pattern just fills the gap underneath it scoped to exactly the component that might fail.&lt;/p&gt;</content:encoded><category>nextjs</category><category>react</category><category>error handling</category><category>frontend</category><category>engineering</category></item><item><title>Why a Smaller Connection Pool Makes Your Database Faster</title><link>https://devnotes.rimrachai.com/blogs/database-connection-pool-sizing/</link><guid isPermaLink="true">https://devnotes.rimrachai.com/blogs/database-connection-pool-sizing/</guid><description>More database connections doesn&apos;t mean more throughput. Here&apos;s the math behind why a pool of 10-20 connections often outperforms one with hundreds, and the formula to size yours correctly.</description><pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I used to think more database connections meant better performance. I was wrong and the real answer surprised me.&lt;/p&gt;
&lt;h2 id=&quot;a-real-scenario&quot;&gt;A Real Scenario&lt;/h2&gt;
&lt;p&gt;Say you have 10,000 concurrent users hitting your app. How big should your connection pool be?&lt;/p&gt;
&lt;p&gt;10,000? 1,000? 500?&lt;/p&gt;
&lt;p&gt;Try 10. Yes, ten.&lt;/p&gt;
&lt;h2 id=&quot;why-thats-not-a-typo&quot;&gt;Why That’s Not a Typo&lt;/h2&gt;
&lt;p&gt;Your database is bottlenecked by three things: CPU, disk, and network not connection count.&lt;/p&gt;
&lt;p&gt;A 4-core server can only do four things at once. Throwing 500 connections at it doesn’t give you 500x throughput. It gives you 500 threads fighting over 4 cores, with the operating system burning cycles just switching between them. That overhead is called &lt;strong&gt;context switching&lt;/strong&gt;, and it’s pure waste.&lt;/p&gt;
&lt;h2 id=&quot;so-why-not-exactly-4-connections&quot;&gt;So Why Not Exactly 4 Connections?&lt;/h2&gt;
&lt;p&gt;Because of I/O wait.&lt;/p&gt;
&lt;p&gt;When a query hits disk, that thread just sits there blocked, doing nothing, while the CPU sits idle. So it makes sense to let another thread step in and use that idle CPU time up to a point.&lt;/p&gt;
&lt;p&gt;This is the reasoning behind a formula the PostgreSQL community has used for pool sizing:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;/_astro/ec.szowa.css&quot;&gt;&lt;script type=&quot;module&quot; src=&quot;/_astro/ec.0vx5m.js&quot;&gt;&lt;/script&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#c6d0f5;--1:#4c4f69&quot;&gt;connections = (core_count × 2) + effective_spindle_count&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;connections = (core_count × 2) + effective_spindle_count&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;For a 4-core server with one HDD:&lt;/p&gt;
&lt;div class=&quot;expressive-code&quot;&gt;&lt;figure class=&quot;frame&quot;&gt;&lt;figcaption class=&quot;header&quot;&gt;&lt;/figcaption&gt;&lt;pre data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;div class=&quot;ec-line&quot;&gt;&lt;div class=&quot;code&quot;&gt;&lt;span style=&quot;--0:#c6d0f5;--1:#4c4f69&quot;&gt;(4 × 2) + 1 = 9 → round up to 10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class=&quot;copy&quot;&gt;&lt;div aria-live=&quot;polite&quot;&gt;&lt;/div&gt;&lt;button title=&quot;Copy to clipboard&quot; data-copied=&quot;Copied!&quot; data-code=&quot;(4 × 2) + 1 = 9 → round up to 10&quot;&gt;&lt;div&gt;&lt;/div&gt;&lt;/button&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;For SSDs, the effective spindle count drops to 0, giving you 8. Faster storage means less blocking, which means you need &lt;em&gt;fewer&lt;/em&gt; connections, not more. Counterintuitive, but it holds up: SSDs shrink the ideal pool size rather than growing it.&lt;/p&gt;
&lt;h2 id=&quot;the-proof-oracles-50x-improvement&quot;&gt;The Proof: Oracle’s 50x Improvement&lt;/h2&gt;
&lt;p&gt;Oracle’s Real-World Performance team demonstrated this live in a short video: they dropped a connection pool from 2,048 down to 96 connections. Response time went from roughly 100ms to roughly 2ms a 50x improvement, with zero code changes. You can watch the demo yourself: &lt;a href=&quot;https://youtu.be/_C77sBcAtSQ&quot;&gt;Oracle Real-World Performance: Connection Pooling&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-mental-model-to-keep&quot;&gt;The Mental Model to Keep&lt;/h2&gt;
&lt;p&gt;Aim for a small pool somewhere around 10 to 20 connections. Everything else queues and waits its turn. The database runs at full speed on what it can actually handle, and requests get served quickly, one after another.&lt;/p&gt;
&lt;p&gt;Compare that to a huge pool where 500 connections all thrash the CPU simultaneously. Nobody gets fast service everyone gets slow service, together.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Sources: &lt;a href=&quot;https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing&quot;&gt;HikariCP wiki — About Pool Sizing&lt;/a&gt;, &lt;a href=&quot;https://youtu.be/_C77sBcAtSQ&quot;&gt;Oracle Real-World Performance: Connection Pooling (video)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded><category>database</category><category>performance</category><category>postgresql</category><category>backend</category><category>engineering</category></item></channel></rss>