--- title: 'Build a User Management App with SolidJS' description: 'Learn how to use Supabase in your SolidJS App.' --- <$Partial path="quickstart_intro.mdx" /> ![Supabase User Management example](/docs/img/user-management-demo.png) If you get stuck while working through this guide, you can find the [full example on GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/solid-user-management). <$Partial path="project_setup.mdx" variables={{ "framework": "solidjs", "tab": "frameworks" }} /> ## Building the app Start building the SolidJS app from scratch. ### Initialize a SolidJS app You can use [degit](https://github.com/Rich-Harris/degit) to initialize an app called `supabase-solid`: ```bash npx degit solidjs/templates/ts supabase-solid cd supabase-solid ``` Then install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js) ```bash npm install @supabase/supabase-js ``` And finally save the environment variables in a `.env` with the API URL and the key that you copied [earlier](#get-api-details). <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/.env.example" lines={[[1, -1]]} meta="name=.env" /> Now that you have the API credentials in place, create a helper file to initialize the Supabase client. These variables will be exposed on the browser, and that's completely fine since you have [Row Level Security](/docs/guides/auth#row-level-security) enabled on the Database. <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/supabaseClient.tsx" lines={[[1, -1]]} meta="name=src/supabaseClient.tsx" /> ### App styling (optional) An optional step is to update the CSS file `src/index.css` to make the app look better. You can find the full contents of this file [in the example repository](https://raw.githubusercontent.com/supabase/supabase/master/examples/user-management/solid-user-management/src/index.css). ### Set up a sign-in component Set up a SolidJS component to manage sign-ins and sign-ups using Magic Links, so users can sign in with their email without using passwords. <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/Auth.tsx" lines={[[1, -1]]} meta="name=src/Auth.tsx" /> ### Account page After a user is signed in allow them to edit their profile details and manage their account. Create a new component for that called `Account.tsx`. <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/Account.tsx" lines={[[1, 1], [3, 78], [87, -1]]} meta="name=src/Account.tsx" /> ## Profile photos Next, add a way for users to upload a profile photo. Supabase configures every project with [Storage](/docs/guides/storage) for managing large files like photos and videos. ### Create an upload widget Start by creating a new component: <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/Avatar.tsx" lines={[[1, -1]]} meta="name=src/Avatar.tsx" /> ### Update the Account component With the Avatar component created, update `src/Account.tsx` to include it: <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/Account.tsx" lines={[[1, -1]]} meta="name=src/Account.tsx" /> ### Launch! With all the components in place, update `App.tsx`: <$CodeTabs> <$CodeSample path="/user-management/solid-user-management/src/App.tsx" lines={[[1, -1]]} meta="name=src/App.tsx" /> Once that's done, run this in a terminal window: ```bash npm start ``` And then open the browser to [localhost:3000](http://localhost:3000) and you should see the completed app. ![Supabase SolidJS](/docs/img/supabase-solidjs-demo.png) At this stage you have a fully functional application! ## Add a server route (SolidStart) The example above is client-only. If you migrate the app to [SolidStart](https://start.solidjs.com/) for server-side rendering and API routes, you can add protected server endpoints with [`@supabase/server`](https://supabase.github.io/server/). `createSupabaseContext` validates the incoming request's JWT locally (using your project's asymmetric signing keys, no round-trip to the Auth server), scopes a Supabase client to the authenticated user via RLS, and exposes the user's claims, all from a single call inside your SolidStart API route handler. ```bash npm install @supabase/server ``` <$CodeTabs> ```typescript name=src/routes/api/profile.ts import type { APIEvent } from '@solidjs/start/server' import { createSupabaseContext } from '@supabase/server' export async function GET({ request }: APIEvent) { const { data: ctx, error } = await createSupabaseContext(request, { auth: 'user', }) if (error) { return Response.json({ message: error.message, code: error.code }, { status: error.status }) } const { supabase, userClaims } = ctx const { data, error: queryError } = await supabase .from('profiles') .select('username, website, avatar_url') .eq('id', userClaims.id) .single() if (queryError) { return Response.json({ message: queryError.message }, { status: 500 }) } return Response.json(data) } ``` To make a route public, swap `auth: 'user'` for `auth: 'none'`. For app-wide authentication via SolidStart middleware, or for the full `@supabase/server` API, see the [getting started guide](https://supabase.github.io/server/getting-started).