Suggest an editImprove this articleRefine the answer for “How to add fallback content for slots in Vue?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Slot fallback content** is the template inside `<slot>` tags that renders when the parent passes no content for that slot. ```vue <template> <button> <slot>Click me</slot> </button> </template> <Button /> <!-- Shows: Click me --> <Button>Save</Button> <!-- Shows: Save --> ``` **Key point:** parent content fully replaces the fallback, no merging.Shown above the full answer for quick recall.Answer (EN)Image**Fallback content** for a Vue slot is the template placed inside `<slot>` tags that renders when the parent component passes no content for that slot. ## Theory ### TL;DR - Think of it like a mail slot in an apartment door: the fallback is the "No mail today" sign that shows when nothing gets delivered - Place any template content inside `<slot>` tags and Vue treats it as the default - Parent-provided content fully replaces the fallback. No merging happens - Works with both default and named slots - Use it for optional UI sections: empty states, default headers, generic alert messages ### Quick example ```vue <!-- Button.vue --> <template> <button class="btn"> <slot>Click me</slot> <!-- fallback label --> </button> </template> <!-- No content passed: renders "Click me" --> <Button /> <!-- Custom content passed: renders "Save" --> <Button>Save</Button> ``` The child defines what to show when the parent stays quiet. The parent can override it, but doesn't have to. ### How Vue picks what to render Vue checks whether the parent provided content for a given slot. If yes, that content renders. If not, the slot's inner template takes over. There's no blending: one wins, the other disappears entirely. This happens at the component's mounting phase. The template compiler generates a conditional check: if `slots.default` exists (or `slots.header` for named slots), use it; otherwise render the fallback children. No extra runtime cost beyond normal vnode diffing. ### When to use - Optional layout sections (sidebars, headers) where most pages supply content but some don't - Notification or alert components where a generic message covers the common case - Button and input wrappers with sensible default labels - Skip fallbacks for slots you always fill from the parent. Use props for required content instead Most dashboard layouts I've worked on use named slot fallbacks exactly this way: the layout component defines safe defaults, and individual pages override only what they need. ### Common mistakes **Expecting fallback to merge with parent content** ```vue <!-- Wrong expectation --> <ChildComponent> <p>Extra paragraph</p> </ChildComponent> <!-- Only "Extra paragraph" shows. Fallback is gone. --> ``` Slots replace entirely. If you need both the fallback and extra content, define separate named slots. **Wrong name on a named slot** ```vue <!-- Child declares: <slot name="header"> --> <!-- Parent uses wrong name --> <template #head>Custom title</template> <!-- "head" never matches "header". Fallback always shows. --> ``` Names are case-sensitive and must match exactly. The default slot has no name attribute. **Empty template fools the fallback check** ```vue <ChildComponent> <template #default></template> </ChildComponent> <!-- Vue sees a slot was provided. Fallback does not render. --> ``` Vue considers any provided slot as filled, even if it contains nothing. This catches people trying to conditionally pass a slot from the parent. **Dynamic fallbacks and SSR** ```vue <!-- Risky in Nuxt --> <slot><div v-if="isClient">Fallback</div></slot> ``` If the fallback depends on client-only state, you'll get a hydration mismatch: server renders nothing, client adds the div. Keep fallbacks static or wrap them with `<ClientOnly>`. ### Real-world usage - Vuetify `v-card`: slot fallbacks for title and action areas when parent skips them - Element Plus `el-table`: default empty state message via slot fallback - Quasar `q-page`: app-branded default header and drawer fallbacks - Nuxt UI: fallback notifications in global layout slots ### Follow-up questions **Q:** Can fallback content access the child component's data? **A:** Yes. Fallback lives in the child's template scope, so it has full access to the child's reactive data, computed properties, and methods. **Q:** What happens if the parent provides content for a slot that doesn't exist in the child? **A:** Vue drops it. The child must declare `<slot name="foo">` explicitly, otherwise the content disappears without any warning. **Q:** Do scoped slots work with fallbacks? **A:** Yes, with one catch. Fallback inside a scoped slot can access the slot's exposed data directly, since it runs in child scope. But if the parent overrides the slot, it must declare `v-slot="{ items }"` to receive that data. The fallback doesn't run at all in that case. **Q:** Any performance difference between a component using fallback vs one always receiving parent content? **A:** None. The check is compile-time conditional logic. Both paths generate the same number of vnode operations. ## Examples ### Button with default label ```vue <!-- SubmitButton.vue --> <template> <button type="submit" class="btn-primary"> <slot>Submit</slot> </button> </template> <!-- Usage --> <SubmitButton /> <!-- Renders: Submit --> <SubmitButton>Save draft</SubmitButton> <!-- Renders: Save draft --> <SubmitButton>Delete</SubmitButton> <!-- Renders: Delete --> ``` One component, multiple labels, zero extra props. The fallback handles the common case; callers override when they need something different. ### Dashboard layout with named slot fallbacks ```vue <!-- AppLayout.vue --> <template> <div class="layout"> <header> <slot name="header"> <h1>My App</h1> <!-- generic fallback --> </slot> </header> <aside> <slot name="sidebar"> <p>No sidebar configured</p> </slot> </aside> <main> <slot>Load your content here</slot> </main> </div> </template> <!-- CRM page: overrides header and sidebar, leaves main as fallback --> <AppLayout> <template #header> <h1>Customer Dashboard</h1> </template> <template #sidebar> <nav>Users | Reports | Billing</nav> </template> <!-- No #default provided: main shows fallback text --> </AppLayout> ``` Each slot is independent. Providing content for `#header` has no effect on `#sidebar` or the default slot. Fallbacks fill only the gaps the parent leaves open.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.