Integrate your microapp with Supabase by bridging authentication using JWT tokens generated by Microapp. This approach lets you use Microapp for user identity and securely access Supabase data—without using Supabase’s built-in authentication.

Supabase authentication is not compatible with Microapp. Always use the JWT token generated by Microapp to authenticate and check users in Supabase.

Prerequisites

1. Set Up Your Supabase Project

  1. Sign in to Supabase and create a new project.
  2. Note your project’s URL and anon/public API key from the project settings. You’ll need these to connect your microapp.

2. Install the SDKs

Install both the Microapp SDK and Supabase client:

npm install @microapp-io/react @supabase/supabase-js

3. Create a Supabase Hook

Create a React hook that provides a Supabase client authenticated with the current user’s JWT token:

// src/hooks/useSupabase.ts
import { useMemo } from 'react';
import { useAuth } from '@microapp-io/react';
import { createClient } from '@supabase/supabase-js';

const SUPABASE_URL = 'your-supabase-url';
const SUPABASE_ANON_KEY = 'your-anon-key';

export function useSupabase() {
  const { jwtToken } = useAuth();

  return useMemo(() => {
    return createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
      global: {
        headers: jwtToken ? { Authorization: `Bearer ${jwtToken}` } : {},
      },
      auth: {
        autoRefreshToken: false,
        detectSessionInUrl: false,
        persistSession: false,
      },
    });
  }, [jwtToken]);
}

Replace your-supabase-url and your-anon-key with your actual Supabase project values.

4. Use Supabase in Your Components

Now you can use both Microapp and Supabase authentication in your components:

// src/pages/Index.tsx
import { useAuth } from '@microapp-io/react';
import { useSupabase } from '@/hooks/useSupabase';

export default function Index() {
  const { isAuthenticated, requestLogin, user } = useAuth();
  const supabase = useSupabase();

  const handleCreateTodo = async () => {
    if (!isAuthenticated) {
      requestLogin();
      return;
    }

    await supabase.from('todos').insert({
      user_id: user.id,
      title: 'My Todo',
    });
  };

  return (
    <button onClick={handleCreateTodo}>
      {isAuthenticated ? 'Create Todo' : 'Log In to Create'}
    </button>
  );
}

5. Configure JWT Authentication

To let Supabase validate Microapp’s JWT tokens, both systems must use the same JWT secret:

  1. Copy the Microapp JWT Secret
  • Go to Microapp Creator Dashboard → Settings → JWT Secret and copy the value
  • Or generate a new secret if needed
  1. Set the Same Secret in Supabase
  • Go to Supabase Dashboard → Project Settings → Auth → JWT Settings
  • Paste the same secret under JWT Secret

Both Microapp and Supabase must use the exact same JWT secret so that tokens can be verified.

6. Set Up Row Level Security (RLS)

Enable secure access to user-owned data with RLS policies:

-- Enable RLS on your table
ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY;

-- Allow users to view their own todos
CREATE POLICY "Users can view their own todos"
  ON public.todos
  FOR SELECT
  USING (auth.uid() = user_id);

-- Allow users to create their own todos
CREATE POLICY "Users can create their own todos"
  ON public.todos
  FOR INSERT
  WITH CHECK (auth.uid() = user_id);

7. Deploy and Test

  1. Test authentication and database queries in your local environment
  2. Ensure your environment variables are set in your deployment platform
  3. Deploy your microapp as usual

For advanced features like real-time subscriptions, storage, and edge functions, see the Supabase documentation.


Understanding JWT Authentication Flow

Here’s how authentication works between Microapp and Supabase:

Data Flow Overview

  1. User logs in via Microapp and receives a JWT token
  2. Your React app gets the token using useAuth()
  3. The useSupabase hook creates a client with the user’s token
  4. All Supabase queries are authenticated with that token
  5. Supabase enforces Row Level Security using the token’s sub claim as the user ID

Token Structure

Microapp JWT tokens include these important claims:

{
  "aud": "authenticated",
  "role": "authenticated",
  "metadata": {
    "user": {
      "id": "b07a3a69-852c-496f-9bad-b4bd1a63e61a",
      "email": "[email protected]",
      "pictureUrl": null
    },
    "app": {
      "id": "e21e0abf-00fe-4b56-ac19-f6764af38760",
      "slug": "todo-app"
    }
  },
  "sub": "cbe35973-d7d3-4ee7-9ec3-bf76a15dbf9f",
  "iat": 1750941947,
  "exp": 1750945547
}
  • sub is used by Supabase as auth.uid() and contains the user ID
  • metadata.user contains user information like email and profile picture
  • metadata.app contains the microapp details
  • aud and role are set to “authenticated” for Supabase compatibility
  • exp is the expiration time (in seconds since epoch)
  • iat is the issued-at time

Token Management

  • Default TTL: Tokens expire after 60 minutes by default
  • Custom TTL: You can modify the token expiration time in the Microapp Creator Dashboard
  • Token Refresh: To get a new token, call getUserJwtToken() method or refresh the page
  • Automatic Handling: The useSupabase hook automatically uses the latest token from useAuth()

Best Practices

  • JWT Bridging: Microapp handles authentication and provides a JWT. You pass this token to Supabase for secure data access
  • Token Expiry: If Supabase returns authentication errors, the token may have expired - simply refresh or call getUserJwtToken()
  • Security: Never share JWT secrets publicly. Use environment variables for all secrets and keys

Next Steps