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 installThis 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 filesThis 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 dialogAvailable 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 devGenerate Drizzle migrations:
npm run generateIntrospect 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:deploynpm 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
useFormStateanduseFormStatushooks - 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_BUCKETenvironment 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: `