UNPKG

nuxt

Version:

Nuxt is a free and open-source framework with an intuitive and extendable way to create type-safe, performant and production-grade full-stack web applications and websites with Vue.js.

78 lines (77 loc) 2.37 kB
import { renderDiagnostics } from "../diagnostics/render.js"; import { createBuffer, sanitizeTag } from "./utils.js"; import { useState } from "../composables/state.js"; import { defineComponent, getCurrentInstance, onErrorCaptured, shallowRef, useId } from "vue"; import { isPromise } from "@vue/shared"; import { ssrInterpolate, ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from "vue/server-renderer"; //#region src/app/components/client-fallback.server.ts const NuxtClientFallbackServer = defineComponent({ name: "NuxtClientFallback", inheritAttrs: false, props: { fallbackTag: { type: String, default: () => "div" }, fallback: { type: String, default: () => "" }, placeholder: { type: String }, placeholderTag: { type: String }, keepFallback: { type: Boolean, default: () => false } }, emits: { "ssr-error"(_error) { return true; } }, async setup(_, ctx) { const vm = getCurrentInstance(); const ssrFailed = shallowRef(false); const error = useState(useId()); onErrorCaptured((err) => { error.value = true; ssrFailed.value = true; ctx.emit("ssr-error", err); return false; }); try { const defaultSlot = ctx.slots.default?.(); const ssrVNodes = createBuffer(); if (defaultSlot) for (let i = 0; i < defaultSlot.length; i++) ssrRenderVNode(ssrVNodes.push, defaultSlot[i], vm); const buffer = ssrVNodes.getBuffer(); if (buffer.hasAsync) await Promise.all(buffer.flat(Infinity).filter(isPromise)); return { ssrFailed, ssrVNodes }; } catch (ssrError) { if (import.meta.dev) renderDiagnostics.NUXT_E4006({ cause: ssrError }); error.value = true; ctx.emit("ssr-error", ssrError); return { ssrFailed: true, ssrVNodes: [] }; } }, ssrRender(ctx, push, parent) { if (ctx.ssrFailed) { const { fallback, placeholder } = ctx.$slots; if (fallback || placeholder) ssrRenderSlot(ctx.$slots, fallback ? "fallback" : "placeholder", {}, null, push, parent); else { const content = ctx.placeholder || ctx.fallback; const tag = sanitizeTag(ctx.placeholderTag || ctx.fallbackTag, "div"); push(`<${tag}${ssrRenderAttrs(ctx.$attrs)}>${ssrInterpolate(content)}</${tag}>`); } } else { push("<!--[-->"); push(ctx.ssrVNodes.getBuffer()); push("<!--]-->"); } } }); //#endregion export { NuxtClientFallbackServer as default };