iles
Version:
Vite & Vue powered static site generator with partial hydration
34 lines (33 loc) • 1.49 kB
JavaScript
import { h, getCurrentInstance, createApp, createSSRApp, ssrContextKey, withCtx } from 'vue';
const newApp = import.meta.env.SSR ? createApp : createSSRApp;
export function useVueRenderer() {
return withCtx((async (content) => {
if (!content)
return '';
// Obtain the app context of the current app to enable nested renders.
const { app: _, provides: appProvides, ...appContext } = getCurrentInstance()?.appContext || {};
// @ts-ignore
const { [ssrContextKey]: ssrContext, ...provides } = appProvides;
// Coerce the content to an array of vnodes.
if (isComponent(content) || isAsyncComponent(content))
content = h(content);
else if (isFunction(content))
content = await content();
const nodes = Array.isArray(content) ? content : [content];
// Initialize a new application that returns the specified nodes.
const proxyApp = newApp({ render: () => nodes });
// Set the external app context to the temporary app.
Object.assign(proxyApp._context, { ...appContext, provides });
const { renderToString } = await import('vue/server-renderer');
return await renderToString(proxyApp, ssrContext);
}), getCurrentInstance());
}
function isFunction(val) {
return typeof val === 'function';
}
function isComponent(val) {
return isFunction(val.render);
}
function isAsyncComponent(val) {
return Boolean(val?.__asyncLoader);
}