1. Configuration
Configure SuperTokens for authentication in your Next.js app with frontend and backend setup.
1. Install supertokens package
npm install supertokens-node supertokens-auth-react supertokens-web-jsyarn add supertokens-node supertokens-auth-react supertokens-web-jspnpm add supertokens-node supertokens-auth-react supertokens-web-jsbun add supertokens-node supertokens-auth-react supertokens-web-js2. Create configuration files
- Create a
configfolder in the app directory of your project. - Create an
appInfo.tsinside theconfigfolder. - Create a
backend.tsinside theconfigfolder. - Create a
frontend.tsinside theconfigfolder.
3. Create the appInfo configuration.
export const appInfo = {
// learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
appName: "<YOUR_APP_NAME>",
apiDomain: "<YOUR_API_DOMAIN>",
websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
apiBasePath: "/auth",
websiteBasePath: "/auth",
};1. Install supertokens package
npm install supertokens-node supertokens-web-jsyarn add supertokens-node supertokens-web-jspnpm add supertokens-node supertokens-web-jsbun add supertokens-node supertokens-web-js2. Create configuration files
- Create a
configfolder in the app directory of your project - Create an
appInfo.tsinside theconfigfolder. - Create a
backend.tsinside theconfigfolder. - Create a
frontend.tsinside theconfigfolder.
3. Create the appInfo configuration.
export const appInfo = {
// learn more about this on https://supertokens.com/docs/references/backend-sdks/reference#sdk-configuration
appName: "<YOUR_APP_NAME>",
websiteDomain: "<YOUR_WEBSITE_DOMAIN>",
apiDomain: "<YOUR_API_DOMAIN>",
apiBasePath: "/auth",
};4. Create a frontend config function
import EmailPasswordReact from "supertokens-auth-react/recipe/emailpassword";
import SessionReact from "supertokens-auth-react/recipe/session";
import { appInfo } from "./appInfo";
import { useRouter } from "next/navigation";
import type { 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: [EmailPasswordReact.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()),
},
}),
};
};4. Create a frontend config function
import EmailPasswordWebJs from "supertokens-web-js/recipe/emailpassword";
import SessionWebJs from "supertokens-web-js/recipe/session";
import { appInfo } from "./appInfo";
import type { SuperTokensConfig } from "supertokens-web-js/types";
export const frontendConfig = (): SuperTokensConfig => {
return {
appInfo,
recipeList: [EmailPasswordWebJs.init(), SessionWebJs.init()],
};
};5. Create a backend config function
import SuperTokens from "supertokens-node";
import EmailPasswordNode from "supertokens-node/recipe/emailpassword";
import SessionNode from "supertokens-node/recipe/session";
import { appInfo } from "./appInfo";
import type { TypeInput } from "supertokens-node/types";
export const backendConfig = (): TypeInput => {
return {
framework: "custom",
supertokens: {
connectionURI: "<CORE_API_ENDPOINT>",
apiKey: "<YOUR_API_KEY>",
},
appInfo,
recipeList: [EmailPasswordNode.init(), SessionNode.init()],
isInServerlessEnv: true,
};
};
let initialized = false;
export function ensureSuperTokensInit() {
if (!initialized) {
SuperTokens.init(backendConfig());
initialized = true;
}
}
ensureSuperTokensInit initializes SuperTokens once before an API route uses the backend SDK.
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 theSuperTokensWrappercomponent - Modify the
/app/layout.tsxfile to use theSuperTokensProvidercomponent. You can learn more about this file here. - An example of this can be found here
"use client";
import type { ReactNode } 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());
}
interface SuperTokensProviderProps {
children: ReactNode;
}
export function SuperTokensProvider({ children }: SuperTokensProviderProps) {
setRouter(useRouter(), usePathname() || window.location.pathname);
return <SuperTokensWrapper>{children}</SuperTokensWrapper>;
}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">
<body className={inter.className}>
<SuperTokensProvider>{children}</SuperTokensProvider>
</body>
</html>
);
}6. Call the frontend init functions and wrap with <SuperTokensInit> component
- Create a client component
/app/components/supertokensInit.tsx. This file will initialise SuperTokens. - Modify the
/app/layout.tsxfile to use theSuperTokensInitcomponent. You can learn more about this file here.
"use client";
import type { ReactNode } from "react";
import SuperTokensWebJs from "supertokens-web-js";
import { frontendConfig } from "../config/frontend";
if (typeof window !== "undefined") {
// we only want to call this init function on the frontend, so we check typeof window !== 'undefined'
SuperTokensWebJs.init(frontendConfig());
}
interface SuperTokensInitProps {
children: ReactNode;
}
export function SuperTokensInit({ children }: SuperTokensInitProps) {
return <>{children}</>;
}import "./globals.css";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { SuperTokensInit } from "./components/supertokensInit";
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">
<body className={inter.className}>
<SuperTokensInit>{children}</SuperTokensInit>
</body>
</html>
);
}