This is a modern web application built with Next.js, using Drizzle ORM with Supabase as the database, and deployed on Cloudflare Pages.
- Node.js 18 or later
- npm or yarn
- Supabase account
- Cloudflare account
Create a .env.local
file in the root directory with the following variables:
NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
- Clone the repository:
git clone <your-repo-url>
cd next-drizzle-supabase
- Install dependencies:
npm install
This project uses several tools to ensure code quality and consistent formatting:
-
Prettier for code formatting:
npm run format # Format all files
-
ESLint for code linting:
npm run lint # Run ESLint
-
Git Hooks (using Husky):
- Pre-commit hook automatically formats and lints staged files
- Ensures consistent code style across the team
- Prevents commits with formatting issues
The following files are automatically formatted on commit:
- JavaScript/TypeScript files (
.js
,.jsx
,.ts
,.tsx
) - Configuration files (
.json
,.yml
) - Markdown files (
.md
)
To manually run formatting checks:
npx lint-staged # Check staged files only
npm run format # Format all files
This project uses shadcn/ui for beautiful and accessible components. To add new components:
- Install the shadcn CLI:
npm install -D @shadcn/ui
- Initialize shadcn/ui (if not already initialized):
npx shadcn-ui@latest init
- Add new components as needed:
npx shadcn-ui@latest add [component-name]
# For example:
npx shadcn-ui@latest add button
npx shadcn-ui@latest add dialog
Available components can be found at shadcn/ui website
This project uses next/font
for optimized font loading:
- Inter for main text (sans-serif)
- JetBrains Mono for monospace text
Benefits:
- Zero layout shift
- Built-in performance optimizations
- Self-hosted fonts (no external requests)
- Automatic font subsetting
Usage in components:
// Default text uses Inter
<p>This uses Inter font</p>
// For monospace text
<code className="font-mono">This uses JetBrains Mono</code>
Font configuration can be found in src/lib/fonts.ts
.
Run the development server:
npm run dev
Generate Drizzle migrations:
npm run generate
Introspect database:
npm run introspect
- Install Cloudflare Pages dependencies:
npm install --save-dev @cloudflare/next-on-pages wrangler
- Build for Cloudflare Pages:
npm run pages:build
- Login to Cloudflare (if not already):
npx wrangler login
- Deploy to Cloudflare Pages:
npm run pages:deploy
npm run dev
- Start development servernpm run build
- Build the applicationnpm run start
- Start production servernpm run lint
- Run ESLintnpm run generate
- Generate Drizzle migrationsnpm run introspect
- Introspect database schemanpm run pages:build
- Build for Cloudflare Pagesnpm run pages:deploy
- Deploy to Cloudflare Pagesnpm run pages:watch
- Watch mode for Cloudflare Pagesnpm run pages:dev
- Local development with Cloudflare Pages
├── src/
│ ├── app/ # Next.js app directory
│ ├── components/ # React components
│ ├── lib/ # Utility functions and configurations
│ ├── providers/ # React context providers
│ └── db/ # Database schemas and configurations
├── .cloudflare/ # Cloudflare configuration
├── public/ # Static assets
└── package.json # Project dependencies and scripts
-
When deploying to Cloudflare Pages, make sure to:
- Add your environment variables in the Cloudflare Pages dashboard
- Configure your custom domain if needed
- Set up any required build settings
-
For local development with Cloudflare Pages:
npm run pages:dev
-
To watch for changes during development:
npm run pages:watch
- Authentication using Supabase Auth
- File Uploads using Supabase Storage
- Database access with Drizzle ORM
- Full Row Level Security (RLS) support
- Dark Mode with Theme Provider
- Form state management using the new
useFormState
anduseFormStatus
hooks - Fully responsive design using Tailwind CSS
create role app_user with login password 'app_user';
grant select, insert, update, delete on all tables in schema public to app_user;
alter default privileges in schema public grant select, insert, update, delete on tables to app_user;
Use the dashboard to enable RLS policies for each table.
- Create a new storage bucket and set the
STORAGE_BUCKET
environment variable to the bucket name. - Create the following storage policies for the bucket:
- Name:
Access own files
- Allowed operation:
SELECT
- Target roles: (default)
- Policy definition:
bucket_id = 'Files' and owner_id = auth.uid()::text and (storage.foldername(name))[1] = auth.uid()::text
- Name:
Allow upload
- Allowed operation:
INSERT
- Target roles: (default)
- Policy definition:
bucket_id = 'Files' and (storage.foldername(name))[1] = auth.uid()::text
- Name:
Delete own files
- Allowed operation: `