@@ -5,7 +5,7 @@ import { friendlyErrorDisplay } from "~/utils/httpErrors";
55import { LinkButton } from "./primitives/Buttons" ;
66import { Header1 } from "./primitives/Headers" ;
77import { Paragraph } from "./primitives/Paragraph" ;
8- import { type ReactNode , useEffect } from "react" ;
8+ import { type ReactNode , useEffect , useState } from "react" ;
99
1010declare global {
1111 namespace JSX {
@@ -56,14 +56,21 @@ type DisplayOptionsProps = {
5656} & ErrorDisplayOptions ;
5757
5858export function ErrorDisplay ( { title, message, button } : DisplayOptionsProps ) {
59+ const [ isSplineReady , setIsSplineReady ] = useState ( false ) ;
60+
5961 useEffect ( ( ) => {
60- // Dynamically load the Spline viewer script
61- if ( ! customElements . get ( "spline-viewer" ) ) {
62- const script = document . createElement ( "script" ) ;
63- script . type = "module" ;
64- script . src = "https://unpkg.com/@splinetool/[email protected] /build/spline-viewer.js" ; 65- document . head . appendChild ( script ) ;
62+ // Already registered from a previous render
63+ if ( customElements . get ( "spline-viewer" ) ) {
64+ setIsSplineReady ( true ) ;
65+ return ;
6666 }
67+
68+ const script = document . createElement ( "script" ) ;
69+ script . type = "module" ;
70+ script . src = "https://unpkg.com/@splinetool/[email protected] /build/spline-viewer.js" ; 71+ script . onload = ( ) => setIsSplineReady ( true ) ;
72+ // On error, we simply don't show the decorative viewer - no action needed
73+ document . head . appendChild ( script ) ;
6774 } , [ ] ) ;
6875
6976 return (
@@ -80,18 +87,20 @@ export function ErrorDisplay({ title, message, button }: DisplayOptionsProps) {
8087 { button ? button . title : "Go to homepage" }
8188 </ LinkButton >
8289 </ div >
83- < motion . div
84- className = "pointer-events-none absolute inset-0 overflow-hidden"
85- initial = { { opacity : 0 } }
86- animate = { { opacity : 1 } }
87- transition = { { delay : 0.5 , duration : 2 , ease : "easeOut" } }
88- >
89- < spline-viewer
90- loading-anim-type = "spinner-small-light"
91- url = "https://prod.spline.design/wRly8TZN-e0Twb8W/scene.splinecode"
92- style = { { width : "100%" , height : "100%" } }
93- />
94- </ motion . div >
90+ { isSplineReady && (
91+ < motion . div
92+ className = "pointer-events-none absolute inset-0 overflow-hidden"
93+ initial = { { opacity : 0 } }
94+ animate = { { opacity : 1 } }
95+ transition = { { delay : 0.5 , duration : 2 , ease : "easeOut" } }
96+ >
97+ < spline-viewer
98+ loading-anim-type = "spinner-small-light"
99+ url = "https://prod.spline.design/wRly8TZN-e0Twb8W/scene.splinecode"
100+ style = { { width : "100%" , height : "100%" } }
101+ />
102+ </ motion . div >
103+ ) }
95104 </ div >
96105 ) ;
97106}
0 commit comments