/* eslint-disable @next/next/google-font-display */
import React, { type JSX } from 'react';
import type { DocumentContext, DocumentInitialProps } from 'next/document';
import Document, { Head, Html, Main, NextScript } from 'next/document';
import type { Locale } from '@growi/core/dist/interfaces';
import type { GrowiPluginResourceEntries } from '~/features/growi-plugin/server/services';
import type { CrowiRequest } from '~/interfaces/crowi-request';
import loggerFactory from '~/utils/logger';
import { getLocaleAtServerSide } from './utils/commons';
const logger = loggerFactory('growi:page:_document');
type HeadersForGrowiPluginProps = {
pluginResourceEntries: GrowiPluginResourceEntries;
};
const HeadersForGrowiPlugin = (
props: HeadersForGrowiPluginProps,
): JSX.Element => {
const { pluginResourceEntries } = props;
return (
<>
{pluginResourceEntries.map(([installedPath, href]) => {
if (href.endsWith('.js')) {
// eslint-disable-next-line @next/next/no-sync-scripts
return (
);
}
if (href.endsWith('.css')) {
// eslint-disable-next-line @next/next/no-sync-scripts
return (
);
}
return <>>;
})}
>
);
};
interface GrowiDocumentProps {
themeHref: string;
customScript: string | null;
customCss: string | null;
customNoscript: string | null;
pluginResourceEntries: GrowiPluginResourceEntries;
locale: Locale;
}
declare type GrowiDocumentInitialProps = DocumentInitialProps &
GrowiDocumentProps;
class GrowiDocument extends Document {
static override async getInitialProps(
ctx: DocumentContext,
): Promise {
const initialProps: DocumentInitialProps =
await Document.getInitialProps(ctx);
const req = ctx.req as CrowiRequest;
const { crowi } = req;
const { customizeService } = crowi;
const { themeHref } = customizeService;
const customScript: string | null = customizeService.getCustomScript();
const customCss: string | null = customizeService.getCustomCss();
const customNoscript: string | null = customizeService.getCustomNoscript();
// retrieve plugin manifests
const growiPluginService = await import(
'~/features/growi-plugin/server/services'
).then((mod) => mod.growiPluginService);
const pluginResourceEntries =
await growiPluginService.retrieveAllPluginResourceEntries();
const locale = getLocaleAtServerSide(req);
return {
...initialProps,
themeHref,
customScript,
customCss,
customNoscript,
pluginResourceEntries,
locale,
};
}
renderCustomScript(customScript: string | null): JSX.Element {
if (customScript == null || customScript.length === 0) {
return <>>;
}
return (
);
}
renderCustomCss(customCss: string | null): JSX.Element {
if (customCss == null || customCss.length === 0) {
return <>>;
}
// biome-ignore lint/security/noDangerouslySetInnerHtml: ignore
return ;
}
renderCustomNoscript(customNoscript: string | null): JSX.Element {
if (customNoscript == null || customNoscript.length === 0) {
return <>>;
}
// biome-ignore lint/security/noDangerouslySetInnerHtml: ignore
return ;
}
override render(): JSX.Element {
const {
customCss,
customScript,
customNoscript,
themeHref,
pluginResourceEntries,
locale,
} = this.props;
return (
{this.renderCustomScript(customScript)}
{this.renderCustomCss(customCss)}
{this.renderCustomNoscript(customNoscript)}
);
}
}
export default GrowiDocument;