forked from nuxt/nuxt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
client-fallback.server.ts
79 lines (73 loc) · 2.06 KB
/
client-fallback.server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { defineComponent, getCurrentInstance, onErrorCaptured, ref } from 'vue'
import { ssrRenderAttrs, ssrRenderSlot, ssrRenderVNode } from 'vue/server-renderer'
import { useState } from '../composables/state'
import { createBuffer } from './utils'
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
},
strategy: {
type: String as () => 'default'|'keep-fallback',
default: () => 'default'
}
},
emits: ['ssr-error'],
setup (props, ctx) {
const vm = getCurrentInstance()
const ssrFailed = ref(false)
onErrorCaptured(() => {
useState(`${props.uid}`, () => true)
ssrFailed.value = true
ctx.emit('ssr-error')
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 {
// catch in dev
useState(`${props.uid}`, () => true)
ctx.emit('ssr-error')
return { ssrFailed: true, ssrVNodes: [] }
}
},
ssrRender (ctx: any, push: any, parent: any) {
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 Fragment markup
push('<!--[-->')
push(ctx.ssrVNodes.getBuffer())
push('<!--]-->')
}
}
})
export default NuxtClientFallbackServer