Quickstart with Supabase
Intro
Supabase is an open-source Firebase alternative.
This quickstart is a simple example showcasing how to use Supabase with Plasmo.
Prerequisites
- Supabase (opens in a new tab) Account
- Supabase project
Set up Environment Variables
For Supabase to work, we'll need to define a URL and a KEY.
You can find these by finding them in your Supabase project dashboard:
We need to declare a ProcessEnv namespace for our environment variables so that IntelliSense will work.
index.d.ts
index.d.ts
declare namespace NodeJS {
interface ProcessEnv {
PLASMO_PUBLIC_SUPABASE_URL?: string
PLASMO_PUBLIC_SUPABASE_KEY?: string
}
}
.env.local
PLASMO_PUBLIC_SUPABASE_URL="CHANGE ME"
PLASMO_PUBLIC_SUPABASE_KEY="CHANGE ME"
Supabase Store
We need to initialize Supabase, so let's add a file called store.
core/store.ts
import { createClient } from "@supabase/supabase-js"
export const supabase = createClient(
process.env.PLASMO_PUBLIC_SUPABASE_URL,
process.env.PLASMO_PUBLIC_SUPABASE_KEY
)
Integrating with a React component
Now we can write code in our React components utilizing Supabase!
Here's an example of using Supabase in a React component for the extension's options page.
options.tsx
import type { User } from "@supabase/supabase-js"
import { useState } from "react"
import { supabase } from "~core/store"
function IndexOptions() {
const [username, setUsername] = useState("")
const [password, setPassword] = useState("")
const [user, setUser] = useState<User>(null)
const handleLogin = async (
type: "LOGIN" | "SIGNUP",
username: string,
password: string
) => {
try {
const { error, user: signedInUser } =
type === "LOGIN"
? await supabase.auth.signIn(
{ email: username, password },
{
redirectTo: window.location.href
}
)
: await supabase.auth.signUp(
{ email: username, password },
{
redirectTo: window.location.href
}
)
if (error) {
alert("Error with auth: " + error.message)
} else if (!signedInUser) {
alert("Signup successful, confirmation mail should be sent soon!")
} else {
setUser(signedInUser)
}
} catch (error) {
console.log("error", error)
alert(error.error_description || error)
}
}
return (
<div
style={{
display: "flex",
flexDirection: "column",
padding: 16
}}>
{user && (
<div>
{user.email} - {user.id}
</div>
)}
{!user && (
<div>
<div className="mb-4">
<label className="font-bold text-grey-darker block mb-2">
Email
</label>
<input
type="text"
placeholder="Your Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</div>
<div className="mb-4">
<label className="font-bold text-grey-darker block mb-2">
Password
</label>
<input
type="password"
placeholder="Your password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
<div className="flex flex-col gap-2">
<button
onClick={(e) => {
e.preventDefault()
handleLogin("SIGNUP", username, password)
}}
className="bg-indigo-700 hover:bg-teal text-white py-2 px-4 rounded text-center transition duration-150 hover:bg-indigo-600 hover:text-white">
Sign up
</button>
<button
onClick={(e) => {
e.preventDefault()
handleLogin("LOGIN", username, password)
}}
className="border border-indigo-700 text-indigo-700 py-2 px-4 rounded w-full text-center transition duration-150 hover:bg-indigo-700 hover:text-white">
Login
</button>
</div>
</div>
)}
</div>
)
}
export default IndexOptions
Full Example
To see a complete example, check out with-supabase (opens in a new tab) in our examples repo!
Last updated on December 27, 2022