Quick start

Get up and running with your first feature in 5 minutes

This guide will help you understand the boilerplate by building a simple feature. We'll create a protected page that displays user information.

Goal

By the end of this guide, you'll have:

  1. Created a new protected page
  2. Added it to the navigation menu
  3. Fetched and displayed user data
  4. Used shadcn-vue components for the UI

Let's get started!

Step 1: Create a protected page

Create a new file at app/pages/profile.vue:

app/pages/profile.vue
<script setup lang="ts">
// This page requires authentication
definePageMeta({
  middleware: 'auth',
})

const userStore = useUserStore()
const { user } = storeToRefs(userStore)

useSeoMeta({
  title: 'Profile',
  description: 'View your profile information',
})
</script>

<template>
  <div class="base-container py-8">
    <h1 class="text-4xl font-bold mb-2">Your profile</h1>
    <p class="text-muted-foreground mb-8">View and manage your account information</p>

    <Card v-if="user" class="max-w-2xl">
      <CardHeader>
        <CardTitle>Account information</CardTitle>
        <CardDescription> Your account details and settings </CardDescription>
      </CardHeader>
      <CardContent class="space-y-4">
        <div class="grid grid-cols-2 gap-4">
          <div>
            <p class="text-sm font-medium text-muted-foreground">Name</p>
            <p class="text-base">{{ user.name }}</p>
          </div>
          <div>
            <p class="text-sm font-medium text-muted-foreground">Email</p>
            <p class="text-base">{{ user.email }}</p>
          </div>
          <div>
            <p class="text-sm font-medium text-muted-foreground">Email verified</p>
            <p class="text-base">{{ user.emailVerified ? 'Yes' : 'No' }}</p>
          </div>
          <div>
            <p class="text-sm font-medium text-muted-foreground">Member since</p>
            <p class="text-base">{{ new Date(user.createdAt).toLocaleDateString() }}</p>
          </div>
        </div>
      </CardContent>
      <CardFooter>
        <Button as-child>
          <NuxtLink to="/settings"> Edit profile </NuxtLink>
        </Button>
      </CardFooter>
    </Card>
  </div>
</template>
The middleware: 'auth' in definePageMeta ensures only authenticated users can access this page. Unauthenticated users will be redirected to the login page.

Step 2: Add to navigation

Open app/components/header/MainHeader.vue and add the profile link to the navigationItems array:

app/components/header/MainHeader.vue
const navigationItems = [
  {
    label: 'Dashboard',
    icon: Home,
    to: '/dashboard',
    requiresAuth: true,
  },
  {
    label: 'Profile',
    icon: User,
    to: '/profile',
    requiresAuth: true,
  },
  // ... other items
]

Don't forget to import the User icon at the top of the file:

app/components/header/MainHeader.vue
import { User, Home /* other icons */ } from 'lucide-vue-next'

Step 3: Test your page

  1. Start the dev server (if not already running):
pnpm dev
  1. Log in to your application at http://localhost:3000/auth/login
  2. Navigate to your new page - Click "Profile" in the header menu
  3. See your data - You should see your account information displayed in a card
Congratulations! You've created your first feature using the boilerplate.

What you learned

Through this quick example, you've seen how to:

  • ✅ Create a protected page with definePageMeta
  • ✅ Use the user store to access authentication state
  • ✅ Use shadcn-vue components (Card, Button)
  • ✅ Add navigation items to the header menu
  • ✅ Follow the boilerplate's conventions

Key concepts explained

Page metadata

definePageMeta({
  middleware: 'auth',
})

This tells Nuxt to run the auth middleware before rendering the page. The middleware is defined in app/middleware/auth.global.ts and automatically redirects unauthenticated users.

User store

const userStore = useUserStore()
const { user } = storeToRefs(userStore)

The user store (Pinia) holds the current user's authentication state. Using storeToRefs ensures reactivity when accessing store properties.

Shadcn-vue components

The boilerplate includes 170+ pre-built UI components. They're automatically imported, so you can use them directly:

<Card>
  <CardHeader>
    <CardTitle>Title</CardTitle>
  </CardHeader>
  <CardContent>
    Content here
  </CardContent>
</Card>
Learn more about available UI components in the UI components guide.

Next steps

Now that you understand the basics, explore more features:

Authentication system

Deep dive into how authentication works in this boilerplate.

Database queries

Learn how to work with the database using Prisma.

Stripe payments

Add subscription payments to your application.

AI integration

Use OpenAI, Claude, or Grok in your app.

Challenge: Extend the feature

Try adding these enhancements on your own:

  1. Add an avatar - Display the user's image if available
  2. Show subscription status - Use the useSubscription composable to display plan info
  3. Add a button - Create a button to change the user's email
  4. Style improvements - Customize the card appearance with Tailwind classes
The best way to learn is by building! Try modifying this example and creating your own pages.