@@ -46,6 +46,19 @@ navigationInit()
4646const reloadStorageKey = `gatsby-reload-compilation-hash-match`
4747
4848apiRunnerAsync ( `onClientEntry` ) . then ( ( ) => {
49+ // Set up React 19 error handling
50+ const handleUncaughtError = ( error , errorInfo ) => {
51+ // Report uncaught errors to any error tracking service
52+ console . error ( `Uncaught error:` , error , errorInfo )
53+ apiRunner ( `onUncaughtError` , { error, errorInfo } )
54+ }
55+
56+ const handleCaughtError = ( error , errorInfo ) => {
57+ // Report caught errors to any error tracking service
58+ console . error ( `Caught error:` , error , errorInfo )
59+ apiRunner ( `onCaughtError` , { error, errorInfo } )
60+ }
61+
4962 // Let plugins register a service worker. The plugin just needs
5063 // to return true.
5164 if ( apiRunner ( `registerServiceWorker` ) . filter ( Boolean ) . length > 0 ) {
@@ -277,16 +290,23 @@ apiRunnerAsync(`onClientEntry`).then(() => {
277290
278291 // Client only pages have any empty body so we just do a normal
279292 // render to avoid React complaining about hydration mis-matches.
280- let defaultRenderer = render
293+ let defaultRenderer = ( Component , el ) =>
294+ render ( Component , el , {
295+ onUncaughtError : handleUncaughtError ,
296+ onCaughtError : handleCaughtError ,
297+ } )
298+
281299 if ( focusEl && focusEl . children . length ) {
282- defaultRenderer = hydrate
300+ defaultRenderer = ( Component , el ) =>
301+ hydrate ( Component , el , {
302+ onUncaughtError : handleUncaughtError ,
303+ onCaughtError : handleCaughtError ,
304+ } )
283305 }
284306
285- const renderer = apiRunner (
286- `replaceHydrateFunction` ,
287- undefined ,
307+ const renderer =
308+ apiRunner ( `replaceHydrateFunction` , undefined , defaultRenderer ) [ 0 ] ||
288309 defaultRenderer
289- ) [ 0 ]
290310
291311 function runRender ( ) {
292312 const rootElement =
0 commit comments