Which UI do you use?
Custom UI
Pre built UI
1. Configuration
#
1) Install supertokens packageyarn add supertokens-node supertokens-auth-react supertokens-web-js nextjs-cors
#
2) Create configuration files- Create a
config
folder in the app directory of your project. - Create an
appInfo.ts
inside theconfig
folder. - Create a
backend.ts
inside theconfig
folder. - Create a
frontend.ts
inside theconfig
folder.
appInfo
configuration. #
3) Create the app/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 functionapp/config/frontend.tsx
import PasswordlessReact from 'supertokens-auth-react/recipe/passwordless'
import SessionReact from 'supertokens-auth-react/recipe/session'
import { appInfo } from './appInfo'
import { SuperTokensConfig } from 'supertokens-auth-react/lib/build/types'
import { useRouter } from "next/navigation";
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: [
PasswordlessReact.init({
contactMethod: "^{form_contactMethod}"
}),
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 functionHow do you want to identify your users?
Only phone numberOnly emailEmail or phone number
Which authentication type will you use?
OTPMagic linksOTP and Magic link
- Single app setup
- Multi app setup
app/config/backend.ts
import SuperTokens from "supertokens-node";
import PasswordlessNode from 'supertokens-node/recipe/passwordless'
import SessionNode from 'supertokens-node/recipe/session'
import { appInfo } from './appInfo'
import { TypeInput } from "supertokens-node/types";
export const backendConfig = (): TypeInput => {
return {
framework: "custom",
supertokens: {
connectionURI: "",
apiKey: "",
},
appInfo,
recipeList: [
PasswordlessNode.init({
flowType: "USER_INPUT_CODE",
contactMethod: "PHONE"
}),
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.
app/config/backend.ts
import SuperTokens from "supertokens-node";
import PasswordlessNode from 'supertokens-node/recipe/passwordless'
import SessionNode from 'supertokens-node/recipe/session'
import { appInfo } from './appInfo'
import { TypeInput } from "supertokens-node/types";
export const backendConfig = (): TypeInput => {
return {
framework: "custom",
supertokens: {
connectionURI: "",
apiKey: "",
},
appInfo,
recipeList: [
PasswordlessNode.init({
flowType: "USER_INPUT_CODE",
contactMethod: "PHONE"
}),
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.
init
functions and wrap with <SuperTokensWrapper>
component #
7) Call the frontend - Create a client component
/app/components/supertokensProvider.tsx
. This file will initialise SuperTokens and wrap its children with theSuperTokensWrapper
component - Modify the
/app/layout.tsx
file to use theSuperTokensProvider
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>
)
}