nuxt
Version:
78 lines (77 loc) • 2.37 kB
JavaScript
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 };