+ router.push('/logout')}
+ >
+ Sign out
+ {' '}
+ and sign back in
+
+
+
+ Clear your browser storage
+ {' '}
+ to clean potentially outdated data
+
+
+ Disable browser extensions that might modify page content (e.g., Google Translate)
+
+
If the problem persists, please contact support for assistance
+
+
+
+
+ }>
+
+ Contact support
+
+
+
+ {/* [Joshen] For local and staging, allow us to escape the error boundary */}
+ {/* We could actually investigate how to make this available on prod, but without being able to reliably test this, I'm not keen to do it now */}
+ {isProduction ? (
+
+ ) : (
+
+ )}
+
+ >
+ )
+}
diff --git a/apps/studio/components/ui/ErrorBoundary.tsx b/apps/studio/components/ui/ErrorBoundary/ErrorBoundary.tsx
similarity index 100%
rename from apps/studio/components/ui/ErrorBoundary.tsx
rename to apps/studio/components/ui/ErrorBoundary/ErrorBoundary.tsx
diff --git a/apps/studio/components/ui/ErrorBoundary/GlobalErrorBoundaryState.tsx b/apps/studio/components/ui/ErrorBoundary/GlobalErrorBoundaryState.tsx
new file mode 100644
index 00000000000..4efebda3cb8
--- /dev/null
+++ b/apps/studio/components/ui/ErrorBoundary/GlobalErrorBoundaryState.tsx
@@ -0,0 +1,65 @@
+import { isError } from 'lodash'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
+
+import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
+import { ClientSideExceptionHandler } from './ClientSideExceptionHandler'
+import { InsertBeforeRemoveChildErrorHandler } from './InsertBeforeRemoveChildErrorHandler'
+
+export type FallbackProps = {
+ error: unknown
+ resetErrorBoundary: (...args: unknown[]) => void
+}
+
+export const GlobalErrorBoundaryState = ({ error, resetErrorBoundary }: FallbackProps) => {
+ const router = useRouter()
+ const checkIsError = isError(error)
+
+ const largeLogo = useIsFeatureEnabled('branding:large_logo')
+
+ const errorMessage = checkIsError ? error.message : ''
+ const urlMessage = checkIsError ? `Path name: ${router.pathname}\n\n${error?.stack}` : ''
+
+ const isRemoveChildError = checkIsError
+ ? errorMessage.includes("Failed to execute 'removeChild' on 'Node'")
+ : false
+ const isInsertBeforeError = checkIsError
+ ? errorMessage.includes("Failed to execute 'insertBefore' on 'Node'")
+ : false
+
+ // Get Sentry issue ID from error if available
+ const sentryIssueId = (!!error && typeof error === 'object' && (error as any).sentryId) ?? ''
+
+ return (
+
Sorry! A browser extension may have caused an error.
+
+
+
+
+
+ Browser translation tools (like Chrome's built-in Translate) or some third-party browser
+ extensions are known to cause errors when using the Supabase Dashboard.
+
+
+
+ We highly recommend{' '}
+
+ {browser === 'Chrome'
+ ? 'disabling Chrome Translate or certain browser extensions'
+ : 'avoiding the use of browser translation tools or disabling certain extensions'}
+ {' '}
+ while using the Supabase Dashboard to avoid running into this error. Try to refresh the
+ browser to see if it occurs again.
+
- Try to avoid using Google translate or disable certain browser extensions to avoid
- running into the{' '}
-
- {isRemoveChildError
- ? `'removeChild' on 'Node'`
- : isInsertBeforeError
- ? `'insertBefore' on 'Node'`
- : ''}
- {' '}
- error.{' '}
- window.location.reload()}
- >
- Refresh
- {' '}
- the browser to see if occurs again.
-
- router.push('/logout')}
- >
- Sign out
- {' '}
- and sign back in
-
-
-
- Clear your browser storage
- {' '}
- to clean potentially outdated data
-
-
- Disable browser extensions that might modify page content (e.g., Google Translate)
-
-
If the problem persists, please contact support for assistance
-
-
- )}
-
- {!isRemoveChildError && !isInsertBeforeError && (
- }>
-
- Contact support
-
-
- )}
-
- {/* [Joshen] For local and staging, allow us to escape the error boundary */}
- {/* We could actually investigate how to make this available on prod, but without being able to reliably test this, I'm not keen to do it now */}
- {process.env.NEXT_PUBLIC_ENVIRONMENT !== 'prod' ? (
-
- ) : (
-
- )}
-
- {(isRemoveChildError || isInsertBeforeError) && (
-
- Still stuck?
-
- )}
-
-
-
- )
-}
diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx
index 04aac87207a..fb4ae48c14c 100644
--- a/apps/studio/pages/_app.tsx
+++ b/apps/studio/pages/_app.tsx
@@ -48,7 +48,7 @@ import { StudioCommandMenu } from 'components/interfaces/App/CommandMenu'
import { FeaturePreviewContextProvider } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import FeaturePreviewModal from 'components/interfaces/App/FeaturePreview/FeaturePreviewModal'
import { MonacoThemeProvider } from 'components/interfaces/App/MonacoThemeProvider'
-import { GlobalErrorBoundaryState } from 'components/ui/GlobalErrorBoundaryState'
+import { GlobalErrorBoundaryState } from 'components/ui/ErrorBoundary/GlobalErrorBoundaryState'
import { useRootQueryClient } from 'data/query-client'
import { customFont, sourceCodePro } from 'fonts'
import { useCustomContent } from 'hooks/custom-content/useCustomContent'
@@ -143,6 +143,7 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
{appTitle ?? 'Supabase'}
+
{/* [Alaister]: This has to be an inline style tag here and not a separate component due to next/font */}