Nuxt 3 SaaS Boilerplate: Complete Setup Guide

Learn how to set up a production-ready Nuxt 3 SaaS project with essential modules like Nuxt UI, Pinia, VueUse, and more. This comprehensive guide covers everything from initial setup to deployment configuration.

Essential Modules for Nuxt SaaS

  • 📦 Nuxt UI - A fully styled and customizable component library that follows Vue best practices. Perfect for rapid UI development with a professional look.
  • 📦 Pinia - Vue's official state management solution. Provides a simple and type-safe way to manage application state with DevTools support.
  • 📦 Pinia Persisted Store - Automatically persists your Pinia store data in localStorage, maintaining user state across page reloads.
  • 📦 VueUse - Collection of essential Vue composition utilities for common tasks like state handling, animations, and browser APIs.
  • 📦 PostHog - Open-source product analytics platform for tracking user behavior, feature flags, and A/B testing in your SaaS application.

Initial Project Setup

Initialize Nuxt Project

Start by creating and configuring your new Nuxt project:

bash
# Initialize new Nuxt project
npx nuxi@latest init <my-app>
cd <my-app>

# Open folder in Cursor IDE
cursor .

# Configure Git
echo .yarn >> .gitignore

# Install dependencies
yarn install

Configure CursorRules for Nuxt Project

CursorRules help maintain consistent coding standards and best practices across your Nuxt project. Create a .cursorrules file in your project root folder with these guidelines:

.cursorrules
markdown
# Content for your .cursorrules file:

# Project Technology Stack and Preferences

This is a Nuxt 3 project that follows these technical guidelines:

Framework & Core:
- Nuxt 3 as the main framework
- TypeScript for type safety
- Vue 3 Composition API preferred over Options API

UI & Styling:
- Nuxt UI for component library
- Tailwind CSS for styling
- Avoid inline styles when possible
- Follow Nuxt UI design patterns and conventions

State Management & Utilities:
- Pinia for state management
- VueUse for composition utilities
- Prefer using 'npx nuxi@latest module add' for adding new modules and functionality

Code Style:
- Use TypeScript for all new files
- Prefer Composition API with <script setup lang="ts"> syntax
- Use proper type annotations
- Follow Vue 3 best practices
- Use ES6+ features
- Keep components single-responsibility
- Use composables for reusable logic
- For .vue files, maintain section order: <template>, <script>, <style>

File Structure:
- Follow Nuxt 3 directory structure conventions
- Keep components modular and reusable
- Use proper naming conventions (PascalCase for components, camelCase for files)

When suggesting code:
- Include TypeScript types
- Use Nuxt 3 built-in composables when applicable
- Leverage Nuxt UI components and utilities
- Implement proper error handling
- Consider performance implications

Save Initial Configuration

Commit your initial project setup:

bash
# Commit initial setup
git add .
git commit -m 'initial'

Adding Essential Modules

Add the following modules: Nuxt UI, Pinia, Pinia Persisted Store, VueUse

bash
npx nuxi@latest module add ui
npx nuxi@latest module add pinia
yarn add pinia-plugin-persistedstate
npx nuxi@latest module add vueuse
npx nuxi@latest module add nuxt-posthog
yarn install

Configuration

Update your nuxt.config.ts with these configurations:

nuxt.config.ts
typescript
modules: [
  '@nuxt/ui',
  '@pinia/nuxt',
  'pinia-plugin-persistedstate/nuxt',
  '@vueuse/nuxt',
  'nuxt-posthog',
]

Add persistent storage config to store data by default in browser's localStorage:

nuxt.config.ts
typescript
piniaPluginPersistedstate: {
  storage: 'localStorage',
}

Configure Posthog:

nuxt.config.ts
typescript
posthog: {
  disabled: "prerender" === 'development',
  host: 'https://eu.i.posthog.com',
  publicKey: 'yourkey',
}

Commit Changes

bash
git add .
git commit -m 'installed essential modules'

Development Server Configuration

It's recommended to assign a unique port for your development server to prevent conflicts between different local projects. This helps avoid issues with browser caching, localStorage, and service workers that might be shared across projects running on the default port.

nuxt.config.ts
typescript
devServer: {
  host: '0.0.0.0',
  port: 3008,
}

Taskfile Setup

Taskfile.yml
yaml
version: "3"

tasks:
  setup:
    desc: Setup the application
    cmds:
      - yarn install

  dev:
    desc: Start the development server
    cmds:
      - yarn dev

  ngrok:
    desc: Start ngrok
    cmds:
      - ngrok http 3008

  deploy:
    desc: Deploy the application
    cmds:
      - ./deploy.sh

  preview:
    desc: Locally run production build
    cmds:
      - yarn build
      - qrlocal 3008 || true
      - NITRO_PORT=3008 yarn preview
  
  preview:static:
    desc: Locally preview production static build
    cmds:
      - yarn generate
      - qrlocal 3008 || true
      - npx serve -l 3008 .output/public

Deployment Scripts

Version Info Generator

Create a script to generate deployment version information:

make_deploy_info.sh
bash
#!/bin/bash

# Get current date in YYYY-MM-DD format
DATE=$(date +%Y-%m-%d)

# Get the latest commit SHA and message
COMMIT_SHA=$(git rev-parse --short=4 HEAD)
COMMIT_MSG=$(git log -1 --pretty=%B)

# Create version string
VERSION="${DATE}-${COMMIT_SHA}"

# Create deployment info JSON
echo "{
  \"version\": \"${VERSION}\",
  \"info\": \"${COMMIT_MSG}\"
}"

Deployment Script

Create the main deployment script that uses the version info generator:

deploy.sh
bash
#!/bin/bash

# Generate deployment info
./make_deploy_info.sh > public/deploy-info.json

# TODO: Write your own deployment script
# Deploy to railway example
# railway up --ci

# Clean up
rm -rf public/deploy-info.json

Final Commit

bash
git add .
git commit -m 'taskfile and deployment script'

Installing Icon Packs

Coming soon: Guide for installing and configuring icon packs.