21 KiB
21 KiB
| 1 | No | Category | Guideline | Description | Do | Don't | Code Good | Code Bad | Severity | Docs URL |
|---|---|---|---|---|---|---|---|---|---|---|
| 2 | 1 | Installation | Add Nuxt UI module | Install and configure Nuxt UI in your Nuxt project | pnpm add @nuxt/ui and add to modules | Manual component imports | modules: ['@nuxt/ui'] | import { UButton } from '@nuxt/ui' | High | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 3 | 2 | Installation | Import Tailwind and Nuxt UI CSS | Required CSS imports in main.css file | @import tailwindcss and @import @nuxt/ui | Skip CSS imports | @import "tailwindcss"; @import "@nuxt/ui"; | No CSS imports | High | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 4 | 3 | Installation | Wrap app with UApp component | UApp provides global configs for Toast Tooltip and overlays | <UApp> wrapper in app.vue | Skip UApp wrapper | <UApp><NuxtPage/></UApp> | <NuxtPage/> without wrapper | High | https://ui.nuxt.com/docs/components/app |
| 5 | 4 | Components | Use U prefix for components | All Nuxt UI components use U prefix by default | UButton UInput UModal | Button Input Modal | <UButton>Click</UButton> | <Button>Click</Button> | Medium | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 6 | 8 | Icons | Use i-{collection}-{name} format for icons | Nuxt UI v4 uses Iconify i-prefix format — lucide:home is v3 legacy | i-lucide-home i-heroicons-user format | lucide:home format (v3 syntax) | <UButton icon="i-lucide-home"> | <UButton icon="lucide:home"> | High | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 7 | 10 | Theming | Configure colors in app.config.ts | Runtime color configuration without restart | ui.colors.primary in app.config.ts | Hardcoded colors in components | defineAppConfig({ ui: { colors: { primary: 'blue' } } }) | <UButton class="bg-blue-500"> | High | https://ui.nuxt.com/docs/getting-started/theme/design-system |
| 8 | 12 | Theming | Extend semantic colors in nuxt.config | Register new colors like tertiary in theme.colors | theme.colors array in ui config | Use undefined colors | ui: { theme: { colors: ['primary', 'tertiary'] } } | <UButton color="tertiary"> without config | Medium | https://ui.nuxt.com/docs/getting-started/theme/design-system |
| 9 | 13 | Forms | Use UForm with schema validation | UForm supports Zod Yup Joi Valibot schemas | :schema prop with validation schema | Manual form validation | <UForm :schema="schema" :state="state"> | Manual @blur validation | High | https://ui.nuxt.com/docs/components/form |
| 10 | 14 | Forms | Use UFormField for field wrapper | Provides label error message and validation display | UFormField with name prop | Manual error handling | <UFormField name="email" label="Email"> | <div><label>Email</label><UInput/><span>error</span></div> | Medium | https://ui.nuxt.com/docs/components/form-field |
| 11 | 15 | Forms | Handle form submit with @submit | UForm emits submit event with validated data | @submit handler on UForm | @click on submit button | <UForm @submit="onSubmit"> | <UButton @click="onSubmit"> | Medium | https://ui.nuxt.com/docs/components/form |
| 12 | 18 | Overlays | Use useOverlay composable for programmatic overlays | Open overlays programmatically — v4 API is create().open() not open(Component) | overlay.create(Component).open({ props }) pattern | v3 overlay.open(Component) pattern (removed in v4) | const modal = overlay.create(MyModal); const { result } = modal.open({ title: 'Confirm' }) | overlay.open(MyModal, { props: { title: 'Confirm' } }) | High | https://ui.nuxt.com/docs/components/modal |
| 13 | 21 | Dashboard | Use UDashboardGroup for layout | Wraps dashboard components with sidebar state management | UDashboardGroup > UDashboardSidebar + UDashboardPanel | Manual layout flex containers | <UDashboardGroup><UDashboardSidebar/><UDashboardPanel/></UDashboardGroup> | <div class="flex"><aside/><main/></div> | Medium | https://ui.nuxt.com/docs/components/dashboard-group |
| 14 | 23 | Tables | Use UTable with data and columns props | Powered by TanStack Table with built-in features | :data and :columns props | Manual table markup | <UTable :data="users" :columns="columns"/> | <table><tr v-for="user in users"> | High | https://ui.nuxt.com/docs/components/table |
| 15 | 24 | Tables | Define columns with accessorKey | Column definitions use accessorKey for data binding | accessorKey: 'email' in column def | String column names only | { accessorKey: 'email', header: 'Email' } | ['name', 'email'] | Medium | https://ui.nuxt.com/docs/components/table |
| 16 | 27 | Navigation | Use UNavigationMenu for nav links | Horizontal or vertical navigation with dropdown support | UNavigationMenu with items array | Manual nav with v-for | <UNavigationMenu :items="navItems"/> | <nav><a v-for="item in items"> | Medium | https://ui.nuxt.com/docs/components/navigation-menu |
| 17 | 28 | Navigation | Use UBreadcrumb for page hierarchy | Automatic breadcrumb with NuxtLink support | :items array with label and to | Manual breadcrumb links | <UBreadcrumb :items="breadcrumbs"/> | <nav><span v-for="crumb in crumbs"> | Low | https://ui.nuxt.com/docs/components/breadcrumb |
| 18 | 29 | Navigation | Use UTabs for tabbed content | Tab navigation with content panels | UTabs with items containing slot content | Manual tab state | <UTabs :items="tabs"/> | <div><button @click="tab=1"> | Medium | https://ui.nuxt.com/docs/components/tabs |
| 19 | 31 | Feedback | Use UAlert for inline messages | Static alert messages with icon and actions | UAlert with title description color | Toast for static messages | <UAlert title="Warning" color="warning"/> | useToast for inline alerts | Medium | https://ui.nuxt.com/docs/components/alert |
| 20 | 33 | Color Mode | Use UColorModeButton for theme toggle | Built-in light/dark mode toggle button | UColorModeButton component | Manual color mode logic | <UColorModeButton/> | <button @click="toggleColorMode"> | Low | https://ui.nuxt.com/docs/components/color-mode-button |
| 21 | 34 | Color Mode | Use UColorModeSelect for theme picker | Dropdown to select system light or dark mode | UColorModeSelect component | Custom select for theme | <UColorModeSelect/> | <USelect v-model="colorMode" :items="modes"/> | Low | https://ui.nuxt.com/docs/components/color-mode-select |
| 22 | 36 | Customization | Configure default variants in nuxt.config | Set default color and size for all components | theme.defaultVariants in ui config | Repeat props on every component | ui: { theme: { defaultVariants: { color: 'neutral' } } } | <UButton color="neutral"> everywhere | Medium | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 23 | 37 | Customization | Use app.config.ts for theme overrides | Runtime theme customization | defineAppConfig with ui key | nuxt.config for runtime values | defineAppConfig({ ui: { button: { defaultVariants: { size: 'sm' } } } }) | nuxt.config ui.button.size: 'sm' | Medium | https://ui.nuxt.com/docs/getting-started/theme/components |
| 24 | 38 | Performance | Enable component detection | Tree-shake unused component CSS | experimental.componentDetection: true | Include all component CSS | ui: { experimental: { componentDetection: true } } | ui: {} (includes all CSS) | Low | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 25 | 39 | Performance | Use UTable virtualize for large data | Enable virtualization for 1000+ rows | :virtualize prop on UTable | Render all rows | <UTable :data="largeData" virtualize/> | <UTable :data="largeData"/> | Medium | https://ui.nuxt.com/docs/components/table |
| 26 | 40 | Accessibility | Use semantic component props | Components have built-in ARIA support | Use title description label props | Skip accessibility props | <UModal title="Settings"> | <UModal><h2>Settings</h2> | Medium | https://ui.nuxt.com/docs/components/modal |
| 27 | 41 | Accessibility | Use UFormField for form accessibility | Automatic label-input association | UFormField wraps inputs | Manual id and for attributes | <UFormField label="Email"><UInput/></UFormField> | <label for="email">Email</label><UInput id="email"/> | High | https://ui.nuxt.com/docs/components/form-field |
| 28 | 42 | Content | Use UContentToc for table of contents | Automatic TOC with active heading highlight | UContentToc with :links | Manual TOC implementation | <UContentToc :links="toc"/> | <nav><a v-for="heading in headings"> | Low | https://ui.nuxt.com/docs/components/content-toc |
| 29 | 44 | AI/Chat | Use UChatMessages for chat UI | Designed for Vercel AI SDK integration | UChatMessages with messages array | Custom chat message list | <UChatMessages :messages="messages"/> | <div v-for="msg in messages"> | Medium | https://ui.nuxt.com/docs/components/chat-messages |
| 30 | 46 | Editor | Use UEditor for rich text | TipTap-based editor with toolbar support | UEditor with v-model:content | Custom TipTap setup | <UEditor v-model:content="content"/> | Manual TipTap initialization | Medium | https://ui.nuxt.com/docs/components/editor |
| 31 | 49 | Loading | Use loadingAuto on buttons | Automatic loading state from @click promise | loadingAuto prop on UButton | Manual loading state | <UButton loadingAuto @click="async () => await save()"> | <UButton :loading="isLoading" @click="save"> | Low | https://ui.nuxt.com/docs/components/button |
| 32 | 50 | Loading | Use UForm loadingAuto | Auto-disable form during submit | loadingAuto on UForm (default true) | Manual form disabled state | <UForm @submit="handleSubmit"> | <UForm :disabled="isSubmitting"> | Low | https://ui.nuxt.com/docs/components/form |
| 33 | 51 | Installation | Do not manually add auto-registered modules | Nuxt UI v4 auto-registers @nuxt/icon @nuxt/fonts @nuxtjs/color-mode | Configure via root-level keys in nuxt.config | Adding them to modules array causes duplicate registration | icon: { /* opts */ } in nuxt.config | modules: ['@nuxt/ui', '@nuxt/icon'] | High | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 34 | 52 | Installation | Use official templates to bootstrap projects | Nuxt UI provides starter templates via nuxi init | npx nuxi init -t ui/dashboard for dashboard project | Manual project setup from scratch | npx nuxi@latest init -t ui/dashboard | pnpm create nuxt app (manual UI setup) | Medium | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 35 | 53 | Icons | Install icon collections locally for SSR | Local Iconify JSON prevents network requests and flash | pnpm i @iconify-json/lucide for reliable server rendering | Rely on remote icon fetching in production | pnpm i @iconify-json/lucide @iconify-json/simple-icons | No local icon packages | Medium | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 36 | 54 | Icons | Override default component icons globally | Components use default icons configurable via appConfig.ui.icons | Set loading close check icons in app.config.ts | Accept default icons for all components | defineAppConfig({ ui: { icons: { loading: 'i-lucide-refresh-cw', close: 'i-lucide-x' } } }) | <UModal :close-icon="'i-lucide-x'"> on every usage | Low | https://ui.nuxt.com/docs/getting-started/installation/nuxt |
| 37 | 55 | Forms | Use UFileUpload for file input | Built-in drag-drop and preview support | UFileUpload with v-model and accept prop | Custom input type=file | <UFileUpload v-model="files" accept="image/*" multiple/> | <input type="file" @change="handleFiles"> | Medium | https://ui.nuxt.com/docs/components/file-upload |
| 38 | 56 | Forms | Use UInputDate for date selection | Locale-aware date picker built on UCalendar | UInputDate with v-model and locale prop | Third-party date picker libraries | <UInputDate v-model="date" /> | <DatePicker v-model="date" /> | Medium | https://ui.nuxt.com/docs/components/input-date |
| 39 | 57 | Forms | Use UInputTags for tag input | Multi-value tag input with keyboard support | UInputTags with v-model and max prop | Custom chip input implementation | <UInputTags v-model="tags" :max="5" /> | <UInput @keydown.enter="addTag"> | Low | https://ui.nuxt.com/docs/components/input-tags |
| 40 | 58 | Forms | Use UColorPicker for color selection | Full-featured color picker with multiple format support | UColorPicker with v-model and format prop | Native input type=color | <UColorPicker v-model="color" format="hex" /> | <input type="color" v-model="color"> | Low | https://ui.nuxt.com/docs/components/color-picker |
| 41 | 59 | Data | Use UTree for hierarchical data | Built-in tree component with expand/collapse | UTree with items prop containing nested children | Custom recursive component | <UTree :items="treeItems" /> | <TreeNode v-for="item in items" :key="item.id"> | Low | https://ui.nuxt.com/docs/components/tree |
| 42 | 60 | Data | Use UMarquee for infinite scroll content | Animated infinite scroll band for logos or testimonials | UMarquee with repeat and pauseOnHover props | CSS animation keyframes loop | <UMarquee :repeat="3" pause-on-hover> | <div class="animate-marquee"> | Low | https://ui.nuxt.com/docs/components/marquee |
| 43 | 62 | Overlays | Await overlay result for confirmation dialogs | useOverlay returns a result Promise resolving to user action | await instance.result to get confirm/cancel | Emit events from overlay components | const { result } = modal.open(); if (await result) { deleteItem() } | overlay.open(Confirm, { onConfirm: deleteItem }) | Medium | https://ui.nuxt.com/docs/components/modal |
| 44 | 63 | Navigation | Use UCommandPalette with grouped items | Command palette supports grouped search with icons and kbds | groups array with id label items | Flat list without categories | <UCommandPalette :groups="[{ id: 'actions', label: 'Actions', items }]"/> | <UCommandPalette :items="flatList"/> | Medium | https://ui.nuxt.com/docs/components/command-palette |
| 45 | 64 | Navigation | Use defineShortcuts with extractShortcuts | Wire keyboard shortcuts from menu item kbds automatically | extractShortcuts(items) + defineShortcuts to sync keybindings | Manually duplicate shortcuts from menu items | defineShortcuts(extractShortcuts(items)) | defineShortcuts({ meta_n: () => newFile() }) // duplicated from items | Low | https://ui.nuxt.com/docs/composables/define-shortcuts |
| 46 | 65 | Layout | Use UHeader and UFooter for page layout | Responsive header/footer with built-in mobile menu | UHeader with #default slot for nav UFooter with columns | Custom header/footer from scratch | <UHeader><template #right><UNavigationMenu/></template></UHeader> | <header class="sticky top-0"> | Low | https://ui.nuxt.com/docs/components/header |
| 47 | 66 | Layout | Use UPageAside for sidebar content | Sidebar that hides below lg breakpoint automatically | UPageAside for docs and landing page sidebars | Manual hidden lg: classes | <UPageAside><UNavigationMenu orientation="vertical"/></UPageAside> | <aside class="hidden lg:block"> | Low | https://ui.nuxt.com/docs/components/page-aside |
| 48 | 68 | Theming | Read generated theme file to find slot names | Nuxt UI generates theme files listing all component slots and variants | Check .nuxt/ui/<component>.ts for slot names | Guess slot names or use trial-and-error | .nuxt/ui/button.ts for UButton slot names | <UButton :ui="{ base: 'rounded-full' }"/> without checking slots | Medium | https://ui.nuxt.com/docs/getting-started/theme/components |
| 49 | 69 | Composables | Use defineShortcuts whenever keyword shortcut | whenever array condition prevents shortcut firing when inactive | whenever: [isFormValid] to guard shortcut execution | Always-on shortcuts that fire in wrong context | defineShortcuts({ meta_enter: { handler: submit, whenever: [isFormValid] } }) | defineShortcuts({ meta_enter: () => submit() }) // fires even when invalid | Low | https://ui.nuxt.com/docs/composables/define-shortcuts |
| 50 | 70 | i18n | Use UApp locale prop for internationalization | Nuxt UI supports 50+ built-in locales via locale prop on UApp | Import locale from @nuxt/ui/locale and pass to UApp | Manual translation of component UI strings | import { fr } from '@nuxt/ui/locale'; // <UApp :locale="fr"> | <UModal title="Fermer"> manually for each component | Low | https://ui.nuxt.com/docs/composables/define-locale |