Skip to main content

@auth/solid-start

warning

@auth/solid-start is currently experimental. The API will change in the future.

SolidStart Auth is the official SolidStart integration for Auth.js. It provides a simple way to add authentication to your SolidStart app in a few lines of code.

Installation​

npm install @auth/core @auth/solid-start

We recommended to using create-jd-app

SolidAuth()​

SolidAuth(config): {
GET: Promise< undefined | Response >;
POST: Promise< undefined | Response >;
}

Setup​

Generate an auth secret, then set it as an environment variable:

AUTH_SECRET=your_auth_secret

Creating the API handler​

in this example we are using github so make sure to set the following environment variables:

GITHUB_ID=your_github_oauth_id
GITHUB_SECRET=your_github_oauth_secret
// routes/api/auth/[...solidauth].ts
import { SolidAuth, type SolidAuthConfig } from "@auth/solid-start"
import GitHub from "@auth/core/providers/github"

export const authOpts: SolidAuthConfig = {
providers: [
GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
debug: false,
}

export const { GET, POST } = SolidAuth(authOpts)

Getting the current session​

import { getSession } from "@auth/solid-start"
import { createServerData$ } from "solid-start/server"
import { authOpts } from "~/routes/api/auth/[...solidauth]"

export const useSession = () => {
return createServerData$(
async (_, { request }) => {
return await getSession(request, authOpts)
},
{ key: () => ["auth_user"] }
)
}

// useSession returns a resource:
const session = useSession()
const loading = session.loading
const user = () => session()?.user

Protected Routes​

When Using SSR​

When using SSR, I recommend creating a Protected component that will trigger suspense using the Show component. It should look like this:

// components/Protected.tsx
import { type Session } from "@auth/core/types";
import { getSession } from "@auth/solid-start";
import { Component, Show } from "solid-js";
import { useRouteData } from "solid-start";
import { createServerData$, redirect } from "solid-start/server";
import { authOpts } from "~/routes/api/auth/[...solidauth]";

const Protected = (Comp: IProtectedComponent) => {
const routeData = () => {
return createServerData$(
async (_, event) => {
const session = await getSession(event.request, authOpts);
if (!session || !session.user) {
throw redirect("/");
}
return session;
},
{ key: () => ["auth_user"] }
);
};

return {
routeData,
Page: () => {
const session = useRouteData<typeof routeData>();
return (
<Show when={session()} keyed>
{(sess) => <Comp {...sess} />}
</Show>
);
},
};
};

type IProtectedComponent = Component<Session>;

export default Protected;

It can be used like this:

// routes/protected.tsx
import Protected from "~/components/Protected";

export const { routeData, Page } = Protected((session) => {
return (
<main class="flex flex-col gap-2 items-center">
<h1>This is a protected route</h1>
</main>
);
});

export default Page;

When Using CSR​

When using CSR, the Protected component will not work as expected and will cause the screen to flash, so I had to come up with a tricky solution, we will use a Solid-Start middleware:

// entry-server.tsx
import { Session } from "@auth/core";
import { getSession } from "@auth/solid-start";
import { redirect } from "solid-start";
import {
StartServer,
createHandler,
renderAsync,
} from "solid-start/entry-server";
import { authOpts } from "./routes/api/auth/[...solidauth]";

const protectedPaths = ["/protected"]; // add any route you wish in here

export default createHandler(
({ forward }) => {
return async (event) => {
if (protectedPaths.includes(new URL(event.request.url).pathname)) {
const session = await getSession(event.request, authOpts);
if (!session) {
return redirect("/");
}
}
return forward(event);
};
},
renderAsync((event) => <StartServer event={event} />)
);

And now you can easily create a protected route:

// routes/protected.tsx
export default () => {
return (
<main class="flex flex-col gap-2 items-center">
<h1>This is a protected route</h1>
</main>
);
};
note

The CSR method should also work when using SSR, the SSR method shouldn't work when using CSR

Parameters​

β–ͺ config: SolidAuthConfig

Returns​

object

GET()​

Parameters​

β–ͺ event: any

Returns​

Promise< undefined | Response >

POST()​

Parameters​

β–ͺ event: any

Returns​

Promise< undefined | Response >