supabase-oauth-popup
v1.0.0
Published
Ensure a Supabase session via OAuth in a popup
Maintainers
Readme
supabase-oauth-popup
Ensure a Supabase session via OAuth in a popup (Google/GitHub/…) with a full-page redirect fallback.
Installation
Use with a bundler:
import ensureSupabaseSession from "supabase-oauth-popup";Use via CDN (ESM import map):
<script type="importmap">
{
"imports": {
"supabase-oauth-popup": "https://cdn.jsdelivr.net/npm/supabase-oauth-popup@1/dist/index.js"
}
}
</script>Install locally with npm:
npm install supabase-oauth-popup…then import via an import map in your HTML (no bundler):
<script type="importmap">
{
"imports": {
"supabase-oauth-popup": "./node_modules/supabase-oauth-popup/dist/index.js"
}
}
</script>Usage
import { createClient } from "@supabase/supabase-js";
import ensureSupabaseSession from "supabase-oauth-popup";
const supabase = createClient(
"https://YOUR-PROJECT.supabase.co",
"YOUR_PUBLIC_ANON_KEY",
{
auth: {
detectSessionInUrl: true,
persistSession: true,
autoRefreshToken: true,
},
},
);
// Trigger from a user gesture to avoid popup blockers
document.getElementById("login")!.addEventListener("click", async () => {
const session = await ensureSupabaseSession(supabase, { provider: "google" });
// Example query (enforce access with your RLS policies)
const { data, error } = await supabase.from("demos").select("*");
console.log(data, error);
});API
async function ensureSupabaseSession(
client: SupabaseClient,
options?: {
provider?: Provider; // default: "google"
redirectTo?: string; // default: location.origin + location.pathname
popupFeatures?: string; // default: "width=480,height=640,menubar=no,toolbar=no"
timeoutMs?: number; // default: 120_000
scopes?: string; // e.g. "email profile openid"
queryParams?: Record<string, string>; // e.g. { access_type: "offline", prompt: "consent" }
onSignedIn?: (session: Session) => void;
},
): Promise<Session>;Behavior
- If a session already exists, it’s returned immediately.
- Otherwise, the function requests an OAuth URL with
skipBrowserRedirect: true. - It attempts to open a popup; if blocked (no user gesture), it falls back to a full-page redirect.
- When the provider completes, Supabase stores the session and broadcasts
SIGNED_INto same-origin tabs; the opener resolves. - If broadcasts are delayed, the optional
postMessagebackup (above) resolves it quickly.
Popup blocking & timeouts
- Popup blockers: Always call from a click or other user gesture. If blocked, this library automatically redirects the current page.
- Timeout: Defaults to 120s to avoid zombie popups/listeners. If your users routinely need longer (e.g., 2FA), raise
timeoutMs.
Security & RLS
Client queries should rely on Row Level Security:
alter table demos enable row level security;
create policy "read own rows"
on demos for select
using (user_id = auth.uid());Development
git clone https://github.com/sanand0/supabase-oauth-popup.git
cd supabase-oauth-popup
npm install
npm run lint && npm run build && npm testTo publish:
npm login
npm publish --access publicRelease notes
- 1.0.0: 14 Oct 2025. Initial release
