Remix Reference

Installation

npm install @propelauth/remix

Configure the Remix Library

Starting in the Frontend Integration section of your dashboard, make sure to use /api/auth/callback as the Default redirect path after login, and /api/auth/logout as the Default redirect path after logout.

nextjs frontend locations

Since we're using Remix for both our frontend and backend, we'll set up our environment variables in the same place. The easiest way to do this is to create a .env file in the root of your project, and add the following:

.env

REMIX_PUBLIC_AUTH_URL=...
PROPELAUTH_API_KEY=...
PROPELAUTH_VERIFIER_KEY=...
PROPELAUTH_REDIRECT_URI=...

You can find the REMIX_PUBLIC_AUTH_URL, PROPELAUTH_API_KEY, and PROPELAUTH_VERIFIER_KEY variables for your application in the PropelAuth Dashboard under Backend Integration.

Remix backend config

When you copy the PROPELAUTH_VERIFIER_KEY from the PropelAuth dashboard, select the Copy as single line option and then paste into your .env file. For example:

PROPELAUTH_VERIFIER_KEY=-----BEGIN PUBLIC KEY-----\nMIIBIjANBgk...

PROPELAUTH_REDIRECT_URI is where your application is hosted with /api/auth/callback as the path. So, for example, if you are developing in the test environment and using http://localhost:3000, you would use http://localhost:3000/api/auth/callback

Nextjs frontend config


Setup the Remix Library

Initialization

Create a new directory app/auth and a file auth.server.ts inside it with the following content:

app/auth/auth.server.ts

import { initRemixAuth } from '@propelauth/remix'

export const auth = initRemixAuth({
    authUrl: process.env.REMIX_PUBLIC_AUTH_URL!,
    integrationApiKey: process.env.PROPELAUTH_API_KEY!,
    verifierKey: process.env.PROPELAUTH_VERIFIER_KEY!,
    redirectUri: process.env.PROPELAUTH_REDIRECT_URI!,
})

Install Routes

Create a new file in your app/routes/ directory called api.auth.$.tsx. We'll be importing auth from the auth.server file we just created:

app/routes/api.auth.$.tsx

import type { LoaderFunctionArgs } from '@remix-run/node'
import { auth } from '../auth/auth.server'

export async function loader({ params, request }: LoaderFunctionArgs) {
    return await auth.routes.loader(request, params)
}

export default function Auth() {
    return null
}

export async function action({ request, params }: LoaderFunctionArgs) {
    return await auth.routes.action(request, params)
}

This will create a few routes like /api/auth/login which will handle the login flow for you.

If you haven't already, run npx remix reveal in your terminal which will create app/entry.server.tsx.

In that file, import the auth function from the auth.server file we created earlier.

app/entry.server.tsx

import { PassThrough } from "node:stream";
import type { AppLoadContext, EntryContext } from "@remix-run/node";
import { createReadableStreamFromReadable } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { isbot } from "isbot";
import { renderToPipeableStream } from "react-dom/server";
import { auth } from "./auth/auth.server";

// ...

In that same file, there's a function called handleRequest. You need to add the single line auth.handleRequest(responseHeaders, loadContext) to the top of that function.

app/entry.server.tsx

export default function handleRequest(
    request: Request,
    responseStatusCode: number,
    responseHeaders: Headers,
    remixContext: EntryContext,
    loadContext: AppLoadContext
) {
  auth.handleRequest(responseHeaders, loadContext)
// ...

Lastly, let's add the RevalidateSession component to your root.tsx file. This will keep your session alive and your user's information up to date.

app/root.tsx

import { RevalidateSession } from "@propelauth/remix/client";

export default function App() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
        <LiveReload />
        <RevalidateSession />
      </body>
    </html>
  );
}