Next.js + Supabase Starter
Jumpstart your full-stack project with Next.js and Supabase. Authentication, database, and API routes - all set up and ready to go!
best for e-commerce, SaaS, Dashboards.
Key Features
âš¡ Next.js 13 App Router
Leverage the latest Next.js features with the App Router
âš¡ Supabase Authentication
Pre-configured authentication with Supabase
âš¡ Supabase Database
Easy database setup and management with Supabase
âš¡ Tailwind CSS & shadcn/ui
Styled components ready to use.
âš¡ React Hook Form
Efficient and flexible form handling with ZOD validation integrated.
âš¡ TypeScript Support
Type Safe with typescript error handling.
âš¡ React Query Integration
Efficient data fetching, caching, and synchronization.
âš¡ Built-in Hooks
Custom hooks for fetching and mutating data with optimistic updates.
âš¡ Uses pnpm
Using pnpm for faster installs and efficient dependency handling.
Get Started
To get started with this Next.js and Supabase starter, follow these steps to start effortlessly:
- Create a new project using the CLI:
npx create-next-supabase-starter my-project
- Navigate to your project folder:
cd my-project
- Set up your environment variables: Rename the
.env.example
file to.env.local
and update it with your Supabase credentials.NEXT_PUBLIC_SUPABASE_URL
,NEXT_PUBLIC_SUPABASE_ANON_KEY
- Install dependencies using pnpm if it's skipped:
pnpm install
- Run the development server:
pnpm dev
Once the setup is complete, open http://localhost:3000 in your browser to explore your project.
For more detailed instructions, check out the README in the GitHub repository.
Documentation
Learn how to use the prebuilt components, hooks, and utilities included in this starter. Below are some essential parts of the system to help you quickly integrate and expand upon this project.
🔹 Fetching Data
import { useClientFetch } from "@/hooks/useClientFetch"; const Posts = () => { const { data, isLoading } = useClientFetch("posts", "posts"); if (isLoading) return <p>Loading...</p>; return ( <ul> {data?.map((post) => ( <li key={post.id}>{post.name}</li> ))} </ul> ); };
🔹 Mutations
import { useClientMutate } from "@/hooks/useClientMutate"; const AddPost = () => { const mutation = useClientMutate("posts", "insert"); const handleSubmit = async () => { mutation.mutate({ id: Date.now(), name: "New Post" }); }; return <button onClick={handleSubmit}>Add Post</button>; };
🔹 Advanced Hooks Usage
The starter includes powerful hooks to handle complex use cases. Here are some advanced examples:
🔸 Fetching Data with Filters
const FilteredUsers = () => { const { data, isLoading } = useClientFetch( "filtered-users", // key "users", // table name 5000, // cache time (query) => query.eq("role", "admin") // Supabase query filter ); if (isLoading) return <p>Loading...</p>; return ( <ul> {data?.map((user) => ( <li key={user.id}>{user.name} ({user.role})</li> ))} </ul> ); };
🔸 Mutating with Optimistic Updates
import { useClientMutate } from "@/hooks/useClientMutate"; import { useQueryClient } from "@tanstack/react-query"; const queryClient = useQueryClient(); const mutation = useClientMutate("posts", "update", { onMutate: async (newData) => { await queryClient.cancelQueries(["posts"]); const previousData = queryClient.getQueryData(["posts"]); queryClient.setQueryData(["posts"], (oldData) => oldData?.map(post => (post.id === newData.id ? { ...post, ...newData } : post)) ); return { previousData }; }, onError: (err, newData, context) => { queryClient.setQueryData(["posts"], context.previousData); }, onSettled: () => { queryClient.invalidateQueries(["posts"]); }, }); mutation.mutate({ id: 1, name: "Updated Post" });
🔸 Subscribing to Real-Time Data
import { useEffect, useState } from "react"; import { createClient } from "@/supabase/client; const supabase = createClient() const [messages, setMessages] = useState([]); useEffect(() => { const subscription = supabase .from("messages") .on("INSERT", (payload) => { setMessages((prev) => [...prev, payload.new]); }) .subscribe(); return () => { supabase.removeSubscription(subscription); }; }, []);