diff --git a/.changeset/red-bats-chew.md b/.changeset/red-bats-chew.md new file mode 100644 index 000000000..33c9ccefd --- /dev/null +++ b/.changeset/red-bats-chew.md @@ -0,0 +1,5 @@ +--- +'@gitbook/react-contentkit': patch +--- + +Fix rendering of webframe with SSR causing wrong communication between frame and renderer diff --git a/.changeset/shy-buttons-relate.md b/.changeset/shy-buttons-relate.md new file mode 100644 index 000000000..4f1c7585f --- /dev/null +++ b/.changeset/shy-buttons-relate.md @@ -0,0 +1,5 @@ +--- +'gitbook': patch +--- + +Add optional env `GITBOOK_INTEGRATIONS_HOST` to configure the host serving the integrations diff --git a/packages/gitbook/src/components/DocumentView/Integration/IntegrationBlock.tsx b/packages/gitbook/src/components/DocumentView/Integration/IntegrationBlock.tsx index f5d98f712..5278203ef 100644 --- a/packages/gitbook/src/components/DocumentView/Integration/IntegrationBlock.tsx +++ b/packages/gitbook/src/components/DocumentView/Integration/IntegrationBlock.tsx @@ -3,6 +3,7 @@ import { Icon } from '@gitbook/icons'; import { ContentKit, ContentKitOutput, ContentKitServerContext } from '@gitbook/react-contentkit'; import { ignoreAPIError, renderIntegrationUi } from '@/lib/api'; +import { INTEGRATIONS_HOST } from '@/lib/csp'; import { parseMarkdown } from '@/lib/markdown'; import { tcls } from '@/lib/tailwind'; @@ -69,7 +70,7 @@ export async function IntegrationBlock(props: BlockProps { diff --git a/packages/gitbook/src/lib/csp.ts b/packages/gitbook/src/lib/csp.ts index 465a197fe..e883c8f58 100644 --- a/packages/gitbook/src/lib/csp.ts +++ b/packages/gitbook/src/lib/csp.ts @@ -25,6 +25,12 @@ export function createContentSecurityPolicyNonce(): string { return nonce; } +/** + * Hostname serving the integrations. + */ +export const INTEGRATIONS_HOST = + process.env.GITBOOK_INTEGRATIONS_HOST ?? 'integrations.gitbook.com'; + /** * Generate a Content Security Policy header for a space. */ @@ -39,10 +45,10 @@ export function getContentSecurityPolicy(scripts: SpaceIntegrationScript[], nonc // Since I can't get the nonce to work for inline styles, we need to allow unsafe-inline const defaultCSP = ` default-src 'self' ${assetsDomain}; - script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-inline' 'unsafe-eval' ${assetsDomain} https://integrations.gitbook.com https://cdn.iframe.ly; + script-src 'self' 'nonce-${nonce}' 'strict-dynamic' 'unsafe-inline' 'unsafe-eval' ${assetsDomain} https://${INTEGRATIONS_HOST} https://cdn.iframe.ly; style-src 'self' ${assetsDomain} fonts.googleapis.com 'unsafe-inline'; img-src * 'self' blob: data: files.gitbook.com ${assetsDomain} ${iconsAssetsSrc}; - connect-src * 'self' integrations.gitbook.com app.gitbook.com api.gitbook.com srv.buysellads.com ${assetsDomain} ${iconsAssetsSrc}; + connect-src * 'self' ${INTEGRATIONS_HOST} app.gitbook.com api.gitbook.com srv.buysellads.com ${assetsDomain} ${iconsAssetsSrc}; font-src 'self' fonts.gstatic.com ${assetsDomain}; frame-src *; object-src 'none'; diff --git a/packages/react-contentkit/src/ElementWebframe.tsx b/packages/react-contentkit/src/ElementWebframe.tsx index ec7f97477..866c8e8f5 100644 --- a/packages/react-contentkit/src/ElementWebframe.tsx +++ b/packages/react-contentkit/src/ElementWebframe.tsx @@ -10,6 +10,7 @@ import { resolveDynamicBinding } from './dynamic'; export function ElementWebframe(props: ContentKitClientElementProps) { const { element } = props; + const [mounted, setMounted] = React.useState(false); const renderer = useContentKitClientContext(); const iframeRef = React.useRef(null); const [size, setSize] = React.useState<{ @@ -23,10 +24,6 @@ export function ElementWebframe(props: ContentKitClientElementProps { - if (!iframeRef.current) { - return; - } - const target = new URL(element.source.url); // For security reasons, only iframe from our integrations domains are allowed @@ -36,6 +33,10 @@ export function ElementWebframe(props: ContentKitClientElementProps { window.removeEventListener('message', callback); }; @@ -142,26 +148,29 @@ export function ElementWebframe(props: ContentKitClientElementProps -