Fix front component crash on unknown elements (#22455)
## What Front components are third-party React components rendered on the host via remote-dom against an allow-list of elements. Today the host renderer throws on any element tag it has no component for (e.g. a raw tag produced by `innerHTML`), and there is no error boundary, so a single unknown element crashes the whole widget. This wraps the component registry with a fallback: - a raw tag that has an allow-listed `html-*` equivalent is routed to that safe wrapper (so a raw `iframe` renders through the existing sandbox-forcing renderer instead of being dropped), - tags with no safe renderer (`script`, `object`, `embed`, `link`, `meta`, `base`, `noscript`, `style`) render nothing, - any other unknown tag renders children only. `RemoteRootRenderer` is also wrapped in an error boundary that fails closed to the existing error panel, so a render error can no longer take down the host. ## Notes The host allow-list remains the single rendering gate. This is the first hardening step of a broader effort to widen the DOM/Web API surface available to front components; it is self-contained and does not change behavior for components that only use allow-listed elements. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22455?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
+16
-4
@@ -12,11 +12,16 @@ import {
|
||||
RemoteRootRenderer,
|
||||
} from '@remote-dom/react/host';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ThemeProvider } from 'twenty-ui/theme-constants';
|
||||
import { FrontComponentWorkerEffect } from '../../remote/components/FrontComponentWorkerEffect';
|
||||
import { componentRegistry } from '../generated/host-component-registry';
|
||||
import { createFallbackComponentRegistry } from '../utils/createFallbackComponentRegistry';
|
||||
|
||||
const fallbackComponentRegistry =
|
||||
createFallbackComponentRegistry(componentRegistry);
|
||||
|
||||
type FrontComponentContentProps = {
|
||||
componentUrl: string;
|
||||
@@ -128,10 +133,17 @@ export const FrontComponentRenderer = ({
|
||||
|
||||
{isDefined(receiver) && isExecutionContextInitialized && (
|
||||
<ThemeProvider colorScheme={colorScheme}>
|
||||
<RemoteRootRenderer
|
||||
receiver={receiver}
|
||||
components={componentRegistry}
|
||||
/>
|
||||
<ErrorBoundary
|
||||
onError={setError}
|
||||
onReset={() => setError(null)}
|
||||
resetKeys={[componentUrl]}
|
||||
fallbackRender={() => null}
|
||||
>
|
||||
<RemoteRootRenderer
|
||||
receiver={receiver}
|
||||
components={fallbackComponentRegistry}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
</ThemeProvider>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user