Make your app resilient and responsive — error boundaries that contain crashes, lazy components for smaller pages, and Teleport for modals that escape clipping.
Why: a render error with no boundary can blank the entire app. <NuxtErrorBoundary> catches errors from everything inside it and shows a fallback instead, with clearError to retry. Note: an error.vue file at the project root gives you a full-page error screen for anything unhandled.
<template>
<!-- A crash inside stops here — the rest of the app keeps working -->
<NuxtErrorBoundary>
<BrokenWidget />
<template #error="{ error, clearError }">
<p>Something broke: {{ error.message }}</p>
<button @click="clearError">Try again</button>
</template>
</NuxtErrorBoundary>
</template>
<!-- For full-page errors, create error.vue at the project root —
Nuxt shows it for any unhandled error, like a global error page -->Why: a heavy component the user might never see — a chart, an editor, a map — shouldn't be in the initial download. Prefix any auto-imported component with Lazy and Nuxt splits its code out, loading it only when it first renders. Smaller first page, same component.
<script setup lang="ts">
import { ref } from 'vue'
const showChart = ref(false)
</script>
<template>
<div>
<button @click="showChart = true">Show chart</button>
<!-- The Lazy prefix makes Nuxt download this component's code
only when it first renders — smaller initial page -->
<LazyHeavyChart v-if="showChart" />
</div>
</template>Why: modals, tooltips, and toasts break when a parent element clips its children (overflow: hidden) or makes them render underneath other content (z-index). <Teleport> escapes that by putting the element somewhere else on the page — usually at the end of <body> — while it still behaves like a normal child in your code: same state, same events.
<script setup lang="ts">
import { ref } from 'vue'
const open = ref(false)
</script>
<template>
<div style="overflow: hidden"> <!-- would clip a normal child -->
<button @click="open = true">Open modal</button>
<!-- Renders at the end of <body>, escaping overflow and z-index traps -->
<Teleport to="body">
<div v-if="open" class="modal">
<p>I render into document.body</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
</div>
</template>