@progress/sitefinity-nextjs-sdk
Version:
Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.
62 lines (61 loc) • 3.43 kB
JavaScript
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
import { RootUrlService } from '../rest-sdk/root-url.service';
import { PageScriptLocation } from '../rest-sdk/dto/scripts';
import Script from 'next/script';
const TrackingConsentDialogScriptAttributeName = 'data-sf-tracking-consent-dialog-script';
const TrackingConsentScriptAttributeName = 'data-sf-tracking-consent-script';
const InsightClientScriptUrl = 'cdn.insight.sitefinity.com/sdk/sitefinity-insight-client';
export function RenderPageScripts({ layout, scriptLocation }) {
return (_jsx(_Fragment, { children: layout.Scripts.filter(x => x.Location === scriptLocation).map((script, i) => {
if (script.Source) {
if (script.Source[0] === '/') {
script.Source = RootUrlService.getClientCmsUrl() + script.Source;
}
}
const scriptAttributes = Object.fromEntries(script.Attributes.map(x => [x.Key.toLocaleLowerCase(), x.Value]));
if (isScirptForHeadTag(script)) {
return RenderPageHeadScript(script, scriptAttributes, i);
}
return RenderPageBodyScript(script, scriptAttributes, i);
}) }));
}
function RenderPageHeadScript(script, scriptAttributes, index) {
if (script.IsNoScript) {
return _jsx("noscript", { ...scriptAttributes, dangerouslySetInnerHTML: { __html: script.Value || '' } }, index);
}
else {
if (script.Source) {
// eslint-disable-next-line @next/next/no-before-interactive-script-outside-document
return _jsx(Script, { ...scriptAttributes, src: script.Source, strategy: "beforeInteractive" }, index);
}
// eslint-disable-next-line @next/next/no-before-interactive-script-outside-document
return _jsx(Script, { ...scriptAttributes, dangerouslySetInnerHTML: { __html: script.Value }, strategy: "beforeInteractive" }, index);
}
}
function RenderPageBodyScript(script, scriptAttributes, index) {
if (script.IsNoScript) {
return _jsx("noscript", { ...scriptAttributes, dangerouslySetInnerHTML: { __html: script.Value || '' } }, index);
}
else {
if (script.Source) {
return _jsx("script", { ...scriptAttributes, src: script.Source, defer: true }, index);
}
return _jsx("script", { ...scriptAttributes, dangerouslySetInnerHTML: { __html: script.Value }, defer: true }, index);
}
}
function isScirptForHeadTag(script) {
// HACK: The insight script cannot be placed in body tag because of nextjs error related to page hydration and
// difference of what is rendered on the server as script tags and what the insight one additionaly adds in the HTML
// when it loads. The link below describes the error:
// https://nextjs.org/docs/messages/react-hydration-error
const isInsightScript = script.Source && script.Source.includes(InsightClientScriptUrl);
if (isInsightScript) {
return true;
}
// HACK: The Tracking Consent Scripts should be loaded in the <body> instead of the <head> tag because they do not work properly otherwise
const isTrackingConsentScript = script.Attributes.find(attr => attr.Key === TrackingConsentDialogScriptAttributeName || attr.Key === TrackingConsentScriptAttributeName);
if (isTrackingConsentScript) {
return false;
}
return script.Location === PageScriptLocation.Head;
}