import { InlineScriptErrorGuard, UIDLUtils } from '@teleporthq/teleport-shared' import { wrapBodyCustomCode } from './body-code/body-code-component' import { ASTUtils, ASTBuilders } from '@teleporthq/teleport-plugin-common' import * as types from '@babel/types' import { ProjectUIDL, ChunkDefinition, EntryFileOptions, FileType, ChunkType, FrameWorkConfigOptions, } from '@teleporthq/teleport-types' export const createDocumentFileChunks = (uidl: ProjectUIDL, options: EntryFileOptions) => { const { meta, assets, manifest, customCode } = uidl.globals const htmlNode = ASTBuilders.createJSXTag('Html') // When i18n is configured, Next.js automatically sets the lang attribute // on based on the current route locale, so we skip it here. if (!uidl.internationalization) { const defaultLang = uidl.globals.settings.language if (defaultLang) { ASTUtils.addAttributeToJSXTag(htmlNode, 'lang', defaultLang) } } addDirectionAttribute(htmlNode, uidl) const headNode = ASTBuilders.createJSXTag('Head') const bodyNode = ASTBuilders.createJSXTag('body') const mainNode = ASTBuilders.createJSXTag('Main') const nextScriptNode = ASTBuilders.createJSXTag('NextScript') ASTUtils.addChildJSXTag(bodyNode, mainNode) ASTUtils.addChildJSXTag(bodyNode, nextScriptNode) ASTUtils.addChildJSXTag(htmlNode, headNode) ASTUtils.addChildJSXTag(htmlNode, bodyNode) // First in , ahead of every script it guards. if (InlineScriptErrorGuard.documentRunsProjectScripts(uidl.globals)) { const guardTag = ASTBuilders.createJSXTag('script') ASTUtils.addAttributeToJSXTag(guardTag, 'dangerouslySetInnerHTML', { __html: InlineScriptErrorGuard.INLINE_SCRIPT_ERROR_GUARD, }) ASTUtils.addChildJSXTag(headNode, guardTag) } // NOTE: Title is added in per page, not in the layout file if (manifest) { const linkTag = ASTBuilders.createJSXTag('link') ASTUtils.addAttributeToJSXTag(linkTag, 'rel', 'manifest') ASTUtils.addAttributeToJSXTag( linkTag, 'href', UIDLUtils.prefixAssetsPath(`/manifest.json`, options.assets) ) ASTUtils.addChildJSXTag(headNode, linkTag) } meta.forEach((metaItem) => { // Skip viewport meta tags in _document.js — Next.js requires them in _app.js via next/head if (metaItem.name === 'viewport') { return } const metaTag = ASTBuilders.createJSXTag('meta') Object.keys(metaItem).forEach((key) => { const metaValue = UIDLUtils.prefixAssetsPath(metaItem[key], options.assets) ASTUtils.addAttributeToJSXTag(metaTag, key, metaValue) }) ASTUtils.addChildJSXTag(headNode, metaTag) }) ASTBuilders.appendAssetsAST(assets, options, headNode, bodyNode) if (customCode?.head) { // This is a workaround for inserting