logicloom-nextjs-starter
Version:
A production-ready Next.js starter template with authentication, i18n, dark mode, and modern patterns
716 lines (554 loc) • 20.2 kB
Markdown
# Logicloom Starter
A production-ready Next.js starter template with authentication, i18n (multi-language), dark mode, database, and modern patterns.
## ✨ Features
- ✅ Next.js 16 with App Router
- ✅ TypeScript
- ✅ Tailwind CSS v4
- ✅ Shadcn/ui Components
- ✅ **SQLite Database** (better-sqlite3)
- ✅ **Cookie-based Authentication** (HTTP-only cookies)
- ✅ **Password Hashing** (bcryptjs) - Configurable salt rounds
- ✅ **Multi-language Support** (i18n) - English, German, Spanish
- ✅ **Dark Mode / Light Mode**
- ✅ **Protected Routes Middleware** - Automatic auth checking
- ✅ **User Dashboard** - Dropdown menu with navigation
- ✅ Axios for HTTP requests with credentials
- ✅ TanStack Query for data fetching
- ✅ Zod validation (client & server)
- ✅ Custom hooks
- ✅ Session management with refresh tokens
- ✅ **Toast Notifications** (Sonner) - Color-coded error/success/warning
- ✅ **Smart Error Handling** - No duplicate error messages
- ✅ **Auto Redirect** - After login/register
- ✅ Responsive design
- ✅ SEO ready
## 🚀 Quick Start
### Using npx (Recommended)
```bash
# Create a new project
npx logicloom-nextjs-starter my-app
# Navigate to project
cd my-app
# Install dependencies
npm install
# Run development server
npm run dev
# Visit http://localhost:3000
```
### Manual Installation
```bash
# Clone the repository
git clone https://github.com/logicloom-app/logicloom-starter.git my-app
cd my-app
# Install dependencies
npm install
# Run development server
npm run dev
# Visit http://localhost:3000
```
That's it! The SQLite database will be created automatically on first run.
## Project Structure
```
nextjs-starter/
├── src/
│ ├── app/
│ │ ├── (user)/ # User routes group
│ │ │ ├── [...not_found]/ # Catch-all 404 route
│ │ │ │ └── page.tsx
│ │ │ ├── about/ # About page
│ │ │ │ └── page.tsx
│ │ │ ├── auth/ # Authentication page
│ │ │ │ └── page.tsx
│ │ │ ├── contact/ # Contact page
│ │ │ │ └── page.tsx
│ │ │ ├── layout.tsx # User layout
│ │ │ └── not-found.tsx # 404 component
│ │ ├── api/
│ │ │ └── auth/ # Auth API routes
│ │ │ ├── login/ # POST /api/auth/login
│ │ │ │ └── route.ts
│ │ │ ├── logout/ # POST /api/auth/logout
│ │ │ │ └── route.ts
│ │ │ ├── me/ # GET /api/auth/me
│ │ │ │ └── route.ts
│ │ │ ├── refresh/ # POST /api/auth/refresh
│ │ │ │ └── route.ts
│ │ │ └── register/ # POST /api/auth/register
│ │ │ └── route.ts
│ │ ├── favicon.ico
│ │ ├── globals.css # Global styles + Sonner styles
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Home page
│ ├── components/
│ │ ├── auth/
│ │ │ └── auth-form.tsx # Login/Register form with validation
│ │ ├── providers/
│ │ │ ├── query-provider.tsx # TanStack Query provider
│ │ │ └── theme-provider.tsx # Next-themes provider
│ │ ├── ui/ # Shadcn components
│ │ │ ├── button.tsx
│ │ │ ├── card.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── input.tsx
│ │ │ ├── label.tsx
│ │ │ ├── sheet.tsx
│ │ │ └── sonner.tsx # Toast configuration
│ │ ├── footer.tsx # Footer component
│ │ ├── language-switcher.tsx
│ │ └── navbar.tsx # Navbar with user dropdown
│ ├── contexts/
│ │ └── language-context.tsx # i18n context
│ ├── hooks/
│ │ └── use-auth.ts # Auth hooks (login/register/logout/user)
│ ├── lib/
│ │ ├── api/
│ │ │ └── auth.ts # Auth API functions
│ │ ├── validations/
│ │ │ └── auth.ts # Zod schemas
│ │ ├── axios.ts # Axios instance with interceptors
│ │ ├── constants.ts # API endpoints & keys
│ │ ├── db-helpers.ts # Database CRUD helpers
│ │ ├── db.ts # SQLite database setup
│ │ ├── error-handler.ts # Error handling utilities
│ │ ├── storage.ts # Cookie storage helpers
│ │ ├── toast-helpers.ts # Toast notification helpers
│ │ └── utils.ts # Utility functions
│ ├── middleware.ts # Route protection middleware
│ └── types/
│ └── auth.ts # TypeScript types
├── bin/
│ └── create.js # NPX CLI tool
├── public/ # Static assets
├── database.sqlite # SQLite database (auto-created)
├── env.example # Environment variables template
├── ENV_SETUP.md # Environment setup guide
├── package.json
├── tsconfig.json
├── tailwind.config.ts
├── next.config.ts
└── README.md
```
## Database
This template uses **better-sqlite3** - a fast, simple SQLite database that requires no setup!
### Why SQLite?
✅ **Zero configuration** - Just run and it works
✅ **Fast** - Better performance than PostgreSQL for small to medium apps
✅ **Embedded** - No separate database server needed
✅ **Perfect for Next.js** - Works great with serverless
✅ **Easy deployment** - Single file database
### Database Schema
```sql
-- Users table
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
password TEXT NOT NULL, -- bcrypt hashed
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Sessions table
CREATE TABLE sessions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
token TEXT UNIQUE NOT NULL,
expires_at DATETIME NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
```
### Database Helpers
```typescript
import { userHelpers, sessionHelpers } from "@/lib/db-helpers";
// Create user
const userId = userHelpers.create("John", "john@example.com", "password");
// Find user by email
const user = userHelpers.findByEmail("john@example.com");
// Verify password
const isValid = userHelpers.verifyPassword("password", user.password);
// Create session
const token = sessionHelpers.create(userId);
// Find session
const session = sessionHelpers.findByToken(token);
```
## Authentication
### Cookie-Based Auth (HTTP-only)
All tokens are stored in **HTTP-only cookies** for maximum security:
✅ **XSS Protection** - JavaScript cannot access auth tokens
✅ **CSRF Protection** - SameSite=Lax
✅ **Secure** - HTTPS-only in production
✅ **Auto-expiry** - 7 days default
✅ **Dual Cookie System** - Secure tokens + login state flag
✅ **Middleware Protection** - Auto-redirect on protected routes
### Authentication Flow
```
1. User submits login/register form
↓
2. Client: Zod validation
↓
3. Client: Axios POST to API with credentials
↓
4. Server: Zod validation
↓
5. Server: Check/Create user in SQLite
↓
6. Server: Create session token
↓
7. Server: Set HTTP-only cookies (auth_token + user_logged_in flag)
↓
8. Client: Cookies stored automatically
↓
9. Client: Auto-redirect to home page
↓
10. Future requests: Cookies sent automatically
↓
11. Middleware: Protects routes & prevents auth page access when logged in
```
### Protected Routes
The middleware automatically:
- ✅ Redirects logged-in users away from `/auth` page
- ✅ Protects routes like `/dashboard`, `/profile`, `/settings`
- ✅ Allows public routes for everyone
```typescript
// src/middleware.ts
export function middleware(request: NextRequest) {
const authToken = request.cookies.get("auth_token");
const isAuthenticated = !!authToken?.value;
// Redirect logic based on authentication state
if (isAuthenticated && pathname === "/auth") {
return NextResponse.redirect(new URL("/", request.url));
}
// Add more protected routes as needed
}
```
### Using Authentication
```typescript
import { useLogin, useRegister, useLogout, useUser } from "@/hooks/use-auth";
function MyComponent() {
const { data: user, isLoading } = useUser(); // Get current user
const loginMutation = useLogin();
const registerMutation = useRegister();
const logoutMutation = useLogout();
const handleLogin = async () => {
await loginMutation.mutateAsync({
email: "user@example.com",
password: "password123",
});
// ✅ Token automatically stored in HTTP-only cookie
// ✅ User automatically redirected to home page
// ✅ Success toast notification shown
};
const handleLogout = async () => {
await logoutMutation.mutateAsync();
// ✅ Cookies cleared
// ✅ User state reset
};
if (isLoading) return <div>Loading...</div>;
if (user) return <div>Welcome, {user.name}!</div>;
return <button onClick={handleLogin}>Login</button>;
}
```
### Navbar with User Menu
The navbar automatically shows:
- **Not logged in**: Sign In button
- **Logged in**: User dropdown with Dashboard link and Logout option
```typescript
// Navbar automatically handles authentication state
<Navbar />
// Shows user info + dropdown when authenticated
// Shows Sign In button when not authenticated
```
## API Routes
### POST /api/auth/login
```json
{
"email": "user@example.com",
"password": "password123"
}
```
**Response:**
```json
{
"success": true,
"message": "Login successful",
"user": {
"id": "1",
"name": "John Doe",
"email": "user@example.com"
},
"token": "..." // Also set in HTTP-only cookie
}
```
### POST /api/auth/register
```json
{
"name": "John Doe",
"email": "user@example.com",
"password": "password123",
"confirmPassword": "password123"
}
```
### POST /api/auth/logout
No body required. Clears session and cookie.
### GET /api/auth/me
Returns current user. Requires authentication cookie.
## 🛠️ Technologies
- **Next.js 16** - React framework
- **TypeScript** - Type safety
- **Tailwind CSS v4** - Styling
- **Shadcn/ui** - UI components
- **better-sqlite3** - SQLite database
- **bcryptjs** - Password hashing
- **js-cookie** - Cookie management
- **Axios** - HTTP client
- **TanStack Query** - Data fetching
- **Zod** - Validation
- **Sonner** - Toast notifications
- **next-themes** - Dark mode support
- **lucide-react** - Icons
## Toast Notifications
Toast notifications are **color-coded** for better UX:
- 🔴 **Error**: Red background with white text
- 🟢 **Success**: Green background with white text
- 🟡 **Warning**: Yellow background with white text
- 🔵 **Info**: Blue background with white text
### Basic Usage
```typescript
import { toast } from "sonner";
// Success (Green)
toast.success("Success!", {
description: "Your action was completed successfully.",
});
// Error (Red) - Single error, no duplicates!
toast.error("Error!", {
description: "Something went wrong.",
});
// Warning (Yellow)
toast.warning("Warning!", {
description: "Please be careful.",
});
// Info (Blue)
toast.info("Info", {
description: "Here's some information.",
});
// Loading
const loadingToast = toast.loading("Loading...");
// Later dismiss it
toast.dismiss(loadingToast);
// Promise
toast.promise(fetch("/api/data"), {
loading: "Loading...",
success: "Data loaded!",
error: "Failed to load data",
});
```
### Smart Error Handling
The authentication system prevents duplicate error messages:
- ✅ Only **one** toast notification per error
- ✅ User-friendly messages (no technical HTTP codes)
- ✅ Automatic handling by React Query mutations
### Using Toast Helpers
```typescript
import { toastHelpers } from "@/lib/toast-helpers";
// Simple success
toastHelpers.success("Operation successful!");
// With description
toastHelpers.error("Failed to save", "Please try again later.");
// Promise with auto-handling
toastHelpers.promise(apiCall(), {
loading: "Saving...",
success: "Saved successfully!",
error: "Failed to save",
});
```
## Development
### Adding New Tables
Edit `src/lib/db.ts`:
```typescript
db.exec(`
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id)
);
`);
```
### Adding API Endpoints
```typescript
// src/app/api/posts/route.ts
import { NextRequest, NextResponse } from "next/server";
import db from "@/lib/db";
export async function GET(request: NextRequest) {
const posts = db.prepare("SELECT * FROM posts").all();
return NextResponse.json({ posts });
}
```
### Adding Validation
```typescript
// src/lib/validations/post.ts
import { z } from "zod";
export const createPostSchema = z.object({
title: z.string().min(3),
content: z.string().min(10),
});
```
## Deployment
### Vercel (Recommended)
```bash
vercel
```
**Important**: SQLite works on Vercel but data is ephemeral. For production, consider:
- Vercel Postgres
- PlanetScale
- Supabase
### Railway
```bash
railway up
```
SQLite persists on Railway with volume mounts.
### Docker
```bash
docker build -t nextjs-app .
docker run -p 3000:3000 -v $(pwd)/database.sqlite:/app/database.sqlite nextjs-app
```
## Security Features
✅ **HTTP-only cookies** - XSS protection (tokens inaccessible to JavaScript)
✅ **Dual cookie system** - Secure tokens + safe login state flag
✅ **SameSite=Lax** - CSRF protection
✅ **bcrypt hashing** - Configurable salt rounds (default: 10)
✅ **Zod validation** - Client & server-side input sanitization
✅ **Session expiry** - Auto logout after 7 days
✅ **Prepared statements** - SQL injection protection
✅ **Middleware protection** - Route-level authentication checking
✅ **Secure cookies in production** - HTTPS-only when `NODE_ENV=production`
✅ **No token exposure** - Credentials sent via secure cookies only
✅ **Smart error handling** - No information leakage in error messages
## Database Backup
```bash
# Backup
cp database.sqlite database.backup.sqlite
# Restore
cp database.backup.sqlite database.sqlite
```
## Environment Variables
### Development (Optional)
Create `.env.local`:
```env
# Application URL
NEXT_PUBLIC_APP_URL=http://localhost:3000
# API URL (default: /api)
NEXT_PUBLIC_API_URL=/api
# Password hashing strength (10-12 recommended)
BCRYPT_SALT_ROUNDS=10
# Node environment (auto-detected)
NODE_ENV=development
```
### Production (Required)
Set these in your deployment platform:
```env
# REQUIRED
NODE_ENV=production
NEXT_PUBLIC_APP_URL=https://yourdomain.com
# OPTIONAL
BCRYPT_SALT_ROUNDS=12 # Higher for better security
```
### Environment Variables Guide
For a complete guide with all available options, see `ENV_SETUP.md` or check the `env.example` file.
**Available configurations:**
- 🔐 Security (bcrypt, JWT secrets)
- 📧 Email (SMTP, SendGrid, Resend)
- 🔗 OAuth (Google, GitHub)
- 💳 Payments (Stripe)
- ☁️ Cloud Storage (AWS S3)
- 📊 Analytics (Google Analytics)
- 🐛 Monitoring (Sentry)
## FAQ
### Why SQLite?
SQLite is perfect for:
- MVPs and prototypes
- Small to medium applications
- Low-traffic sites
- Development/testing
- Serverless environments (with caveats)
### When to upgrade from SQLite?
Consider PostgreSQL/MySQL when you need:
- High concurrent writes
- Multi-server deployment
- Advanced features (full-text search, JSON queries)
- > 100GB database size
### Can I use PostgreSQL instead?
Yes! Install `pg` and update `src/lib/db.ts`:
```typescript
import { Pool } from "pg";
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
export default pool;
```
## 📦 Installation via npm
This package can be installed and used via npx:
```bash
npx logicloom-nextjs-starter my-project-name
```
This will create a new Next.js project with all the features pre-configured.
## 📝 What's Included
- **Authentication**: Login, Register, Logout with secure cookie-based sessions
- **Protected Routes**: Middleware that auto-protects authenticated routes
- **User Dashboard**: Dropdown menu with user info and navigation
- **Database**: SQLite setup with user and session management
- **Internationalization**: Multi-language support (EN, DE, ES)
- **Dark Mode**: Toggle between light and dark themes
- **UI Components**: Pre-configured Shadcn/ui components
- **Form Validation**: Client and server-side validation with Zod
- **API Routes**: Pre-built auth endpoints with proper error handling
- **Smart Error Handling**: Single toast notifications, no duplicates
- **Auto Redirects**: Automatic navigation after login/register
- **Toast Notifications**: Color-coded for error/success/warning/info
- **Responsive Design**: Mobile-first responsive design
- **Environment Config**: Comprehensive environment variables support
## 🎨 Pages Included
- ✅ **Home page** with hero section and features
- ✅ **About page**
- ✅ **Contact page** with form
- ✅ **Authentication page** with Login/Register toggle
- ✅ **Dashboard** (protected route example)
- ✅ **404 Not Found page**
- ✅ **Navbar** with user dropdown menu
- ✅ **Footer** with links
### Authentication Features
- ✅ Login form with validation
- ✅ Register form with password confirmation
- ✅ Email validation (format checking)
- ✅ Password strength requirements (min 8 chars)
- ✅ Real-time field validation on blur
- ✅ Show/hide password toggles
- ✅ Duplicate email detection with user-friendly error
- ✅ Auto-redirect after successful auth
- ✅ Toast notifications for all actions
- ✅ Loading states during submission
- ✅ Form reset on mode toggle
## 🚀 Recent Updates
### v1.0.1
- ✅ Enhanced authentication with middleware protection
- ✅ Fixed duplicate error messages
- ✅ Added color-coded toast notifications
- ✅ Improved user dropdown menu with dashboard link
- ✅ Auto-redirect after login/register
- ✅ Fixed Next.js 16 theme provider types
- ✅ Added comprehensive environment variables support
- ✅ Improved cookie-based authentication flow
- ✅ Better error handling across the application
## 📄 License
MIT
---
Built with ❤️ using modern Next.js patterns
**Star this repo if you find it helpful! ⭐**
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## 📞 Support
- 🐛 [Report a bug](https://github.com/logicloom-app/logicloom-starter/issues)
- 💡 [Request a feature](https://github.com/logicloom-app/logicloom-starter/issues)
- 📖 [Read the docs](https://github.com/logicloom-app/logicloom-starter#readme)