UNPKG

nuxt

Version:

[![Nuxt banner](./.github/assets/banner.png)](https://nuxt.com)

76 lines (75 loc) 2.1 kB
import { defineComponent, getCurrentInstance, onErrorCaptured, ref } from "vue"; import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from "vue/server-renderer"; import { useState } from "../composables/state.js"; import { createBuffer } from "./utils.js"; const NuxtClientFallbackServer = defineComponent({ name: "NuxtClientFallback", inheritAttrs: false, props: { uid: { type: String }, 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; } }, setup(props, ctx) { const vm = getCurrentInstance(); const ssrFailed = ref(false); onErrorCaptured((err) => { useState(`${props.uid}`, () => true); ssrFailed.value = true; ctx.emit("ssr-error", err); return false; }); try { const defaultSlot = ctx.slots.default?.(); const ssrVNodes = createBuffer(); for (let i = 0; i < (defaultSlot?.length || 0); i++) { ssrRenderVNode(ssrVNodes.push, defaultSlot[i], vm); } return { ssrFailed, ssrVNodes }; } catch (ssrError) { useState(`${props.uid}`, () => 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 = ctx.placeholderTag || ctx.fallbackTag; push(`<${tag}${ssrRenderAttrs(ctx.$attrs)}>${content}</${tag}>`); } } else { push("<!--[-->"); push(ctx.ssrVNodes.getBuffer()); push("<!--]-->"); } } }); export default NuxtClientFallbackServer;