Skip to Content
Multi-Platform Content Distribution 🚀 Read more → 
DocumentationQuickstart: Supabase

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

Initialize a Plasmo project with Supabase

pnpm create plasmo --with-supabase

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:

Let’s add them in an .env file:

.env
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 core/supabase.ts:

core/supabase.ts
import { createClient } from "@supabase/supabase-js" import { Storage } from "@plasmohq/storage" const storage = new Storage({ area: "local" }) export const supabase = createClient( process.env.PLASMO_PUBLIC_SUPABASE_URL, process.env.PLASMO_PUBLIC_SUPABASE_KEY, { auth: { storage, autoRefreshToken: true, persistSession: true, detectSessionInUrl: true } } )

Adding Redirect URL

When a user signs up, they’ll need to confirm their email. To do this, we need to add a redirect URL to our Supabase project.

First, we need to create a consistent ID for our extension for development. When you push to the different web stores, you’ll get a different ID. To learn more about how all of this works, check out our blog post on creating consistent extension IDs 

Go to the Itero KeyPair Tool  to generate your consistent extension ID.

We can store the ID and public key in our .env file:

.env
CRX_ID="Replace with the value of CRX ID from Itero KeyPair tool" CRX_KEY="Replace with the value of Public Key from Itero KeyPair tool"

Then, references the public key in your package.json under the manifest.key value:

"manifest": { "host_permissions": [ "https://*/*" ], "key": "$CRX_KEY", }

Now we need to make it so that the browser doesn’t block access to our options page. To do this, we must add it to our web_accessible_resources in our manifest:

"web_accessible_resources": [ { "resources": [ "options.html" ], "matches": [ "<all_urls>" ], "extension_ids": [ "$CRX_ID" ] } ]

Head over to the Supabase console and click on the “Authentication” tab, and click URL Configuration.

Now add the following URL in your site URL as well as your redirect URL:

chrome-extension://<CRX_ID>/options.html

Replace CRX_ID with the generated extension ID given to you by Itero KeyPairs tool, or the actual ID given to you by the production web store.

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 { Provider, User } from "@supabase/supabase-js" import { useEffect, useState } from "react" import { Storage } from "@plasmohq/storage" import { useStorage } from "@plasmohq/storage/hook" import { supabase } from "~core/supabase" function IndexOptions() { const [user, setUser] = useStorage<User>({ key: "user", instance: new Storage({ area: "local" }) }) const [username, setUsername] = useState("") const [password, setPassword] = useState("") useEffect(() => { async function init() { const { data, error } = await supabase.auth.getSession() if (error) { console.error(error) return } if (!!data.session) { setUser(data.session.user) } } init() }, []) const handleEmailLogin = async ( type: "LOGIN" | "SIGNUP", username: string, password: string ) => { try { const { error, data: { user } } = type === "LOGIN" ? await supabase.auth.signInWithPassword({ email: username, password }) : await supabase.auth.signUp({ email: username, password }) if (error) { alert("Error with auth: " + error.message) } else if (!user) { alert("Signup successful, confirmation mail should be sent soon!") } else { setUser(user) } } catch (error) { console.log("error", error) alert(error.error_description || error) } } const handleOAuthLogin = async (provider: Provider, scopes = "email") => { await supabase.auth.signInWithOAuth({ provider, options: { scopes, redirectTo: location.href } }) } return ( <main style={{ display: "flex", justifyContent: "center", alignItems: "center", width: "100%", top: 240, position: "relative" }}> <div style={{ display: "flex", flexDirection: "column", width: 240, justifyContent: "space-between", gap: 4.2 }}> {user && ( <> <h3> {user.email} - {user.id} </h3> <button onClick={() => { supabase.auth.signOut() setUser(null) }}> Logout </button> </> )} {!user && ( <> <label>Email</label> <input type="text" placeholder="Your Username" value={username} onChange={(e) => setUsername(e.target.value)} /> <label>Password</label> <input type="password" placeholder="Your password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button onClick={(e) => { handleEmailLogin("SIGNUP", username, password) }}> Sign up </button> <button onClick={(e) => { handleEmailLogin("LOGIN", username, password) }}> Login </button> <button onClick={(e) => { handleOAuthLogin("github") }}> Sign in with GitHub </button> </> )} </div> </main> ) } export default IndexOptions

Full Example

To see a complete example, check out with-supabase  in our examples repo!

Last updated on