Skip to main content
Which UI do you use?
Custom UI
Pre built UI

1. Configuration

1) Install supertokens package #

yarn add supertokens-node supertokens-auth-react supertokens-web-js nextjs-cors

2) Create configuration files #

  • Create a config folder in the root directory of your project
  • Create an appInfo.ts inside the config folder.
  • Create a backendConfig.ts inside the config folder.
  • Create a frontendConfig.ts inside the config folder.

3) Create the appInfo configuration. #

/config/appInfo.ts

export const appInfo = {
// learn more about this on https://supertokens.com/docs/thirdpartyemailpassword/appinfo
appName: "<YOUR_APP_NAME>",
apiDomain: "<YOUR_API_DOMAIN>",
websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
apiBasePath: "/auth",
websiteBasePath: "/auth"
}

4) Create a frontend config function #

/config/frontendConfig.ts
import ThirdPartyEmailPasswordReact from 'supertokens-auth-react/recipe/thirdpartyemailpassword'
import SessionReact from 'supertokens-auth-react/recipe/session'
import { appInfo } from './appInfo'
import Router from 'next/navigation'
import { useRouter } from "next/navigation";
import { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types'

const routerInfo: { router?: ReturnType<typeof useRouter>; pathName?: string } =
{};

export function setRouter(
router: ReturnType<typeof useRouter>,
pathName: string,
) {
routerInfo.router = router;
routerInfo.pathName = pathName;
}

export const frontendConfig = (): SuperTokensConfig => {
return {
appInfo,
recipeList: [
ThirdPartyEmailPasswordReact.init({
signInAndUpFeature: {
providers: [
ThirdPartyEmailPasswordReact.Google.init(),
ThirdPartyEmailPasswordReact.Facebook.init(),
ThirdPartyEmailPasswordReact.Github.init(),
ThirdPartyEmailPasswordReact.Apple.init(),
],
},
}),
SessionReact.init(),
],
windowHandler: (original) => ({
...original,
location: {
...original.location,
getPathName: () => routerInfo.pathName!,
assign: (url) => routerInfo.router!.push(url.toString()),
setHref: (url) => routerInfo.router!.push(url.toString()),
},
}),
}
}

5) Create a backend config function#

/config/backendConfig.ts
import SuperTokens from "supertokens-node";
import ThirdPartyEmailPasswordNode from 'supertokens-node/recipe/thirdpartyemailpassword'
import SessionNode from 'supertokens-node/recipe/session'
import { appInfo } from './appInfo'
import { TypeInput } from "supertokens-node/types";

export const backendConfig = (): TypeInput => {
return {
framework: "express",
supertokens: {
connectionURI: "",
apiKey: "",
},
appInfo,
recipeList: [
ThirdPartyEmailPasswordNode.init({
// We have provided you with development keys which you can use for testing.
// IMPORTANT: Please replace them with your own OAuth keys for production use.
providers: [{
config: {
thirdPartyId: "google",
clients: [{
clientId: "1060725074195-kmeum4crr01uirfl2op9kd5acmi9jutn.apps.googleusercontent.com",
clientSecret: "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"
}]
}
}, {
config: {
thirdPartyId: "github",
clients: [{
clientId: "467101b197249757c71f",
clientSecret: "e97051221f4b6426e8fe8d51486396703012f5bd"
}]
}
}, {
config: {
thirdPartyId: "apple",
clients: [{
clientId: "4398792-io.supertokens.example.service",
additionalConfig: {
keyId: "7M48Y4RYDL",
privateKey:
"-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgu8gXs+XYkqXD6Ala9Sf/iJXzhbwcoG5dMh1OonpdJUmgCgYIKoZIzj0DAQehRANCAASfrvlFbFCYqn3I2zeknYXLwtH30JuOKestDbSfZYxZNMqhF/OzdZFTV0zc5u5s3eN+oCWbnvl0hM+9IW0UlkdA\n-----END PRIVATE KEY-----",
teamId: "YWQCXGJRJL",
}
}]
}
}],
}),
SessionNode.init(),
],
isInServerlessEnv: true,
}
}

let initialized = false;
// This function is used in your APIs to make sure SuperTokens is initialised
export function ensureSuperTokensInit() {
if (!initialized) {
SuperTokens.init(backendConfig());
initialized = true;
}
}

ensureSuperTokensinit is a helper function that can be used in your API routes to make sure SuperTokens is initiailised before using any functionality exposed by the backend SDKs.

When you want to generate your own keys, please refer to the corresponding documentation to get your client ids and client secrets for each of the below providers:

Google
  • Generate your client ID and secret by following the docs here
  • Set the authorisation callback URL to <YOUR_WEBSITE_DOMAIN>/auth/callback/google
Github
  • Generate your client ID and secret by following the docs here
  • Set the authorisation callback URL to <YOUR_WEBSITE_DOMAIN>/auth/callback/github
Facebook
  • Generate your client ID and secret by following the docs here
  • Set the authorisation callback URL to <YOUR_WEBSITE_DOMAIN>/auth/callback/facebook
Note

Make sure to enable https to be able to use the test users of the Facebook app. On http://localhost, the login flow can be verified only with the app's admin user.

Apple
  • Generate your client ID and secret by following this article
  • Set the authorisation callback URL to <YOUR_API_DOMAIN>/auth/callback/apple. Note that Apple doesn't allow localhost in the URL. So if you are in dev mode, you can use the dev keys we have provided above.

6) Call the frontend init functions and wrap with <SuperTokensWrapper> component #

  • Create a client component /app/components/supertokensProvider.tsx. This file will initialise SuperTokens and wrap its children with the SuperTokensWrapper component
  • Modify the /app/layout.tsx file to use the SuperTokensProvider component. You can learn more about this file here.
  • An example of this can be found here
/app/components/supertokensProvider.tsx
'use client';
import React from 'react';
import { SuperTokensWrapper } from 'supertokens-auth-react';
import SuperTokensReact from 'supertokens-auth-react';
import { frontendConfig, setRouter } from '../config/frontend';
import { usePathname, useRouter } from 'next/navigation';

if (typeof window !== 'undefined') {
// we only want to call this init function on the frontend, so we check typeof window !== 'undefined'
SuperTokensReact.init(frontendConfig());
}

export const SuperTokensProvider: React.FC<React.PropsWithChildren<{}>> = ({
children,
}) => {
setRouter(useRouter(), usePathname() || window.location.pathname);

return <SuperTokensWrapper>{children}</SuperTokensWrapper>;
};
/app/layout.tsx
import './globals.css'
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import { SuperTokensProvider } from "./components/supertokensProvider";

const inter = Inter({ subsets: ['latin'] })

export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}

export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<SuperTokensProvider>
<body className={inter.className}>{children}</body>
</SuperTokensProvider>
</html>
)
}