Create your Plasmic App using Supabase Auth with Userbased Database Access.

Create your Plasmic App using Supabase Auth with Userbased Database Access.

In this Breakdown, I walk you through setting up a local server to host Plasmic, and show you how to integrate Supabase Authentication for user-based table access with relations to POST/GET data and CRUD functionalities. This beginner-friendly tutorial is the only one available online that addresses the Supabase-Plasmic authentication integration. I’ve included all the necessary details and steps to ensure a smooth setup process.

However, if you encounter any issues, feel free to reach out to me at contact@shams.digital.

Big Thanks to Callum Boase Brother for his powerful Package.

First Check This Video, then follow all steps below:

https://www.youtube.com/watch?v=daiODdH1BYk

  • Open VS Code Terminal, and run this, and do the rest of the setup as I showed on my breakdown video.

    npx create-plasmic-app

  • Setup Custom App Host as shown.

Supabase Setup

Set up your supabase project as shown on the video.

Setup Plasmic Auth using Supabase on VS Code

  • In the terminal, run npm install to install Plasmic & it's dependencies

  • Add a .env.local file with your supabase credentials (from Supabase dashboard)

    # Supabase Project NEXT_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

  • npm install plasmic-supabase to install this package

  • Open ./plasmic-init.ts. It should look like this to start with (default Plasmic comments removed for brevity)

      import { initPlasmicLoader } from "@plasmicapp/loader-nextjs";
      import { 
       SupabaseProvider, 
       SupabaseProviderMeta,
       SupabaseUserGlobalContext,
       SupabaseUserGlobalContextMeta,
       SupabaseUppyUploader,
       SupabaseUppyUploaderMeta,
       SupabaseStorageGetSignedUrl,
       SupabaseStorageGetSignedUrlMeta,
      } from "plasmic-supabase"
    
      export const PLASMIC = initPlasmicLoader({
       projects: [
       {
       id: "your-plasmic-project-id",
       token: "your-plasmic-project-token",
       },
       ],
    
       preview: true,
      });
    
      //Register global context
      PLASMIC.registerGlobalContext(SupabaseUserGlobalContext, SupabaseUserGlobalContextMeta)
    
      //Register components
      PLASMIC.registerComponent(SupabaseProvider, SupabaseProviderMeta);
      PLASMIC.registerComponent(SupabaseUppyUploader, SupabaseUppyUploaderMeta);
      PLASMIC.registerComponent(SupabaseStorageGetSignedUrl, SupabaseStorageGetSignedUrlMeta);
    
  • Modify plasmic-init.ts to import components from plasmic-supabase

  • In ./pages directory add a new file called _app.tsx and add the following content. Save your file

      import type { AppProps } from 'next/app';
      // Import the CSS required for SupabaseUppyUploader globally
      import "@uppy/core/dist/style.min.css";
      import "@uppy/dashboard/dist/style.min.css";
    
      function MyApp({ Component, pageProps }: AppProps) {
        return <Component {...pageProps} />;
      }
    
      export default MyApp;
    

    Setup Plasmic Home, Login, Signup pages

    • In terminal: npm run dev to start your Dev server

    • Create Pages and Necessary Forms for auth. Watch the Breakdown video.

    • Test your auth functionalities by signing up and logging in.

Setup plasmic Secret pages by ensuring supabase Middleware

  • Install the package @supabase/ssr by running in terminal

  • npm install @supabase/ssr

    Add to the root directory a file called middleware.ts with the following content:

  •   import { createServerClient } from '@supabase/ssr'
      import { NextResponse, type NextRequest } from 'next/server'
    
      // Define the route that contains your login page
      const loginPage = '/login'
    
      // Add any public (non-login protected) routes here
      // All other routes will be login protected
      // Important: plasmic-host and your login page must always be public
      const publicRoutes = [
       '/',
       '/login',
       '/plasmic-host'
      ]
    
      // Middleware function
      // This will run on every request to your app that matches the pattern at the bottom of this file
      // Adapted from @supabase/ssr docs https://supabase.com/docs/guides/auth/server-side/nextjs?queryGroups=router&router=app
      export async function middleware(request: NextRequest) {
    
       let supabaseResponse = NextResponse.next({
       request,
       })
    
       //Create a new supabase client
       //Refresh expired auth tokens and set new cookies
       const supabase = createServerClient(
       process.env.NEXT_PUBLIC_SUPABASE_URL!,
       process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
       {
       cookies: {
       getAll() {
       return request.cookies.getAll()
       },
       setAll(cookiesToSet) {
       cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
       supabaseResponse = NextResponse.next({
       request,
       })
       cookiesToSet.forEach(({ name, value, options }) =>
       supabaseResponse.cookies.set(name, value, options)
       )
       },
       },
       }
       )
    
       // IMPORTANT: Avoid writing any logic between createServerClient and
       // supabase.auth.getUser(). A simple mistake could make it very hard to debug
       // issues with users being randomly logged out.
    
       // Get details of the logged in user if present
       const {
       data: { user },
       } = await supabase.auth.getUser()
    
       // Decide whether to redirect to the /login page or not
       // You can adapt this logic to suit your needs
    
       if (publicRoutes.includes(request.nextUrl.pathname) !== true && !user) {
       // It's a login protected route but there's no logged in user. 
       // Respond by redirecting the user to the login page
       const url = request.nextUrl.clone()
       url.pathname = loginPage;
       return NextResponse.redirect(url)
    
       } else {
       // It's a public route, or it's a login protected route and there is a logged in user. 
       // Proceed as normal
       return supabaseResponse
       }
    
       // IMPORTANT: You must return the supabaseResponse object as it is. If you're
       // creating a new response object with NextResponse.next() make sure to:
       // 1. Pass the request in it, like so:
       // const myNewResponse = NextResponse.next({ request })
       // 2. Copy over the cookies, like so:
       // myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
       // 3. Change the myNewResponse object to fit your needs, but avoid changing
       // the cookies!
       // 4. Finally:
       // return myNewResponse
       // If this is not done, you may be causing the browser and server to go out
       // of sync and terminate the user's session prematurely!
    
      }
    
      //Only run middleware on requests that match this pattern
      export const config = {
       matcher: [
       /*
      * Match all request paths except for the ones starting with:
      * - next/static (static files)
      * - next/image (image optimization files)
      * - favicon.ico (favicon file)
      * Feel free to modify this pattern to include more paths.
      */
       '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
       ],
      }
    
  • npm run build npm run start

    Fetch data From Supabase

  • Watch Breakdown Video.

  • For adding row based value based on userid

    {id: $ctx.SupabaseUser.user.id, name:$state.nameInput.value}

Thats it, you are now good to go!