Nuxt UI Pro v1.0 is out with dashboard components! Discount ends in 7 hours.

Structure

Learn how to structure your application with Nuxt UI Pro.

We'll only provide examples for the most common use cases, but keep in mind that you can do whatever you want. Let's start by configuring our app, then we'll see how to build a simple landing page and then how to integrate with the @nuxt/content module.

nuxt.config.ts

If you've followed the installation guide, you should already have a nuxt.config.ts file with the @nuxt/ui-pro layer and the @nuxt/ui module registered. We'll also configure @nuxt/ui module with some icons collections and take advantage of @nuxtjs/google-fonts and @nuxtjs/fontaine to choose our font.

nuxt.config.ts
export default defineNuxtConfig({
  extends: ['@nuxt/ui-pro'],
  modules: [
    '@nuxtjs/fontaine',
    '@nuxtjs/google-fonts',
    '@nuxt/ui'
  ],
  ui: {
    icons: ['ph', 'simple-icons']
  },
  colorMode: {
    preference: 'dark'
  },
  googleFonts: {
    display: 'swap',
    download: true,
    families: {
      'DM+Sans': [400, 500, 600, 700]
    }
  },
  fontMetrics: {
    fonts: ['DM Sans']
  }
})
You can use any icon (100,000+) from Iconify, learn more in the Theming documentation.

app.config.ts

We'll now create an app.config.ts file to configure the primary and gray colors. We'll also change the header height, default background and override some icons.

app.config.ts
export default defineAppConfig({
  ui: {
    primary: 'green',
    gray: 'slate',
    tooltip: {
      background: '!bg-background'
    },
    variables: {
      dark: {
        background: 'var(--color-gray-950)'
      },
      header: {
        height: '5rem'
      }
    },
    icons: {
      dark: 'i-ph-moon-duotone',
      light: 'i-ph-sun-duotone',
      search: 'i-ph-magnifying-glass-duotone',
      external: 'i-ph-arrow-up-right',
      chevron: 'i-ph-caret-down',
      hash: 'i-ph-hash-duotone'
    },
    header: {
      wrapper: 'lg:mb-0 lg:border-0',
      popover: {
        links: {
          active: 'dark:bg-gray-950/50',
          inactive: 'dark:hover:bg-gray-950/50'
        }
      }
    }
  }
})

Like in Nuxt UI, you'll configure components through the ui prop. The key to override a component will be its path, for example ui.landing.hero will override the LandingHero component. The only difference with Nuxt UI is that the config lives inside each component instead of a global ui.config.ts file.

You can use any color from Tailwind CSS, learn more in the Theming documentation.

tailwind.config.ts

Let's say we want to override the green color to use the one from Nuxt, we can create a tailwind.config.ts file to do so. Like any other app using Tailwind CSS, you can override any Tailwind config here. We'll also override the fontFamily to use DM Sans as our default font.

tailwind.config.ts
import type { Config } from 'tailwindcss'
import defaultTheme from 'tailwindcss/defaultTheme'

export default <Partial<Config>>{
  theme: {
    extend: {
      fontFamily: {
        sans: ['DM Sans', 'DM Sans fallback', ...defaultTheme.fontFamily.sans]
      },
      colors: {
        green: {
          50: '#EFFDF5',
          100: '#D9FBE8',
          200: '#B3F5D1',
          300: '#75EDAE',
          400: '#00DC82',
          500: '#00C16A',
          600: '#00A155',
          700: '#007F45',
          800: '#016538',
          900: '#0A5331',
          950: '#052e16'
        }
      }
    }
  }
}

app.vue

Let's add an app.vue file which will be the root component of our app. We can use the Header, Main and Footer components to build the layout of our app.

app.vue
<script setup lang="ts">
const links = [{
  label: 'Documentation',
  icon: 'i-heroicons-book-open',
  to: '/getting-started'
}, {
  label: 'Playground',
  icon: 'i-simple-icons-stackblitz',
  to: '/playground'
}, {
  label: 'Roadmap',
  icon: 'i-heroicons-map',
  to: '/roadmap'
}, {
  label: 'Pro',
  icon: 'i-heroicons-square-3-stack-3d',
  to: '/pro'
}, {
  label: 'Releases',
  icon: 'i-heroicons-rocket-launch',
  to: 'https://github.com/nuxt/ui/releases',
  target: '_blank'
}]
</script>

<template>
  <UHeader :links="links">
    <template #logo>
      <Logo class="w-auto h-6" />
    </template>

    <template #right>
      <UColorModeButton />

      <UButton icon="i-simple-icons-github" to="https://github.com/nuxt/nuxt" target="_blank" color="gray" variant="ghost" />
    </template>
  </UHeader>

  <UMain>
    <NuxtLayout>
      <NuxtPage />
    </NuxtLayout>
  </UMain>

  <UFooter>
    <template #left>
      <p class="text-gray-500 dark:text-gray-400 text-sm">
        Copyright © 2016-{{ new Date().getFullYear() }} Nuxt - <NuxtLink class="hover:underline" to="https://github.com/nuxt/nuxt/blob/main/LICENSE" target="_blank">
          MIT License
        </NuxtLink>
      </p>
    </template>

    <template #right>
      <UButton to="https://x.com/nuxt_js" target="_blank" icon="i-simple-icons-x" color="gray" variant="ghost" />
      <UButton to="https://discord.com/invite/ps2h6QT" target="_blank" icon="i-simple-icons-discord" color="gray" variant="ghost" />
      <UButton to="https://github.com/nuxt/nuxt" target="_blank" icon="i-simple-icons-github" color="gray" variant="ghost" />
    </template>
  </UFooter>
  <UNotifications />
</template>

This example is quite long but demonstrates some props and slots available to customize your app.

pages/index.vue

Now, we can create our first page. We'll use the LandingHero and LandingSection components to build a simple landing page.

pages/index.vue
<template>
  <div>
    <ULandingHero description="Nuxt UI Pro is a collection of premium Vue components built on top of Nuxt UI to create beautiful & responsive Nuxt applications in minutes.">
      <template #title>
        The <span class="text-primary block lg:inline-block">Building Blocks</span> for Modern Web apps
      </template>
    </ULandingHero>

    <ULandingSection title="The freedom to build anything" align="left" />

    <ULandingSection title="The flexibility to control your data" align="right" />
  </div>
</template>

This is a very simple example as it's way easier to demonstrate with @nuxt/content rather than hard-coding the content.