UNPKG

@tanstack/vue-router

Version:

Modern and scalable routing for Vue applications

49 lines 2.1 kB
import * as Vue from 'vue'; import { renderToString, renderToWebStream } from 'vue/server-renderer'; import { isbot } from 'isbot'; import { createSsrStreamResponse, getSsrStatus, transformHtmlStringWithRouter, transformReadableStreamWithRouter, waitForRequest, } from '@tanstack/router-core/ssr/server'; const DOCTYPE = new TextEncoder().encode('<!DOCTYPE html>'); /** The router transport needs `<html>` as the outer root, not a fragment. */ export function warnUnlessHtmlRoot(html) { if (process.env.NODE_ENV !== 'production' && !html.startsWith('<html')) { console.warn('TanStack Router: the Vue root component must render <html> as its outer element. A fragment or array root breaks streamed hydration scripts.'); } } export const renderRouterToStream = async ({ request, router, responseHeaders, App, }) => { const signal = request.signal; if (signal.aborted) { router.serverSsr?.cleanup(); throw signal.reason; } try { const app = Vue.createSSRApp(App, { router }); if (isbot(request.headers.get('User-Agent'))) { let fullHtml = await waitForRequest(renderToString(app), signal); warnUnlessHtmlRoot(fullHtml); fullHtml = await transformHtmlStringWithRouter(router, fullHtml, { signal, }); return new Response(fullHtml, { status: getSsrStatus(router), headers: responseHeaders, }); } const readable = renderToWebStream(app).pipeThrough(new TransformStream({ start(controller) { controller.enqueue(DOCTYPE); }, })); const responseStream = transformReadableStreamWithRouter(router, readable, { signal, }); return createSsrStreamResponse(router, new Response(responseStream, { status: getSsrStatus(router), headers: responseHeaders, })); } catch (error) { router.serverSsr?.cleanup(); throw error; } }; //# sourceMappingURL=renderRouterToStream.jsx.map