UNPKG

vike

Version:

The Framework *You* Control - Next.js & Nuxt alternative for unprecedented flexibility and dependability.

81 lines (80 loc) 4.15 kB
export { renderPageAlreadyRouted }; export { prerenderPage }; import { getErrorPageId } from '../../../shared/error-page.js'; import { getHtmlString } from '../html/renderHtml.js'; import { assert, assertUsage, augmentType, hasProp, objectAssign } from '../utils.js'; import { getPageContextClientSerialized } from '../html/serializeContext.js'; import { createHttpResponsePage, createHttpResponsePageContextJson } from './createHttpResponse.js'; import { loadPageConfigsLazyServerSideAndExecHook, } from './loadPageConfigsLazyServerSide.js'; import { execHookOnRenderHtml } from './execHookOnRenderHtml.js'; import { execHookDataAndOnBeforeRender } from './execHookDataAndOnBeforeRender.js'; import { logRuntimeError } from '../loggerRuntime.js'; import { isNewError } from './isNewError.js'; import { preparePageContextForPublicUsageServer } from './preparePageContextForPublicUsageServer.js'; import { execHookGuard } from '../../../shared/route/execHookGuard.js'; import pc from '@brillout/picocolors'; import { isServerSideError } from '../../../shared/misc/isServerSideError.js'; async function renderPageAlreadyRouted(pageContext) { // pageContext.pageId can either be the: // - ID of the page matching the routing, or the // - ID of the error page `_error.page.js`. assert(hasProp(pageContext, 'pageId', 'string')); const isError = pageContext.is404 || !!pageContext.errorWhileRendering; assert(isError === (pageContext.pageId === getErrorPageId(pageContext._globalContext._pageFilesAll, pageContext._globalContext._pageConfigs))); augmentType(pageContext, await loadPageConfigsLazyServerSideAndExecHook(pageContext)); if (!isError) { await execHookGuard(pageContext, (pageContext) => preparePageContextForPublicUsageServer(pageContext)); } if (!isError) { await execHookDataAndOnBeforeRender(pageContext); } else { try { await execHookDataAndOnBeforeRender(pageContext); } catch (err) { if (isNewError(err, pageContext.errorWhileRendering)) { logRuntimeError(err, pageContext._httpRequestId); } } } if (pageContext.isClientSideNavigation) { if (isError) { objectAssign(pageContext, { [isServerSideError]: true }); } const pageContextSerialized = getPageContextClientSerialized(pageContext); const httpResponse = await createHttpResponsePageContextJson(pageContextSerialized); objectAssign(pageContext, { httpResponse }); return pageContext; } const renderHookResult = await execHookOnRenderHtml(pageContext); const { htmlRender, renderHook } = renderHookResult; const httpResponse = await createHttpResponsePage(htmlRender, renderHook, pageContext); objectAssign(pageContext, { httpResponse }); return pageContext; } async function prerenderPage(pageContext) { objectAssign(pageContext, { isClientSideNavigation: false, _urlHandler: null, }); /* Should we execute the guard() hook upon pre-rendering? Is there a use case for this? * - It isn't trivial to implement, as it requires to duplicate / factor out the isAbortError() handling await execHookGuard(pageContext, (pageContext) => preparePageContextForPublicUsageServer(pageContext)) */ await execHookDataAndOnBeforeRender(pageContext); const { htmlRender, renderHook } = await execHookOnRenderHtml(pageContext); assertUsage(htmlRender !== null, `Cannot pre-render ${pc.cyan(pageContext.urlOriginal)} because the ${renderHook.hookName}() hook defined by ${renderHook.hookFilePath} didn't return an HTML string.`); assert(pageContext.isClientSideNavigation === false); const documentHtml = await getHtmlString(htmlRender); assert(typeof documentHtml === 'string'); if (!pageContext._usesClientRouter) { return { documentHtml, pageContextSerialized: null, pageContext }; } else { const pageContextSerialized = getPageContextClientSerialized(pageContext); return { documentHtml, pageContextSerialized, pageContext }; } }