-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathindex.tsx
68 lines (62 loc) · 2.11 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { headers } from 'next/headers';
import { QueryEngine } from '@snapwp/query';
import { TemplateHead } from './template-head';
import { TemplateScripts } from './template-scripts';
import Script from 'next/script';
import type { BlockData } from '@snapwp/types';
import type { ReactNode } from 'react';
export type TemplateRendererProps = {
getTemplateData?: ( typeof QueryEngine )[ 'getTemplateData' ];
children: ( editorBlocks: BlockData[] ) => ReactNode;
};
/**
* Renders a full HTML document including the head, body, and scripts.
* Combines custom styles, block content, and scripts into a complete page.
*
* @param props - The props for the component..
* @param props.getTemplateData - A async callback to get template styles and content.
* @param props.children - The block content to render.
*
* @return A complete HTML document structure.
*/
export async function TemplateRenderer( {
getTemplateData = QueryEngine.getTemplateData,
children,
}: TemplateRendererProps ): Promise< ReactNode > {
const headerList = await headers(); // headers() returns a Promise from NextJS 19.
const pathname = headerList.get( 'x-current-path' );
const { editorBlocks, bodyClasses, stylesheets, scripts, scriptModules } =
await getTemplateData( pathname || '/' );
if ( ! editorBlocks?.length ) {
throw new Error(
'Error: Unable to render content. `editorBlocks` is not defined. This may be due to missing template data or an issue with data fetching.'
);
}
// @todo: Script modules should load before styles to handle ordering properly
return (
<>
<TemplateHead stylesheets={ stylesheets } />
<TemplateScripts
scripts={ scripts }
scriptModules={ scriptModules }
>
<main>
<div className="wp-site-blocks">
{ children( editorBlocks ) }
</div>
</main>
</TemplateScripts>
{ /* Hot Fix for adding classes to the body outside the root layout */ }
<Script
strategy="beforeInteractive"
dangerouslySetInnerHTML={ {
__html: `
${ JSON.stringify( bodyClasses ) }.forEach( ( c ) => {
document.body.classList.add( c );
} );
`,
} }
/>
</>
);
}