Skip to content

tkozzer/nuxt-starter-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

26 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Nuxt Starter Template

A comprehensive Nuxt 3 template with modern development tools, state management, database integration, and TypeScript support. This template provides everything you need to build scalable, production-ready web applications.

πŸš€ Included Features & Components

βœ… Core Framework

  • Nuxt 3.17.4 - Full-stack Vue.js framework with SSR, auto-imports, and file-based routing

βœ… Database & ORM

βœ… UI & Styling

βœ… State Management

βœ… Authentication

  • Better Auth 1.2.x - Email/password, email verification, password reset, Google OAuth
  • Middleware: auth, admin, optional email-verified
  • SSR-friendly session refresh with cookie forwarding

βœ… Validation & Type Safety

  • Zod 3.25.53 - TypeScript-first schema validation with static type inference
  • TypeScript 5.8.3 - Static type checking and enhanced IDE support

βœ… Code Quality & Linting

βœ… Development Tools

  • pnpm - Fast, disk space efficient package manager
  • Hot Module Replacement - Instant updates during development
  • Auto-imports - Automatic imports for Vue composables, utilities, and shadcn-vue components
  • File-based routing - Automatic route generation from file structure

πŸ“ Project Structure

nuxt-starter-template/
β”œβ”€β”€ components/
β”‚   └── ui/             # shadcn-vue components (auto-generated)
β”œβ”€β”€ assets/
β”‚   └── css/            # Global styles and Tailwind CSS
β”œβ”€β”€ pages/              # File-based routing pages
β”œβ”€β”€ composables/        # Vue composables (auto-imported)
β”œβ”€β”€ layouts/            # Page layouts
β”œβ”€β”€ middleware/         # Route middleware
β”œβ”€β”€ plugins/            # Nuxt plugins
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ db/             # Database configuration and schema
β”‚   β”‚   β”œβ”€β”€ migrations/ # Database migration files
β”‚   β”‚   └── schema/     # Drizzle schema definitions
β”‚   β”œβ”€β”€ env/            # Environment variable validation
β”‚   β”œβ”€β”€ types/          # TypeScript type definitions
β”‚   └── utils.ts        # Utility functions
β”œβ”€β”€ scripts/
β”‚   └── db/             # Database seeding and utility scripts
β”œβ”€β”€ server/             # Server-side API routes
β”‚   └── api/            # API endpoints
β”œβ”€β”€ public/             # Static assets
β”œβ”€β”€ utils/              # Utility functions (auto-imported)
β”œβ”€β”€ .cursor/rules/      # Cursor AI rules for development
β”œβ”€β”€ nuxt.config.ts      # Nuxt configuration
β”œβ”€β”€ drizzle.config.ts   # Drizzle ORM configuration
β”œβ”€β”€ package.json        # Dependencies and scripts
β”œβ”€β”€ tsconfig.json       # TypeScript configuration
└── eslint.config.ts    # ESLint configuration

πŸ› οΈ Setup

Make sure to install the dependencies:

# pnpm (recommended)
pnpm install

# npm
npm install

# yarn
yarn install

# bun
bun install

πŸ—„οΈ Database Setup

  1. Set up your database (PostgreSQL or Supabase)

  2. Configure environment variables in .env:

    DATABASE_URL="your-postgresql-connection-string"
    # For Supabase (optional)
    SUPABASE_URL="your-supabase-url"
    SUPABASE_ANON_KEY="your-supabase-anon-key"
    SUPABASE_SERVICE_ROLE_KEY="your-supabase-service-key"
  3. Generate and run migrations:

    # Generate migration files from schema changes
    pnpm run db:generate
    
    # Apply migrations to database
    pnpm run db:migrate
    
    # Or push schema directly (development)
    pnpm run db:push
  4. Seed the database (optional):

    # Seed with sample data
    pnpm run db:seed
    
    # Seed with sample users
    pnpm run db:seed:users

πŸš€ Development Server

Start the development server on http://localhost:3000:

# pnpm (recommended)
pnpm run dev

πŸ”§ Available Scripts

# Development
pnpm run dev          # Start development server

# Building
pnpm run build        # Build for production
pnpm run generate     # Generate static site
pnpm run preview      # Preview production build

# Database
pnpm run db:generate  # Generate migration files from schema
pnpm run db:migrate   # Run database migrations
pnpm run db:push      # Push schema to database (development)
pnpm run db:studio    # Open Drizzle Studio (database GUI)
pnpm run db:seed      # Seed database with sample data
pnpm run db:seed:users # Seed database with sample users
pnpm run db:delete-all # Delete all data from database

# Code Quality
pnpm run lint         # Run ESLint
pnpm run lint:fix     # Run ESLint with auto-fix
pnpm run typecheck    # Run TypeScript type checking
pnpm run check        # Run both linting and type checking

# Setup
pnpm run postinstall  # Prepare Nuxt (auto-run after install)

πŸ”” Toast Notifications (vue-sonner + shadcn)

This template includes a global Toaster using vue-sonner, styled via shadcn-vue.

  • Placement: top-center, offset under the sticky navbar. One toast at a time.
  • Progress: custom CSS progress bar driven by --sonner-duration.
  • Accessibility: pointer events enabled to remain interactive over dialogs.

Usage in components:

// composables/useToasts.ts
const { info, success, warning, error, promise } = useToasts();
info("Heads up!", "Informational toast");

Demo buttons are available on the home page (pages/index.vue).

πŸͺ΅ Logging (Pino server + debug client)

Server (Pino):

// Inside a server handler
export default defineEventHandler((event) => {
  event.context.logger.info({ msg: "users:list" });
});

Client (debug):

import { createClientLogger } from "~/lib/logger/client";
const log = createClientLogger("feature:example");
log("clicked with payload %o", payload);

Environment:

# .env
LOG_LEVEL=info
LOG_PRETTY=true        # pretty logs in dev; set false in prod
LOG_REQUESTS=true      # request start/finish logs
LOG_REDACT=["headers.authorization","headers.cookie","body.password","body.token"]
NUXT_PUBLIC_DEBUG=app:*,feature:*

Notes:

  • Request correlation via x-request-id (echoed in response headers)
  • Toggle client logs at runtime: localStorage.debug = 'app:*,feature:*'; location.reload()

πŸ” Authentication (Better Auth)

This template ships with Better Auth fully wired-up for email/password, email verification, password reset, and Google OAuth, with SSR-friendly session handling.

Features

  • Email/password auth with email verification and password reset
  • Social login: Google
  • SSR-safe session refresh and cookie forwarding
  • Route protection via middleware: auth, admin, optional email-verified

Flows & Usage

  • Login/Signup/Logout: handled via authClient in UI forms and useAuth() composable
  • Authenticated routes: add page meta
// pages/any-protected-page.vue
definePageMeta({ middleware: "auth" });

// Admin-only route
definePageMeta({ middleware: "admin" });

// Require verified email (optional)
definePageMeta({ middleware: ["auth", "email-verified"] });
  • Session refresh (SSR-friendly): useAuth().refresh() forwards cookies on server
// useAuth() excerpt showing SSR cookie forwarding for session
// Server: forwards incoming Cookie header to /api/auth/session
// Client: uses credentials: 'include'

API Routes

  • Better Auth handler: server/api/auth/[...all].ts β†’ proxies all Better Auth endpoints under /api/auth/*
  • Session endpoint: server/api/auth/session.get.ts β†’ returns { user, success }, augments user.admin

Environment Variables

Set these in .env (see .env.example for placeholders):

  • Core: NODE_ENV, DATABASE_URL
  • Better Auth: BETTER_AUTH_SECRET, BETTER_AUTH_URL
  • OAuth (Google): GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
  • SMTP (Ethereal/dev): SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASSWORD, SMTP_FROM_NAME, SMTP_FROM_EMAIL

Production guidance:

  • Set BETTER_AUTH_URL to your canonical HTTPS domain
  • Review secure cookie options in Better Auth config before deploying

Local Testing

  • Seed users: pnpm db:seed:users
  • Test credentials: see scripts/docs/test-credentials.md
  • Admin: admin@example.com / admin123

πŸš€ Production

Build the application for production:

# pnpm (recommended)
pnpm run build

Locally preview production build:

# pnpm (recommended)
pnpm run preview

πŸ“š Documentation Links

🎯 Getting Started

  1. Clone this template and install dependencies with pnpm install
  2. Set up your database and configure environment variables
  3. Run database migrations with pnpm run db:push or pnpm run db:migrate
  4. Start development server with pnpm run dev
  5. Add shadcn-vue components with pnpm dlx shadcn-vue@latest add [component-name]
  6. Explore the /pages directory to add your routes
  7. Check /lib/db/schema for database schema definitions
  8. Add icons using the Nuxt Icon module
  9. Manage state with Pinia stores
  10. Validate data using Zod schemas

🎨 Using shadcn-vue Components

# Initialize shadcn-vue (if not already done)
pnpm dlx shadcn-vue@latest init

# Add specific components
pnpm dlx shadcn-vue@latest add button
pnpm dlx shadcn-vue@latest add card dialog

# View all available components
pnpm dlx shadcn-vue@latest add

Components are automatically imported in your Vue files:

<template>
  <div>
    <Button variant="default">
      Click me
    </Button>
    <Card>
      <CardHeader>
        <CardTitle>Hello World</CardTitle>
      </CardHeader>
      <CardContent>
        <p>Your content here</p>
      </CardContent>
    </Card>
  </div>
</template>

πŸ—„οΈ Working with the Database

Define your schema in lib/db/schema/:

import { createId } from "@paralleldrive/cuid2";
// lib/db/schema/users.ts
import { pgTable, text, timestamp } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: text("id").primaryKey().$defaultFn(() => createId()),
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

Use in your API routes:

// server/api/users.get.ts
import { db } from "~/lib/db";
import { users } from "~/lib/db/schema";

export default defineEventHandler(async (event) => {
  const allUsers = await db.select().from(users);
  return allUsers;
});

Happy coding! πŸŽ‰

About

A comprehensive Nuxt 3 template with modern development tools, database integration, and TypeScript support. Features Drizzle ORM, shadcn-vue components, Tailwind CSS, Pinia state management, and more.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors