@@ -79,9 +79,43 @@ const getDependencies = (packageJsonContent: string): string => {
7979
8080let webContainer : Promise < WebContainer > | null = null
8181
82+ // Detect Firefox for specific handling
83+ const isFirefox =
84+ typeof navigator !== 'undefined' && navigator . userAgent . includes ( 'Firefox' )
85+
8286export default function createWebContainerStore ( shouldShimALS : boolean ) {
8387 if ( ! webContainer ) {
84- webContainer = WebContainer . boot ( )
88+ console . log ( `🌐 Initializing WebContainer (Firefox: ${ isFirefox } )` )
89+
90+ // Firefox-specific boot with timeout and error handling
91+ webContainer = Promise . race ( [
92+ WebContainer . boot ( {
93+ coep : isFirefox ? 'require-corp' : 'credentialless' ,
94+ } as any ) ,
95+ new Promise < never > ( ( _ , reject ) => {
96+ const timeout = isFirefox ? 15000 : 10000
97+ setTimeout ( ( ) => {
98+ reject (
99+ new Error (
100+ isFirefox
101+ ? 'WebContainer boot timeout. Please check Firefox privacy settings (Enhanced Tracking Protection may block Service Workers)'
102+ : 'WebContainer boot timeout'
103+ )
104+ )
105+ } , timeout )
106+ } ) ,
107+ ] ) . catch ( ( err ) => {
108+ console . error ( 'WebContainer boot failed:' , err )
109+ if ( isFirefox ) {
110+ console . warn (
111+ 'Firefox users: Check that Enhanced Tracking Protection is not blocking Service Workers'
112+ )
113+ console . warn (
114+ 'Firefox users: Service Workers are not available in Private Browsing mode'
115+ )
116+ }
117+ throw err
118+ } )
85119 }
86120
87121 const store = createStore < WebContainerStore > ( ( set , get ) => ( {
@@ -134,8 +168,9 @@ export default function createWebContainerStore(shouldShimALS: boolean) {
134168
135169 // Wait for server to be ready (set up listener first)
136170 container . on ( 'server-ready' , ( port , url ) => {
137- console . log ( 'Server ready on port' , port , 'at' , url )
171+ console . log ( '🌐 Server ready on port' , port , 'at' , url )
138172 const currentState = get ( )
173+ console . log ( '🌐 Setting previewUrl:' , url )
139174 set ( {
140175 previewUrl : url ,
141176 setupStep : 'ready' ,
@@ -145,6 +180,7 @@ export default function createWebContainerStore(shouldShimALS: boolean) {
145180 `✅ Server ready at ${ url } ` ,
146181 ] ,
147182 } )
183+ console . log ( '🌐 Preview URL set successfully' )
148184 } )
149185
150186 // Start the dev server
@@ -168,14 +204,28 @@ export default function createWebContainerStore(shouldShimALS: boolean) {
168204
169205 // Check exit code
170206 const exitCode = await newDevProcess . exit
207+ console . log ( '⚠️ Dev server process exited with code:' , exitCode )
171208 if ( exitCode !== 0 ) {
172209 addTerminalOutput ( `❌ Dev server exited with code ${ exitCode } ` )
173- set ( { error : `Dev server exited with code ${ exitCode } ` } )
210+ console . log ( '❌ Clearing preview URL due to dev server exit' )
211+ set ( {
212+ error : `Dev server exited with code ${ exitCode } ` ,
213+ previewUrl : null ,
214+ setupStep : 'error' ,
215+ } )
216+ } else {
217+ console . log ( 'ℹ️ Dev server exited cleanly (code 0)' )
218+ set ( { previewUrl : null , devProcess : null } )
174219 }
175220 } catch ( error ) {
176221 console . error ( 'Dev server start error:' , error )
177222 addTerminalOutput ( `❌ Dev server error: ${ ( error as Error ) . message } ` )
178- set ( { error : ( error as Error ) . message , setupStep : 'error' } )
223+ console . log ( '❌ Clearing preview URL due to dev server error' )
224+ set ( {
225+ error : ( error as Error ) . message ,
226+ setupStep : 'error' ,
227+ previewUrl : null ,
228+ } )
179229 }
180230 } ,
181231 updateProjectFiles : async (
0 commit comments