Nuxt UI Dashboard Template

repository·main·Indexed 21 days ago

https://github.com/nuxt-ui-templates/dashboard

A professional Nuxt-based dashboard template for building admin interfaces. It features a command palette, collapsible sidebar, keyboard shortcuts, and light/dark mode powered by Nuxt UI. The template includes implementations for data visualization with specialized components, state management via the useDashboard composable, and type-safe form validation using UForm and Zod.

Tokens
2.6K
Snippets
11
Records
11
Agent score
77%

What's inside nuxt-ui-templates/dashboard

  1. Quick Start with the Nuxt Dashboard Template

    main

    To create a new project using the Nuxt Dashboard template, use the npx nuxt command with the ui/dashboard template flag. This will scaffold a project featuring multiple pages, a collapsible sidebar, keyboard shortcuts, light/dark mode, and a command palette, all powered by Nuxt UI.

    npm create nuxt@latest -- -t ui/dashboard
  2. Setup and Local Development

    main

    After scaffolding your project, follow these steps to set up your environment and start developing:

    1. Install dependencies: Use pnpm to install the required packages.
    2. Start development server: Run the dev command to launch the application locally, typically at http://localhost:3000.
    pnpm install
    pnpm dev
  3. Structure of the Dashboard Home Page

    main

    The home page route (app/pages/index.vue) serves as a central dashboard view. It utilizes a layout composed of UDashboardPanel, UDashboardNavbar, and UDashboardToolbar.

    Key functional areas include:

    • Navigation & Actions: A UDashboardNavbar containing a sidebar collapse trigger, a notification toggle (via useDashboard), and a UDropdownMenu for quick actions.
    • Filtering: A UDashboardToolbar that hosts date range selection (HomeDateRangePicker) and period selection (HomePeriodSelect).
    • Data Visualization: The main body contains several specialized components (HomeStats, HomeChart, and HomeSales) that react to the selected range and period via v-model.

    State management for the dashboard's UI (like the notifications slideover) is handled via the useDashboard() composable.

    <template>
      <UDashboardPanel id="home">
        <template #header>
          <UDashboardNavbar title="Home">
            <!-- Sidebar collapse, Notifications, and Dropdown actions -->
          </UDashboardNavbar>
          <UDashboardToolbar>
            <!-- Date Range and Period Selectors -->
          </UDashboardToolbar>
        </template>
        <template #body>
          <!-- Stats, Charts, and Sales components -->
        </template>
      </UDashboardPanel>
    </template>
  4. Structure the application entrypoint with UApp and NuxtLayout

    main

    The main application entrypoint uses <UApp> as the top-level wrapper to provide Nuxt UI context. Inside <UApp>, the application structure typically follows a pattern of a <NuxtLoadingIndicator /> for progress feedback, followed by <NuxtLayout> to wrap the current page content provided by <NuxtPage />.

    <template>
      <UApp>
        <NuxtLoadingIndicator />
    
        <NuxtLayout>
          <NuxtPage />
        </NuxtLayout>
      </UApp>
    </template>
  5. Configure ESLint for the Nuxt Dashboard Template

    main

    The project uses a specialized ESLint configuration powered by withNuxt. This wrapper (imported from ./.nuxt/eslint.config.mjs) provides the base Nuxt-specific linting rules. You can extend this configuration by passing an object to withNuxt to override or add specific rules.

    Currently, the template includes the following rule overrides:

    • vue/no-multiple-template-root: Set to 'off' to allow multiple root nodes in Vue templates.
    • vue/max-attributes-per-line: Set to ['error', { singleline: 3 }] to enforce a maximum of 3 attributes per line in single-line elements.
    import withNuxt from './.nuxt/eslint.config.mjs'
    
    export default withNuxt({
      rules: {
        'vue/no-multiple-template-root': 'off',
        'vue/max-attributes-per-line': ['error', { singleline: 3 }]
      }
    })
  6. Configure Nuxt UI colors in app.config.ts

    main

    You can customize the global color scheme of the dashboard by providing a ui object within defineAppConfig. This allows you to set the primary and neutral color palettes used throughout the application components.

    Available keys:

    • primary: The main brand color (e.g., 'green').
    • neutral: The color used for backgrounds, borders, and neutral UI elements (e.g., 'zinc').
    export default defineAppConfig({
      ui: {
        colors: {
          primary: 'green',
          neutral: 'zinc'
        }
      }
    })
  7. Implement a profile settings form with UForm and Zod

    main

    The settings page demonstrates how to use @nuxt/ui components (UForm, UFormField, UInput, etc.) in conjunction with zod for schema-based form validation.

    Key implementation steps:

    1. Define a Schema: Use z.object() to define the shape and validation rules (e.g., .min(), .email()) for your form data.
    2. Define State: Create a reactive object (using reactive) that matches the schema's output type. Use Partial<T> if you want to allow empty initial states.
    3. Bind to UForm: Pass the schema and the state object to the <UForm> component. Use the @submit event to handle the validated data.
    4. Handle File Uploads: For avatar/image uploads, use a hidden <input type="file"> and trigger its click event via a ref when a UI button is clicked. Use URL.createObjectURL() to generate a preview URL for the UAvatar component.
    <script setup lang="ts">
    import * as z from 'zod'
    import type { FormSubmitEvent } from '@nuxt/ui'
    
    // 1. Define validation schema
    const profileSchema = z.object({
      name: z.string().min(2, 'Too short'),
      email: z.string().email('Invalid email'),
      username: z.string().min(2, 'Too short'),
      avatar: z.string().optional(),
      bio: z.string().optional()
    })
    
    type ProfileSchema = z.output<typeof profileSchema>
    
    // 2. Define reactive state
    const profile = reactive<Partial<ProfileSchema>>({
      name: 'Benjamin Canac',
      email: 'ben@nuxtlabs.com',
      username: 'benjamincanac'
    })
    
    // 3. Handle submission
    async function onSubmit(event: FormSubmitEvent<ProfileSchema>) {
      console.log(event.data)
    }
    </script>
    
    <template>
      <UForm
        :schema="profileSchema"
        :state="profile"
        @submit="onSubmit"
      >
        <!-- Form fields go here -->
        <UFormField name="name" label="Name">
          <UInput v-model="profile.name" />
        </UFormField>
        
        <UButton type="submit">Save changes</UButton>
      </UForm>
    </template>
  8. Configure SEO and Meta tags in the application

    main

    The template uses Nuxt composables to manage SEO and head metadata.

    • useHead: Used for low-level HTML configuration like charset, viewport, theme-color, and link tags (e.g., favicons).
    • useSeoMeta: Used for high-level SEO properties including title, description, Open Graph (ogTitle, ogDescription, ogImage), and Twitter card configurations.
    <script setup lang="ts">
    const title = 'Nuxt Dashboard Template'
    const description = 'A professional dashboard template built with Nuxt UI...'
    
    useSeoMeta({
      title,
      description,
      ogTitle: title,
      ogDescription: description,
      ogImage: 'https://ui.nuxt.com/assets/templates/nuxt/dashboard-light.png',
      twitterCard: 'summary_large_image'
    })
    </script>
  9. Use FormSubmitEvent for type-safe form submission

    main

    When handling the @submit event on a <UForm> component, use the FormSubmitEvent<T> type from @nuxt/ui. This ensures that the event.data property is correctly typed according to your Zod schema T.

    import type { FormSubmitEvent } from '@nuxt/ui'
    
    // T is the type derived from your Zod schema
    async function onSubmit(event: FormSubmitEvent<ProfileSchema>) {
      // event.data is now typed as ProfileSchema
      console.log(event.data)
    }
  10. Manage Notifications via useDashboard

    main

    The useDashboard composable provides access to the dashboard's global UI state. To control the visibility of the notifications slideover, destructure isNotificationsSlideoverOpen from useDashboard() and set it to true on a click event.

    const { isNotificationsSlideoverOpen } = useDashboard()
    
    // To open the notifications panel:
    // isNotificationsSlideoverOpen.value = true