Nuxt UI Best Practices

Tips and patterns for building great UIs with Nuxt UI.

Component Composition

Build complex UIs by composing components:

<template>
  <UCard>
    <template #header>
      <div class="flex items-center justify-between">
        <h3>User Profile</h3>
        <UDropdown :items="menuItems">
          <UButton icon="i-heroicons-ellipsis-vertical" variant="ghost" />
        </UDropdown>
      </div>
    </template>

    <div class="flex items-center gap-4">
      <UAvatar :src="user.avatar" size="xl" />
      <div>
        <h4>{{ user.name }}</h4>
        <UBadge :color="user.status">
          {{ user.role }}
        </UBadge>
      </div>
    </div>

    <template #footer>
      <div class="flex justify-end gap-2">
        <UButton variant="outline">
          Cancel
        </UButton>
        <UButton>Save Changes</UButton>
      </div>
    </template>
  </UCard>
</template>

Consistent Spacing

Use Tailwind's spacing system:

<template>
  <div class="space-y-4">
    <UCard />
    <UCard />
    <UCard />
  </div>

  <div class="flex gap-2">
    <UButton />
    <UButton />
  </div>
</template>

Responsive Design

<template>
  <div class="grid grid-cols-1 gap-4 lg:grid-cols-3 md:grid-cols-2">
    <UCard v-for="item in items" :key="item.id" />
  </div>
</template>

Error Handling

<script setup>
const { data, error, pending } = await useFetch('/api/data')
</script>

<template>
  <div>
    <UAlert v-if="error" color="red" :title="error.message" />

    <div v-if="pending" class="flex justify-center">
      <UIcon name="i-heroicons-arrow-path" class="animate-spin" />
    </div>

    <div v-else>
      <!-- Display data -->
    </div>
  </div>
</template>

Performance Tips

  1. ✅ Use lazy loading for heavy components
  2. ✅ Optimize images
  3. ✅ Use virtual scrolling for long lists
  4. ✅ Minimize re-renders with proper refs
  5. ✅ Use CSS transitions instead of JS animations

Customization Without Breaking Updates

// app.config.ts - safe customization
export default defineAppConfig({
  ui: {
    button: {
      default: {
        color: 'primary'
      }
    }
  }
})

Testing Components

import { UButton } from '@nuxt/ui'
import { mount } from '@vue/test-utils'

describe('Button Test', () => {
  it('renders correctly', () => {
    const wrapper = mount(UButton, {
      slots: {
        default: 'Click me'
      }
    })
    expect(wrapper.text()).toBe('Click me')
  })
})

Checklist

  • ✅ Use semantic HTML
  • ✅ Ensure accessibility
  • ✅ Test on mobile devices
  • ✅ Use consistent spacing
  • ✅ Handle loading and error states
  • ✅ Optimize for performance
  • ✅ Follow Tailwind conventions
  • ✅ Document custom components

You've completed the Nuxt UI section! You're now equipped to build beautiful, accessible UIs. Happy building! 🎨

Accessibility
Nuxt UI components are accessible by default, but here's how to use them properly.
Figma Integration and Design Systems
Bridge the gap between design and development by integrating Figma with your Nuxt UI components for consistent design implementation.
Files
Editor
Initializing WebContainer
Mounting files
Installing dependencies
Starting Nuxt server
Waiting for Nuxt to ready
Terminal