I recently came across Supabase, and I have to say I’m really excited about it. Supabase is a Backend-as-a-Service (BaaS) that provides authentication, a Postgres database, real-time subscriptions, and storage right out of the box. What I like the most is how simple it is to learn and how seamlessly it integrates with a React project.
This is the first post in a series on Supabase integration with React. I'll keep things as simple as possible, starting with the basics: setting up a React + TypeScript project, connecting it to Supabase, and building a clean authentication flow with signup, login, and logout, styled using TailwindCSS.
Setting up Supabase
- Go to supabase.com and sign up.
- Create a new project. Once it's ready, note down your Project URL and anon API key from the dashboard.
- In the Authentication settings, enable Email/Password login.
Creating a React + TypeScript Project
We'll start fresh with Vite.
npx create-vite@latest supabase-auth-demo --template react-ts
cd supabase-auth-demo
npm install
npm install @supabase/supabase-js tailwindcss postcss autoprefixer
npx tailwindcss init -p
Set up Tailwind in tailwind.config.js:
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {},
},
plugins: [],
Add Tailwind to src/index.css:
@tailwind base;
@tailwind components;
@tailwind utilities;
Initializing Supabase
Create a new file src/supabaseClient.ts
:
import { createClient } from "@supabase/supabase-js";
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL as string;
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY as string;
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
Add your Supabase credentials to .env
:
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
Building the Authentication UI
We'll build a simple form with React and TailwindCSS for signup, login, and logout.
import { useState } from "react";
import { supabase } from "./supabaseClient";
export default function Auth() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useState<any>(null);
const [error, setError] = useState("");
const handleSignup = async () => {
const { data, error } = await supabase.auth.signUp({ email, password });
if (error) setError(error.message);
else setUser(data.user);
};
const handleLogin = async () => {
const { data, error } = await supabase.auth.signInWithPassword({ email, password });
if (error) setError(error.message);
else setUser(data.user);
};
const handleLogout = async () => {
await supabase.auth.signOut();
setUser(null);
};
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
<div className="bg-white shadow-md rounded-lg p-6 w-80">
<h2 className="text-2xl font-bold text-center mb-4">Supabase Auth</h2>
{error && <p className="text-red-500 text-sm mb-2">{error}</p>}
{!user ? (
<>
<input
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full mb-3 px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full mb-3 px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
<div className="flex gap-2">
<button
onClick={handleSignup}
className="w-1/2 bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700"
>
Sign Up
</button>
<button
onClick={handleLogin}
className="w-1/2 bg-green-600 text-white py-2 rounded-lg hover:bg-green-700"
>
Login
</button>
</div>
</>
) : (
<div className="text-center">
<p className="mb-4">Logged in as {user.email}</p>
<button
onClick={handleLogout}
className="w-full bg-red-600 text-white py-2 rounded-lg hover:bg-red-700"
>
Logout
</button>
</div>
)}
</div>
</div>
);
}
Persisting the User Session
You can fetch the current session when the app loads:
import { useEffect } from "react";
useEffect(() => {
supabase.auth.getSession().then(({ data }) => {
console.log("Session:", data.session);
});
}, []);
Wrapping Up
We just set up a Supabase-powered authentication system in React with TypeScript, complete with signup, login, and logout, all styled using TailwindCSS. This is a solid starting point for any app that needs user authentication.
In the next part of this series, we'll explore Supabase Edge Functions and how to build custom APIs for your application.
If you found this post valuable, consider sharing it with others who might benefit from it as well!
Top comments (0)