Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/teleport-ssr-hydration.md
1---2title: Handle Teleport SSR Hydration Carefully3impact: HIGH4impactDescription: Teleported content causes hydration mismatches in SSR/SSG applications5type: gotcha6tags: [vue3, teleport, ssr, nuxt, hydration]7---89# Handle Teleport SSR Hydration Carefully1011**Impact: HIGH** - Teleports require special handling during SSR. The teleported content is not part of the server-rendered HTML string, causing hydration mismatches that can break the application or cause content to disappear.1213This is a critical issue for Nuxt, Quasar SSR, and custom Vue SSR setups.1415## Task Checklist1617- [ ] Wrap Teleport in `<ClientOnly>` component (Nuxt) for client-only rendering18- [ ] Use conditional rendering based on mount state for non-Nuxt SSR19- [ ] Use `data-allow-mismatch` attribute in Vue 3.5+ when intentional20- [ ] Test SSR applications thoroughly for hydration issues2122**Problem - SSR Hydration Mismatch:**23```vue24<template>25<!-- Server renders nothing for teleported content -->26<!-- Client expects teleported content at #modals -->27<!-- = Hydration mismatch -->28<Teleport to="#modals">29<div v-if="showModal" class="modal">30Modal content31</div>32</Teleport>33</template>34```3536Common error messages:37```38[Vue warn]: Hydration children mismatch in <div>:39server rendered element contains fewer child nodes than client vdom.40```4142**Solution 1 - Nuxt ClientOnly:**43```vue44<template>45<button @click="showModal = true">Open Modal</button>4647<!-- Only render on client, avoiding SSR -->48<ClientOnly>49<Teleport to="body">50<div v-if="showModal" class="modal">51Modal content52</div>53</Teleport>54</ClientOnly>55</template>56```5758**Solution 2 - Manual Client Detection:**59```vue60<template>61<button @click="showModal = true">Open Modal</button>6263<!-- Only render after component mounts on client -->64<Teleport v-if="isMounted" to="body">65<div v-if="showModal" class="modal">66Modal content67</div>68</Teleport>69</template>7071<script setup>72import { ref, onMounted } from 'vue'7374const showModal = ref(false)75const isMounted = ref(false)7677onMounted(() => {78isMounted.value = true79})80</script>81```8283**Solution 3 - Vue 3.5+ data-allow-mismatch:**84```vue85<template>86<!-- Suppress hydration warnings for intentional mismatches -->87<div data-allow-mismatch>88<Teleport to="body">89<div v-if="showModal" class="modal">90Modal content91</div>92</Teleport>93</div>94</template>95```9697## SSR with Multiple Teleports9899Multiple teleports to the same target can cause additional hydration issues:100101```vue102<!-- Parent.vue -->103<template>104<!-- First teleport -->105<Teleport to="#modals">106<NotificationBanner />107</Teleport>108109<ChildComponent />110</template>111112<!-- ChildComponent.vue -->113<template>114<!-- Second teleport to same target - order matters! -->115<Teleport to="#modals">116<Modal />117</Teleport>118</template>119```120121For SSR, ensure consistent ordering or wrap each in `ClientOnly`.122123## Element Plus and UI Library SSR124125Many UI libraries use Teleport internally. Element Plus components that use Teleport include:126- ElDialog127- ElDrawer128- ElTooltip129- ElDropdown130- ElSelect131- ElDatePicker132133```vue134<template>135<!-- These need special SSR handling -->136<ClientOnly>137<ElDialog v-model="visible">138Dialog content139</ElDialog>140</ClientOnly>141</template>142```143144## Known Vue Issues145146- Disabled teleports in fragments can cause hydration mismatches (Vue issue #6152)147- Nested teleports may cause app to break on hydration (Vue issue #5242)148149## Reference150- [Vue.js SSR - Teleports](https://vuejs.org/guide/scaling-up/ssr.html#teleports)151- [Element Plus SSR Guide](https://element-plus.org/en-US/guide/ssr.html)152- [Nuxt ClientOnly Component](https://nuxt.com/docs/api/components/client-only)153