const fs = require("fs"); const path = require("path"); const React = require("react"); const ReactDOMServer = require("react-dom/server"); const { StaticRouter } = require("react-router"); const { CacheProvider } = require("@emotion/react"); const { ThemeProvider } = require("@mui/material/styles"); const createEmotionCache = require("../createEmotionCache.js").default; const theme = require("../src/theme.js").default; const createEmotionServer = require("@emotion/server/create-instance").default; const renderPage = ( component, location, filename, description, metaTags = "", needsRouter = false, config, suppressLogs = false ) => { const { isProduction, outputDir, globalCss, globalCssCollection, webpackEntrypoints, } = config; const { writeCombinedCssFile, optimizeCss } = require("./utils.cjs"); // @note Set prerender fallback flag in global environment for CategoryBox during SSR if (typeof global !== "undefined" && global.window) { global.window.__PRERENDER_FALLBACK__ = { path: location, timestamp: Date.now() }; } // Create fresh Emotion cache for each page const cache = createEmotionCache(); const { extractCriticalToChunks } = createEmotionServer(cache); const wrappedComponent = needsRouter ? React.createElement(StaticRouter, { location: location }, component) : component; const pageElement = React.createElement( CacheProvider, { value: cache }, React.createElement(ThemeProvider, { theme: theme }, wrappedComponent) ); let renderedMarkup; try { renderedMarkup = ReactDOMServer.renderToString(pageElement); const emotionChunks = extractCriticalToChunks(renderedMarkup); // Collect CSS from this page if (emotionChunks.styles.length > 0) { const oldSize = globalCssCollection.size; emotionChunks.styles.forEach((style) => { if (style.css) { globalCssCollection.add(style.css); } }); // Check if new styles were added if (globalCssCollection.size > oldSize) { // Write CSS file immediately when new styles are added writeCombinedCssFile(globalCssCollection, outputDir); } } } catch (error) { console.error(`❌ Rendering failed for ${filename}:`, error); return false; } // Use appropriate template path based on mode // In production, use a clean template file, not the already-rendered index.html const templatePath = isProduction ? path.resolve(__dirname, "..", "dist", "index_template.html") : path.resolve(__dirname, "..", "public", "index.html"); let template = fs.readFileSync(templatePath, "utf8"); // Build CSS and JS tags with optimized CSS loading let additionalTags = ""; let inlinedCss = ""; if (isProduction) { // Check if scripts are already present in template to avoid duplication const existingScripts = template.match(/`; } }); } else { // In development, try to inline prerender CSS as well try { const prerenderCssPath = path.resolve(__dirname, "..", outputDir, "prerender.css"); if (fs.existsSync(prerenderCssPath)) { const prerenderCssContent = fs.readFileSync(prerenderCssPath, "utf8"); const optimizedCss = optimizeCss(prerenderCssContent); inlinedCss += optimizedCss; if (!suppressLogs) console.log(` ✅ Inlined prerender CSS in development (${Math.round(optimizedCss.length / 1024)}KB)`); } else { // Fallback to external loading additionalTags += ``; } } catch (error) { // Fallback to external loading additionalTags += ``; } } // Create script to save prerendered content to window object for fallback use const prerenderFallbackScript = ` `; // @note Create script to populate window.productCache with ONLY the static category tree let productCacheScript = ''; if (typeof global !== "undefined" && global.window && global.window.productCache) { // Only include the static categoryTree_209, not any dynamic data that gets added during rendering const staticCache = {}; if (global.window.productCache.categoryTree_209) { staticCache.categoryTree_209 = global.window.productCache.categoryTree_209; } const staticCacheData = JSON.stringify(staticCache); productCacheScript = ` `; } // Combine all CSS (global + inlined) into a single optimized style tag const combinedCss = globalCss + (inlinedCss ? '\n' + inlinedCss : ''); const combinedCssTag = combinedCss ? `` : ''; // Add resource hints for better performance const resourceHints = ` `; template = template.replace( "", `${resourceHints}${combinedCssTag}${additionalTags}${metaTags}${prerenderFallbackScript}${productCacheScript}` ); const rootDivRegex = /