@@ -18,6 +18,7 @@ import { Spring } from 'react-spring/renderprops.cjs';
1818import { generateFileFromSandbox } from '../../templates/configuration/package-json' ;
1919
2020import { getSandboxName } from '../../utils/get-sandbox-name' ;
21+ import track from '../../utils/analytics' ;
2122
2223import Navigator from './Navigator' ;
2324import { Container , StyledFrame , Loading } from './elements' ;
@@ -56,6 +57,7 @@ type State = {
5657 urlInAddressBar : string ;
5758 url : string | undefined ;
5859 showScreenshot : boolean ;
60+ useFallbackDomain : boolean ;
5961} ;
6062
6163const getSSEUrl = ( sandbox ?: Sandbox , initialPath : string = '' ) =>
@@ -86,6 +88,7 @@ class BasePreview extends React.Component<Props, State> {
8688 urlInAddressBar : this . currentUrl ( ) ,
8789 url : null ,
8890 showScreenshot : true ,
91+ useFallbackDomain : false ,
8992 } ;
9093
9194 // we need a value that doesn't change when receiving `initialPath`
@@ -107,6 +110,8 @@ class BasePreview extends React.Component<Props, State> {
107110
108111 ( window as any ) . openNewWindow = this . openNewWindow ;
109112
113+ this . testFallbackDomainIfNeeded ( ) ;
114+
110115 setTimeout ( ( ) => {
111116 if ( this . state . showScreenshot ) {
112117 this . setState ( { showScreenshot : false } ) ;
@@ -123,11 +128,68 @@ class BasePreview extends React.Component<Props, State> {
123128 }
124129 }
125130
131+ /**
132+ * We have a different domain for the preview (currently :id.csb.app), some corporate
133+ * firewalls block calls to these domains. Which is why we ping the domain here, if it
134+ * returns a bad response we fall back to using our main domain (:id.codesandbox.io).
135+ *
136+ * We use a different domain for the preview, since Chrome runs iframes from a different root
137+ * domain in a different process, which means for us that we have a snappier editor
138+ */
139+ testFallbackDomainIfNeeded = ( ) => {
140+ const TRACKING_NAME = 'Preview - Fallback URL' ;
141+ const normalUrl = frameUrl (
142+ this . props . sandbox ,
143+ this . props . initialPath || ''
144+ ) ;
145+ const fallbackUrl = frameUrl (
146+ this . props . sandbox ,
147+ this . props . initialPath || '' ,
148+ true
149+ ) ;
150+
151+ const setFallbackDomain = ( ) => {
152+ this . setState (
153+ {
154+ useFallbackDomain : true ,
155+ urlInAddressBar : frameUrl (
156+ this . props . sandbox ,
157+ this . props . initialPath || '' ,
158+ true
159+ ) ,
160+ } ,
161+ ( ) => {
162+ requestAnimationFrame ( ( ) => {
163+ this . sendUrl ( ) ;
164+ } ) ;
165+ }
166+ ) ;
167+ } ;
168+
169+ if ( ! this . props . url && normalUrl !== fallbackUrl ) {
170+ fetch ( normalUrl , { mode : 'no-cors' } )
171+ . then ( ( ) => {
172+ // Succeeded
173+ track ( TRACKING_NAME , { needed : false } ) ;
174+ } )
175+ . catch ( ( ) => {
176+ // Failed, use fallback
177+ track ( TRACKING_NAME , { needed : true } ) ;
178+
179+ setFallbackDomain ( ) ;
180+ } ) ;
181+ }
182+ } ;
183+
126184 currentUrl = ( ) =>
127185 this . props . url ||
128186 ( this . serverPreview
129187 ? getSSEUrl ( this . props . sandbox , this . props . initialPath )
130- : frameUrl ( this . props . sandbox , this . props . initialPath || '' ) ) ;
188+ : frameUrl (
189+ this . props . sandbox ,
190+ this . props . initialPath || '' ,
191+ this . state && this . state . useFallbackDomain
192+ ) ) ;
131193
132194 static defaultProps = {
133195 showNavigation : true ,
0 commit comments