mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 15:45:13 +00:00
Investigate performance issues with InlineLink.
This commit is contained in:
@@ -4,16 +4,13 @@ import { getNodeFragmentByType } from '@/lib/document';
|
||||
|
||||
import { Blocks } from '../Blocks';
|
||||
import type { InlineProps } from '../Inline';
|
||||
import { Inlines } from '../Inlines';
|
||||
import { AnnotationPopover } from './AnnotationPopover';
|
||||
|
||||
export function Annotation(props: InlineProps<DocumentInlineAnnotation>) {
|
||||
const { inline, context, document, children } = props;
|
||||
|
||||
const fragment = getNodeFragmentByType(inline, 'annotation-body');
|
||||
const content = children ?? (
|
||||
<Inlines document={document} context={context} nodes={inline.nodes} ancestorInlines={[]} />
|
||||
);
|
||||
const content = children;
|
||||
|
||||
if (!fragment) {
|
||||
return <>{content}</>;
|
||||
|
||||
@@ -46,7 +46,7 @@ export interface BlockProps<Block extends DocumentBlock> extends DocumentContext
|
||||
style?: ClassValue;
|
||||
}
|
||||
|
||||
export function Block<T extends DocumentBlock>(props: BlockProps<T>) {
|
||||
export function renderBlock<T extends DocumentBlock>(props: BlockProps<T>) {
|
||||
const { block, style, isEstimatedOffscreen, context } = props;
|
||||
|
||||
const content = (() => {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type { DocumentBlock, JSONDocument } from '@gitbook/api';
|
||||
|
||||
import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
|
||||
import { Block } from './Block';
|
||||
import { renderBlock } from './Block';
|
||||
import type { DocumentContextProps } from './DocumentView';
|
||||
import { isBlockOffscreen } from './utils';
|
||||
|
||||
@@ -25,7 +24,7 @@ export function Blocks<TBlock extends DocumentBlock, Tag extends React.ElementTy
|
||||
|
||||
return (
|
||||
<Tag {...wrapperProps} className={tcls(style)}>
|
||||
<UnwrappedBlocks {...blocksProps} />
|
||||
{renderUnwrappedBlocks(blocksProps)}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
@@ -50,7 +49,9 @@ type UnwrappedBlocksProps<TBlock extends DocumentBlock> = DocumentContextProps &
|
||||
/**
|
||||
* Renders a list of blocks without a wrapper element.
|
||||
*/
|
||||
export function UnwrappedBlocks<TBlock extends DocumentBlock>(props: UnwrappedBlocksProps<TBlock>) {
|
||||
export function renderUnwrappedBlocks<TBlock extends DocumentBlock>(
|
||||
props: UnwrappedBlocksProps<TBlock>
|
||||
) {
|
||||
const { nodes, blockStyle, isOffscreen: defaultIsOffscreen = false, ...contextProps } = props;
|
||||
|
||||
let isOffscreen = defaultIsOffscreen;
|
||||
@@ -63,20 +64,18 @@ export function UnwrappedBlocks<TBlock extends DocumentBlock>(props: UnwrappedBl
|
||||
ancestorBlocks: props.ancestorBlocks,
|
||||
});
|
||||
|
||||
return (
|
||||
<Block
|
||||
key={node.key || `${node.type}-${index}`}
|
||||
block={node}
|
||||
style={[
|
||||
'mx-auto w-full decoration-primary/6',
|
||||
node.data && 'fullWidth' in node.data && node.data.fullWidth
|
||||
? 'max-w-screen-2xl'
|
||||
: 'page-full-width:ml-0 max-w-3xl',
|
||||
blockStyle,
|
||||
]}
|
||||
isEstimatedOffscreen={isOffscreen}
|
||||
{...contextProps}
|
||||
/>
|
||||
);
|
||||
return renderBlock({
|
||||
key: node.key || `${node.type}-${index}`,
|
||||
block: node,
|
||||
style: [
|
||||
'mx-auto w-full decoration-primary/6',
|
||||
node.data && 'fullWidth' in node.data && node.data.fullWidth
|
||||
? 'max-w-screen-2xl'
|
||||
: 'page-full-width:ml-0 max-w-3xl',
|
||||
blockStyle,
|
||||
],
|
||||
isEstimatedOffscreen: isOffscreen,
|
||||
...contextProps,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { getNodeFragmentByName, isNodeEmpty } from '@/lib/document';
|
||||
import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { DocumentContextProps } from './DocumentView';
|
||||
import { Inlines } from './Inlines';
|
||||
|
||||
/**
|
||||
* Wrap a content of a block that has a potential caption.
|
||||
@@ -62,14 +61,6 @@ export function Caption(
|
||||
return (
|
||||
<picture className={tcls('relative', style)}>
|
||||
<div className={tcls(wrapperStyle, 'mx-auto')}>{children}</div>
|
||||
<figcaption className={tcls('text-sm', 'text-center', 'mt-2', 'text-tint')}>
|
||||
<Inlines
|
||||
nodes={captionParagraph.nodes}
|
||||
document={document}
|
||||
context={context}
|
||||
ancestorInlines={[]}
|
||||
/>
|
||||
</figcaption>
|
||||
</picture>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { BlockProps } from '../Block';
|
||||
import { Blocks } from '../Blocks';
|
||||
import { Inlines } from '../Inlines';
|
||||
import { Details } from './Details';
|
||||
|
||||
export function Expandable(props: BlockProps<DocumentBlockExpandable>) {
|
||||
@@ -54,12 +53,6 @@ export function Expandable(props: BlockProps<DocumentBlockExpandable>) {
|
||||
'group-open/expandable:rotate-90'
|
||||
)}
|
||||
/>
|
||||
<Inlines
|
||||
nodes={titleParagraph.nodes}
|
||||
document={document}
|
||||
context={context}
|
||||
ancestorInlines={[]}
|
||||
/>
|
||||
<a
|
||||
href={`#${id}`}
|
||||
aria-label="Direct link to heading"
|
||||
|
||||
@@ -4,7 +4,6 @@ import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { BlockProps } from './Block';
|
||||
import { HashLinkButton, hashLinkButtonWrapperStyles } from './HashLinkButton';
|
||||
import { Inlines } from './Inlines';
|
||||
import { getBlockTextStyle } from './spacing';
|
||||
|
||||
export function Heading(props: BlockProps<DocumentBlockHeading>) {
|
||||
@@ -46,9 +45,7 @@ export function Heading(props: BlockProps<DocumentBlockHeading>) {
|
||||
textStyle.lineHeight,
|
||||
textStyle.marginTop
|
||||
)}
|
||||
>
|
||||
<Inlines {...rest} context={context} nodes={block.nodes} ancestorInlines={[]} />
|
||||
</div>
|
||||
></div>
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Icon, type IconName } from '@gitbook/icons';
|
||||
|
||||
import { type ClassValue, tcls } from '@/lib/tailwind';
|
||||
|
||||
import { Block, type BlockProps } from './Block';
|
||||
import type { BlockProps } from './Block';
|
||||
import { Blocks } from './Blocks';
|
||||
import { getBlockTextStyle } from './spacing';
|
||||
|
||||
@@ -49,17 +49,6 @@ export function Hint(props: BlockProps<DocumentBlockHint>) {
|
||||
className={tcls('size-[1.2em]', 'mt-px', firstLine.lineHeight)}
|
||||
/>
|
||||
</div>
|
||||
{hasHeading ? (
|
||||
<Block
|
||||
style={tcls(
|
||||
'flip-heading-hash p-4 pl-3 text-[1em] *:mt-0',
|
||||
hasHeading ? hintStyle.header : null
|
||||
)}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
{...contextProps}
|
||||
block={firstNode}
|
||||
/>
|
||||
) : null}
|
||||
<Blocks
|
||||
{...contextProps}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Icon } from '@gitbook/icons';
|
||||
import { StyledLink } from '../primitives';
|
||||
import type { InlineProps } from './Inline';
|
||||
import { InlineLinkTooltip } from './InlineLinkTooltip';
|
||||
import { Inlines } from './Inlines';
|
||||
import { renderInlines } from './Inlines';
|
||||
|
||||
export async function InlineLink(props: InlineProps<DocumentInlineLink>) {
|
||||
const { inline, document, context, ancestorInlines } = props;
|
||||
@@ -20,12 +20,12 @@ export async function InlineLink(props: InlineProps<DocumentInlineLink>) {
|
||||
if (!context.contentContext || !resolved) {
|
||||
return (
|
||||
<span title="Broken link" className="underline">
|
||||
<Inlines
|
||||
context={context}
|
||||
document={document}
|
||||
nodes={inline.nodes}
|
||||
ancestorInlines={[...ancestorInlines, inline]}
|
||||
/>
|
||||
{renderInlines({
|
||||
context,
|
||||
document,
|
||||
nodes: inline.nodes,
|
||||
ancestorInlines: [...ancestorInlines, inline],
|
||||
})}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -43,12 +43,12 @@ export async function InlineLink(props: InlineProps<DocumentInlineLink>) {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Inlines
|
||||
context={context}
|
||||
document={document}
|
||||
nodes={inline.nodes}
|
||||
ancestorInlines={[...ancestorInlines, inline]}
|
||||
/>
|
||||
{renderInlines({
|
||||
context,
|
||||
document,
|
||||
nodes: inline.nodes,
|
||||
ancestorInlines: [...ancestorInlines, inline],
|
||||
})}
|
||||
{isExternal ? (
|
||||
<Icon
|
||||
icon="arrow-up-right"
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { DocumentContextProps } from './DocumentView';
|
||||
import { Inline } from './Inline';
|
||||
import { Text } from './Text';
|
||||
|
||||
export function Inlines<T extends DocumentInline | DocumentText>(
|
||||
export function renderInlines<T extends DocumentInline | DocumentText>(
|
||||
props: DocumentContextProps & {
|
||||
/**
|
||||
* Document being rendered.
|
||||
|
||||
@@ -12,7 +12,11 @@ import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { BlockProps } from './Block';
|
||||
import { Blocks } from './Blocks';
|
||||
import { getBlockTextStyle } from './spacing';
|
||||
|
||||
const UNORDERED_STYLE = {
|
||||
'--font-family': 'inherit',
|
||||
fontSize: 'min(1em, 24px)',
|
||||
};
|
||||
|
||||
export function ListItem(props: BlockProps<DocumentBlockListItem>) {
|
||||
const { block, ancestorBlocks, ...contextProps } = props;
|
||||
@@ -25,31 +29,15 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
|
||||
'Invalid parent list type'
|
||||
);
|
||||
|
||||
const blocksElement = (
|
||||
<Blocks
|
||||
{...contextProps}
|
||||
nodes={block.nodes}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
blockStyle={tcls(
|
||||
'min-h-[1lh]',
|
||||
// flip heading hash icon if list item is a heading
|
||||
'flip-heading-hash',
|
||||
// remove margin-top for the first heading in a list
|
||||
'[&:is(h2)>div]:mt-0',
|
||||
'[&:is(h3)>div]:mt-0',
|
||||
'[&:is(h4)>div]:mt-0',
|
||||
// Override the "mx-auto" class from UnwrappedBlocks
|
||||
'mx-0'
|
||||
)}
|
||||
style="flex min-w-0 flex-1 flex-col space-y-2"
|
||||
/>
|
||||
);
|
||||
|
||||
switch (parent.type) {
|
||||
case 'list-tasks':
|
||||
return (
|
||||
<ListItemLI block={block}>
|
||||
<ListItemPrefix block={block}>
|
||||
<li className={tcls('flex items-start')}>
|
||||
<div
|
||||
className={tcls(
|
||||
'mr-1 flex min-h-[1lh] min-w-6 items-center justify-center text-tint'
|
||||
)}
|
||||
>
|
||||
<Checkbox
|
||||
id={block.key!}
|
||||
disabled
|
||||
@@ -57,45 +45,117 @@ export function ListItem(props: BlockProps<DocumentBlockListItem>) {
|
||||
className="relative"
|
||||
size="small"
|
||||
/>
|
||||
</ListItemPrefix>
|
||||
</div>
|
||||
|
||||
<label htmlFor={block.key} className={tcls('flex-1')}>
|
||||
{blocksElement}
|
||||
<Blocks
|
||||
{...contextProps}
|
||||
nodes={block.nodes}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
blockStyle={tcls(
|
||||
'min-h-[1lh]',
|
||||
// flip heading hash icon if list item is a heading
|
||||
'flip-heading-hash',
|
||||
// remove margin-top for the first heading in a list
|
||||
'[&:is(h2)>div]:mt-0',
|
||||
'[&:is(h3)>div]:mt-0',
|
||||
'[&:is(h4)>div]:mt-0',
|
||||
// Override the "mx-auto" class from UnwrappedBlocks
|
||||
'mx-0'
|
||||
)}
|
||||
style="flex min-w-0 flex-1 flex-col space-y-2"
|
||||
/>
|
||||
</label>
|
||||
</ListItemLI>
|
||||
</li>
|
||||
);
|
||||
case 'list-ordered':
|
||||
return (
|
||||
<ListItemLI block={block}>
|
||||
<ListItemPrefix block={block}>
|
||||
<PseudoBefore
|
||||
content={getOrderedListItemPrefixContent({
|
||||
depth: getListItemDepth({ ancestorBlocks, type: parent.type }),
|
||||
block,
|
||||
parent,
|
||||
})}
|
||||
style={{
|
||||
fontSize: 'min(1em, 24px)',
|
||||
}}
|
||||
<li className={tcls('flex items-start')}>
|
||||
<div
|
||||
className={tcls(
|
||||
'mr-1 flex min-h-[1lh] min-w-6 items-center justify-center text-tint'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="before:font-var before:content-[--pseudoBefore--content]"
|
||||
style={
|
||||
{
|
||||
'--pseudoBefore--content': `'${getOrderedListItemPrefixContent({
|
||||
depth: getListItemDepth({
|
||||
ancestorBlocks,
|
||||
type: parent.type,
|
||||
}),
|
||||
block,
|
||||
parent,
|
||||
})}'`,
|
||||
'--font-family': 'inherit',
|
||||
fontSize: 'min(1em, 24px)',
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</ListItemPrefix>
|
||||
{blocksElement}
|
||||
</ListItemLI>
|
||||
</div>
|
||||
<Blocks
|
||||
{...contextProps}
|
||||
nodes={block.nodes}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
blockStyle={tcls(
|
||||
'min-h-[1lh]',
|
||||
// flip heading hash icon if list item is a heading
|
||||
'flip-heading-hash',
|
||||
// remove margin-top for the first heading in a list
|
||||
'[&:is(h2)>div]:mt-0',
|
||||
'[&:is(h3)>div]:mt-0',
|
||||
'[&:is(h4)>div]:mt-0',
|
||||
// Override the "mx-auto" class from UnwrappedBlocks
|
||||
'mx-0'
|
||||
)}
|
||||
style="flex min-w-0 flex-1 flex-col space-y-2"
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
case 'list-unordered':
|
||||
return (
|
||||
<ListItemLI block={block}>
|
||||
<ListItemPrefix block={block}>
|
||||
<PseudoBefore
|
||||
content={getUnorderedListItemsPrefixContent({
|
||||
depth: getListItemDepth({ ancestorBlocks, type: parent.type }),
|
||||
})}
|
||||
fontFamily="Arial"
|
||||
style={{ fontSize: 'min(1.5em, 24px)', lineHeight: 1 }}
|
||||
<li className={tcls('flex items-start')}>
|
||||
<div
|
||||
className={tcls(
|
||||
'mr-1 flex min-h-[1lh] min-w-6 items-center justify-center text-tint'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="before:font-var before:content-[--pseudoBefore--content]"
|
||||
style={
|
||||
{
|
||||
'--pseudoBefore--content': `'${getUnorderedListItemsPrefixContent(
|
||||
{
|
||||
depth: getListItemDepth({
|
||||
ancestorBlocks,
|
||||
type: parent.type,
|
||||
}),
|
||||
}
|
||||
)})}'`,
|
||||
...UNORDERED_STYLE,
|
||||
} as React.CSSProperties
|
||||
}
|
||||
/>
|
||||
</ListItemPrefix>
|
||||
{blocksElement}
|
||||
</ListItemLI>
|
||||
</div>
|
||||
<Blocks
|
||||
{...contextProps}
|
||||
nodes={block.nodes}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
blockStyle={tcls(
|
||||
'min-h-[1lh]',
|
||||
// flip heading hash icon if list item is a heading
|
||||
'flip-heading-hash',
|
||||
// remove margin-top for the first heading in a list
|
||||
'[&:is(h2)>div]:mt-0',
|
||||
'[&:is(h3)>div]:mt-0',
|
||||
'[&:is(h4)>div]:mt-0',
|
||||
// Override the "mx-auto" class from UnwrappedBlocks
|
||||
'mx-0'
|
||||
)}
|
||||
style="flex min-w-0 flex-1 flex-col space-y-2"
|
||||
/>
|
||||
</li>
|
||||
);
|
||||
default:
|
||||
assertNever(parent);
|
||||
@@ -125,26 +185,6 @@ function getListItemDepth(input: {
|
||||
return depth;
|
||||
}
|
||||
|
||||
function ListItemLI(props: { block: DocumentBlockListItem; children: React.ReactNode }) {
|
||||
const textStyle = getBlockTextStyle(props.block);
|
||||
return <li className={tcls(textStyle.lineHeight, 'flex items-start')}>{props.children}</li>;
|
||||
}
|
||||
|
||||
function ListItemPrefix(props: { block: DocumentBlockListItem; children: React.ReactNode }) {
|
||||
const textStyle = getBlockTextStyle(props.block);
|
||||
return (
|
||||
<div
|
||||
className={tcls(
|
||||
textStyle.textSize,
|
||||
textStyle.lineHeight,
|
||||
'mr-1 flex min-h-[1lh] min-w-6 items-center justify-center text-tint'
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getUnorderedListItemsPrefixContent(input: { depth: number }): string {
|
||||
switch (input.depth % 3) {
|
||||
case 0:
|
||||
|
||||
@@ -3,14 +3,18 @@ import type { DocumentBlockParagraph } from '@gitbook/api';
|
||||
import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import type { BlockProps } from './Block';
|
||||
import { Inlines } from './Inlines';
|
||||
import { renderInlines } from './Inlines';
|
||||
|
||||
export function Paragraph(props: BlockProps<DocumentBlockParagraph>) {
|
||||
const { block, style, ...contextProps } = props;
|
||||
|
||||
return (
|
||||
<p className={tcls(style)}>
|
||||
<Inlines {...contextProps} nodes={block.nodes} ancestorInlines={[]} />
|
||||
{renderInlines({
|
||||
...contextProps,
|
||||
nodes: block.nodes,
|
||||
ancestorInlines: [],
|
||||
})}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { resolveContentRef } from '@/lib/references';
|
||||
import type { GitBookSpaceContext } from '@v2/lib/context';
|
||||
import { getDataOrNull } from '@v2/lib/data';
|
||||
import type { BlockProps } from './Block';
|
||||
import { UnwrappedBlocks } from './Blocks';
|
||||
import { renderUnwrappedBlocks } from './Blocks';
|
||||
|
||||
export async function ReusableContent(props: BlockProps<DocumentBlockReusableContent>) {
|
||||
const { block, context, ancestorBlocks } = props;
|
||||
@@ -62,15 +62,13 @@ export async function ReusableContent(props: BlockProps<DocumentBlockReusableCon
|
||||
shareKey: undefined,
|
||||
};
|
||||
|
||||
return (
|
||||
<UnwrappedBlocks
|
||||
nodes={document.nodes}
|
||||
document={document}
|
||||
ancestorBlocks={[...ancestorBlocks, block]}
|
||||
context={{
|
||||
...context,
|
||||
contentContext: reusableContentContext,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
return renderUnwrappedBlocks({
|
||||
nodes: document.nodes,
|
||||
document: document,
|
||||
ancestorBlocks: [...ancestorBlocks, block],
|
||||
context: {
|
||||
...context,
|
||||
contentContext: reusableContentContext,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
import { CookiesToast } from '@/components/Cookies';
|
||||
import { LoadIntegrations } from '@/components/Integrations';
|
||||
import { SpaceLayout } from '@/components/SpaceLayout';
|
||||
import { buildVersion } from '@/lib/build';
|
||||
import { isSiteIndexable } from '@/lib/seo';
|
||||
import { CustomizationThemeMode } from '@gitbook/api';
|
||||
import type { GitBookSiteContext } from '@v2/lib/context';
|
||||
import type { Metadata, Viewport } from 'next';
|
||||
@@ -5,17 +10,9 @@ import { NuqsAdapter } from 'nuqs/adapters/next/app';
|
||||
import React from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
|
||||
import { AdminToolbar } from '@/components/AdminToolbar';
|
||||
import { CookiesToast } from '@/components/Cookies';
|
||||
import { LoadIntegrations } from '@/components/Integrations';
|
||||
import { SpaceLayout } from '@/components/SpaceLayout';
|
||||
import { buildVersion } from '@/lib/build';
|
||||
import { isSiteIndexable } from '@/lib/seo';
|
||||
|
||||
import type { VisitorAuthClaims } from '@/lib/adaptive';
|
||||
import { GITBOOK_API_PUBLIC_URL, GITBOOK_ASSETS_URL, GITBOOK_ICONS_URL } from '@v2/lib/env';
|
||||
import { getResizedImageURL } from '@v2/lib/images';
|
||||
import { ClientContexts } from './ClientContexts';
|
||||
import { RocketLoaderDetector } from './RocketLoaderDetector';
|
||||
|
||||
/**
|
||||
@@ -48,40 +45,30 @@ export async function SiteLayout(props: {
|
||||
|
||||
return (
|
||||
<NuqsAdapter>
|
||||
<ClientContexts
|
||||
nonce={nonce}
|
||||
forcedTheme={
|
||||
forcedTheme ??
|
||||
(customization.themes.toggeable ? undefined : customization.themes.default)
|
||||
}
|
||||
<SpaceLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
<SpaceLayout
|
||||
context={context}
|
||||
withTracking={withTracking}
|
||||
visitorAuthClaims={visitorAuthClaims}
|
||||
>
|
||||
{children}
|
||||
</SpaceLayout>
|
||||
{children}
|
||||
</SpaceLayout>
|
||||
|
||||
{scripts.length > 0 ? (
|
||||
<>
|
||||
<LoadIntegrations />
|
||||
{scripts.map(({ script }) => (
|
||||
<script key={script} async src={script} nonce={nonce} />
|
||||
))}
|
||||
</>
|
||||
) : null}
|
||||
{scripts.length > 0 ? (
|
||||
<>
|
||||
<LoadIntegrations />
|
||||
{scripts.map(({ script }) => (
|
||||
<script key={script} async src={script} nonce={nonce} />
|
||||
))}
|
||||
</>
|
||||
) : null}
|
||||
|
||||
{scripts.some((script) => script.cookies) || customization.privacyPolicy.url ? (
|
||||
<React.Suspense fallback={null}>
|
||||
<CookiesToast privacyPolicy={customization.privacyPolicy.url} />
|
||||
</React.Suspense>
|
||||
) : null}
|
||||
{scripts.some((script) => script.cookies) || customization.privacyPolicy.url ? (
|
||||
<React.Suspense fallback={null}>
|
||||
<CookiesToast privacyPolicy={customization.privacyPolicy.url} />
|
||||
</React.Suspense>
|
||||
) : null}
|
||||
|
||||
<RocketLoaderDetector nonce={nonce} />
|
||||
|
||||
<AdminToolbar context={context} />
|
||||
</ClientContexts>
|
||||
<RocketLoaderDetector nonce={nonce} />
|
||||
</NuqsAdapter>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import { getPagePath } from '@/lib/pages';
|
||||
import { isPageIndexable, isSiteIndexable } from '@/lib/seo';
|
||||
|
||||
import { getResizedImageURL } from '@v2/lib/images';
|
||||
import { PageContextProvider } from '../PageContext';
|
||||
import { PageClientLayout } from './PageClientLayout';
|
||||
import { type PagePathParams, fetchPageData, getPathnameParam } from './fetch';
|
||||
|
||||
@@ -65,7 +64,7 @@ export async function SitePage(props: SitePageProps) {
|
||||
const document = await getPageDocument(context, page);
|
||||
|
||||
return (
|
||||
<PageContextProvider pageId={page.id} spaceId={context.space.id} title={page.title}>
|
||||
<>
|
||||
{withFullPageCover && page.cover ? (
|
||||
<PageCover as="full" page={page} cover={page.cover} context={context} />
|
||||
) : null}
|
||||
@@ -90,7 +89,7 @@ export async function SitePage(props: SitePageProps) {
|
||||
<React.Suspense fallback={null}>
|
||||
<PageClientLayout withSections={withSections} />
|
||||
</React.Suspense>
|
||||
</PageContextProvider>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user