)
}
```
### 2. Global Loading State
Create `src/app/loading.tsx`:
```typescript
export default function Loading() {
return (
Loading...
)
}
```
### 3. Dashboard Loading State
Create `src/app/dashboard/loading.tsx`:
```typescript
export default function DashboardLoading() {
return (
{[...Array(3)].map((_, i) => (
))}
)
}
```
### 4. Not Found Page
Create `src/app/not-found.tsx`:
```typescript
import Link from 'next/link'
export default function NotFound() {
return (
404
Page Not Found
The page you're looking for doesn't exist.
Go to Dashboard
)
}
```
---
## TypeScript Configuration
### 1. Enhanced tsconfig.json
Update your `tsconfig.json`:
```json
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"],
"@/lib/*": ["./src/lib/*"],
"@/types/*": ["./src/types/*"],
"@/app/*": ["./src/app/*"],
"@/hooks/*": ["./src/hooks/*"]
},
"target": "ES2017",
"forceConsistentCasingInFileNames": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": ["node_modules"]
}
```
### 2. Type Definitions
Create `src/types/auth.ts`:
```typescript
export interface User {
id: string
email: string
created_at: string
}
export interface Session {
user: User
access_token: string
refresh_token: string
}
```
Create `src/types/tasks.ts`:
```typescript
export interface Task {
id: string
title: string
description: string | null
completed: boolean
user_id: string
created_at: string
updated_at: string
}
export interface CreateTaskData {
title: string
description?: string
}
export interface UpdateTaskData {
title?: string
description?: string | null
completed?: boolean
}
```
---
## Deployment & Production
### 1. Next.js Configuration
Update `next.config.ts`:
```typescript
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
experimental: {
// Enable React Compiler (experimental)
reactCompiler: false, // Set to true when ready for production
// Enable typed routes
typedRoutes: true,
},
// TypeScript configuration
typescript: {
ignoreBuildErrors: false,
},
// ESLint configuration
eslint: {
ignoreDuringBuilds: false,
},
// Images configuration for Supabase storage
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '*.supabase.co',
port: '',
pathname: '/storage/v1/object/public/**',
},
],
},
// Security headers
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin',
},
],
},
]
},
}
export default nextConfig
```
### 2. Environment Variables for Production
Create `.env.example`:
```env
# Supabase Configuration
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# Optional: For admin operations (keep secure)
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Next.js
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-nextauth-secret
```
### 3. Deployment Checklist
**Before deploying:**
1. ✅ Test authentication flow completely
2. ✅ Verify RLS policies work correctly
3. ✅ Test all CRUD operations
4. ✅ Check error handling works
5. ✅ Verify environment variables are set
6. ✅ Test responsive design
7. ✅ Run type checking: `npm run type-check`
8. ✅ Run linting: `npm run lint`
9. ✅ Build successfully: `npm run build`
**Deployment platforms:**
- **Vercel** (Recommended): Connect your GitHub repo and deploy automatically
- **Netlify**: Similar to Vercel with good Next.js support
- **Railway**: Good for full-stack apps with databases
- **AWS Amplify**: Enterprise-grade with extensive AWS integration
### 4. Production Environment Setup
**For Vercel deployment:**
1. Push your code to GitHub
2. Connect repository to Vercel
3. Add environment variables in Vercel dashboard
4. Enable preview deployments for testing
5. Set up custom domain if needed
**Environment variables to set:**
- `NEXT_PUBLIC_SUPABASE_URL`
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
- `SUPABASE_SERVICE_ROLE_KEY` (if using admin operations)
---
## Complete Code Examples
### 1. Root Layout
Create/Update `src/app/layout.tsx`:
```typescript
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import './globals.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata: Metadata = {
title: 'Next.js + Supabase App',
description: 'A modern full-stack application built with Next.js and Supabase',
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
{children}
)
}
```
### 2. Home Page with Authentication Check
Update `src/app/page.tsx`:
```typescript
import { createClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
import Link from 'next/link'
export default async function Home() {
const supabase = await createClient()
const { data: { user } } = await supabase.auth.getUser()
if (user) {
redirect('/dashboard')
}
return (
Welcome to Next.js + Supabase
A modern full-stack application template
Get Started
View on GitHub
)
}
```
### 3. Dashboard Layout with Navigation
Create `src/app/dashboard/layout.tsx`:
```typescript
import { verifySession } from '@/lib/dal'
export default async function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
// This ensures the user is authenticated before accessing any dashboard pages
await verifySession()
return (
{children}
)
}
```
### 4. Package.json Scripts
Update your `package.json` scripts:
```json
{
"scripts": {
"dev": "next dev --turbo",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit",
"db:types": "npx supabase gen types typescript --project-id YOUR_PROJECT_ID > src/types/database.types.ts"
}
}
```
### 5. Custom Hook for Authentication
Create `src/hooks/use-auth.ts`:
```typescript
'use client'
import { createClient } from '@/lib/supabase/client'
import { useEffect, useState } from 'react'
import type { User } from '@supabase/supabase-js'
export function useAuth() {
const [user, setUser] = useState(null)
const [loading, setLoading] = useState(true)
const supabase = createClient()
useEffect(() => {
const getUser = async () => {
const { data: { user } } = await supabase.auth.getUser()
setUser(user)
setLoading(false)
}
getUser()
const { data: { subscription } } = supabase.auth.onAuthStateChange(
async (event, session) => {
setUser(session?.user ?? null)
setLoading(false)
}
)
return () => subscription.unsubscribe()
}, [supabase.auth])
return { user, loading }
}
```
---
## Quick Start Commands
**Clone and setup:**
```bash
# Create new project
npx create-next-app@latest my-supabase-app
# Install dependencies
cd my-supabase-app
npm install @supabase/supabase-js @supabase/ssr
# Setup environment
cp .env.example .env.local
# Edit .env.local with your Supabase credentials
# Generate database types
npm run db:types
# Start development server
npm run dev
```
**Development workflow:**
```bash
# Start development
npm run dev
# Type checking
npm run type-check
# Linting
npm run lint
# Build for production
npm run build
# Start production server
npm start
```
---
## Troubleshooting
### Common Issues & Solutions
**1. "Cannot read properties of undefined (reading 'getUser')"**
- Ensure you're using the correct client (server vs browser)
- Check that environment variables are set correctly
**2. "Row Level Security policy violation"**
- Make sure you're authenticated when performing database operations
- Verify your RLS policies are correctly configured
- Check that `auth.uid()` matches your user_id field
**3. "Module not found: Can't resolve '@/...'"**
- Verify your `tsconfig.json` paths configuration
- Ensure you're using the correct import paths
**4. Authentication redirects not working**
- Check your middleware configuration
- Verify the redirect URLs in your Supabase auth settings
- Ensure cookies are being set correctly
**5. Build errors in production**
- Run `npm run type-check` to catch TypeScript errors
- Check that all environment variables are set in production
- Verify Next.js configuration is correct
### Performance Tips
1. **Use Server Components when possible** - They're faster and don't increase bundle size
2. **Implement proper loading states** - Better user experience
3. **Use React Suspense** - For progressive loading
4. **Optimize images** - Use Next.js Image component
5. **Enable caching** - Use Next.js built-in caching strategies
---
## Additional Resources
- **Next.js Documentation**: [nextjs.org/docs](https://nextjs.org/docs)
- **Supabase Documentation**: [supabase.com/docs](https://supabase.com/docs)
- **Tailwind CSS**: [tailwindcss.com](https://tailwindcss.com)
- **TypeScript**: [typescriptlang.org](https://typescriptlang.org)
This guide provides a complete foundation for building modern, production-ready applications with Next.js and Supabase. Save this guide and refer to it whenever you need to set up a new project or implement specific features!