mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 21:05:06 +03:00
* Draft * Simplify code * Add env var step * Update apps/docs/content/guides/auth/quickstarts/react.mdx Co-authored-by: John Schaeffer <john@schaeffer.io> * Update apps/docs/content/guides/auth/quickstarts/react.mdx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update apps/docs/content/guides/auth/quickstarts/react.mdx Co-authored-by: John Schaeffer <john@schaeffer.io> * Update apps/docs/content/guides/auth/quickstarts/react.mdx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Remove partial and change log in text --------- Co-authored-by: John Schaeffer <john@schaeffer.io> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
286 lines
8.8 KiB
Plaintext
286 lines
8.8 KiB
Plaintext
---
|
|
title: 'Use Supabase Auth with React'
|
|
subtitle: 'Learn how to use Supabase Auth with React.js.'
|
|
breadcrumb: 'Auth Quickstarts'
|
|
hideToc: true
|
|
---
|
|
|
|
<StepHikeCompact>
|
|
|
|
<StepHikeCompact.Step step={1}>
|
|
<StepHikeCompact.Details title="Create a new Supabase project">
|
|
|
|
[Launch a new project](/dashboard) in the Supabase Dashboard.
|
|
|
|
Your new database has a table for storing your users. You can see that this table is currently empty by running some SQL in the [SQL Editor](/dashboard/project/_/sql).
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
<StepHikeCompact.Code>
|
|
|
|
```sql name=SQL_EDITOR
|
|
select * from auth.users;
|
|
````
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
|
|
<StepHikeCompact.Step step={2}>
|
|
|
|
<StepHikeCompact.Details title="Create a React app">
|
|
|
|
Create a React app using a [Vite](https://vitejs.dev/guide/) template.
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
<StepHikeCompact.Code>
|
|
|
|
```bash name=Terminal
|
|
npm create vite@latest my-app -- --template react
|
|
```
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
|
|
<StepHikeCompact.Step step={3}>
|
|
<StepHikeCompact.Details title="Install the Supabase client library">
|
|
|
|
Navigate to the React app and install the Supabase libraries.
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
<StepHikeCompact.Code>
|
|
|
|
```bash name=Terminal
|
|
cd my-app && npm install @supabase/supabase-js
|
|
```
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
<StepHikeCompact.Step step={4}>
|
|
<StepHikeCompact.Details title="Declare Supabase Environment Variables">
|
|
|
|
Create `.env.local` and populate with your project's URL and Key.
|
|
|
|
<$Partial path="api_settings_steps.mdx" />
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
<StepHikeCompact.Code>
|
|
|
|
```text name=.env.local
|
|
VITE_SUPABASE_URL=your-project-url
|
|
VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY=sb_publishable_... or anon key
|
|
```
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
<StepHikeCompact.Step step={5}>
|
|
<StepHikeCompact.Details title="Set up your login component">
|
|
|
|
<$Partial path="uiLibCta.mdx" />
|
|
|
|
In `App.jsx`, create a Supabase client using your Project URL and key.
|
|
|
|
You can configure the Auth component to display whenever there is no session inside `supabase.auth.getSession()`
|
|
|
|
</StepHikeCompact.Details>
|
|
<StepHikeCompact.Code>
|
|
|
|
```jsx name=src/App.jsx
|
|
import "./index.css";
|
|
import { useState, useEffect } from "react";
|
|
import { createClient } from "@supabase/supabase-js";
|
|
|
|
const supabase = createClient(import.meta.env.VITE_SUPABASE_URL, import.meta.env.VITE_SUPABASE_PUBLISHABLE_DEFAULT_KEY);
|
|
|
|
export default function App() {
|
|
const [loading, setLoading] = useState(false);
|
|
const [email, setEmail] = useState("");
|
|
const [session, setSession] = useState(null);
|
|
|
|
// Check URL params on initial render
|
|
const params = new URLSearchParams(window.location.search);
|
|
const hasTokenHash = params.get("token_hash");
|
|
|
|
const [verifying, setVerifying] = useState(!!hasTokenHash);
|
|
const [authError, setAuthError] = useState(null);
|
|
const [authSuccess, setAuthSuccess] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Check if we have token_hash in URL (magic link callback)
|
|
const params = new URLSearchParams(window.location.search);
|
|
const token_hash = params.get("token_hash");
|
|
const type = params.get("type");
|
|
|
|
if (token_hash) {
|
|
// Verify the OTP token
|
|
supabase.auth.verifyOtp({
|
|
token_hash,
|
|
type: type || "email",
|
|
}).then(({ error }) => {
|
|
if (error) {
|
|
setAuthError(error.message);
|
|
} else {
|
|
setAuthSuccess(true);
|
|
// Clear URL params
|
|
window.history.replaceState({}, document.title, "/");
|
|
}
|
|
setVerifying(false);
|
|
});
|
|
}
|
|
|
|
// Check for existing session
|
|
supabase.auth.getSession().then(({ data: { session } }) => {
|
|
setSession(session);
|
|
});
|
|
|
|
// Listen for auth changes
|
|
const {
|
|
data: { subscription },
|
|
} = supabase.auth.onAuthStateChange((_event, session) => {
|
|
setSession(session);
|
|
});
|
|
|
|
return () => subscription.unsubscribe();
|
|
}, []);
|
|
|
|
const handleLogin = async (event) => {
|
|
event.preventDefault();
|
|
setLoading(true);
|
|
const { error } = await supabase.auth.signInWithOtp({
|
|
email,
|
|
options: {
|
|
emailRedirectTo: window.location.origin,
|
|
}
|
|
});
|
|
if (error) {
|
|
alert(error.error_description || error.message);
|
|
} else {
|
|
alert("Check your email for the login link!");
|
|
}
|
|
setLoading(false);
|
|
};
|
|
|
|
const handleLogout = async () => {
|
|
await supabase.auth.signOut();
|
|
setSession(null);
|
|
};
|
|
|
|
// Show verification state
|
|
if (verifying) {
|
|
return (
|
|
<div>
|
|
<h1>Authentication</h1>
|
|
<p>Confirming your magic link...</p>
|
|
<p>Loading...</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Show auth error
|
|
if (authError) {
|
|
return (
|
|
<div>
|
|
<h1>Authentication</h1>
|
|
<p>✗ Authentication failed</p>
|
|
<p>{authError}</p>
|
|
<button
|
|
onClick={() => {
|
|
setAuthError(null);
|
|
window.history.replaceState({}, document.title, "/");
|
|
}}
|
|
>
|
|
Return to login
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Show auth success (briefly before session loads)
|
|
if (authSuccess && !session) {
|
|
return (
|
|
<div>
|
|
<h1>Authentication</h1>
|
|
<p>✓ Authentication successful!</p>
|
|
<p>Loading your account...</p>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// If user is logged in, show welcome screen
|
|
if (session) {
|
|
return (
|
|
<div>
|
|
<h1>Welcome!</h1>
|
|
<p>You are logged in as: {session.user.email}</p>
|
|
<button onClick={handleLogout}>
|
|
Sign Out
|
|
</button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
// Show login form
|
|
return (
|
|
<div>
|
|
<h1>Supabase + React</h1>
|
|
<p>Sign in via magic link with your email below</p>
|
|
<form onSubmit={handleLogin}>
|
|
<input
|
|
type="email"
|
|
placeholder="Your email"
|
|
value={email}
|
|
required={true}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
/>
|
|
<button disabled={loading}>
|
|
{loading ? <span>Loading</span> : <span>Send magic link</span>}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
```
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
|
|
<StepHikeCompact.Step step={6}>
|
|
<StepHikeCompact.Details title="Customize email template">
|
|
|
|
Before proceeding, change the email template to support support a server-side authentication flow that sends a token hash:
|
|
|
|
- Go to the [Auth templates](/dashboard/project/_/auth/templates) page in your dashboard.
|
|
- Select the Confirm sign up template.
|
|
- Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}?token_hash={{ .TokenHash }}&type=email`.
|
|
- Change your [Site URL](/dashboard/project/_/auth/url-configuration) to `https://localhost:5173`
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
</StepHikeCompact.Step>
|
|
|
|
<StepHikeCompact.Step step={7}>
|
|
<StepHikeCompact.Details title="Start the app">
|
|
|
|
Start the app, go to http://localhost:5173 in a browser, and open the browser console and you should be able to register and log in.
|
|
|
|
</StepHikeCompact.Details>
|
|
|
|
<StepHikeCompact.Code>
|
|
|
|
```bash name=Terminal
|
|
npm run dev
|
|
```
|
|
|
|
</StepHikeCompact.Code>
|
|
|
|
</StepHikeCompact.Step>
|
|
|
|
</StepHikeCompact>
|