If your app is built on Next.js, Stytch has you covered! Our frontend Next.js SDK is a great option if you want pre-built UI components to build your login flow in minutes or you can use our Node Backend SDK to drive your auth from the server side.

We generally recommend developers leverage our most flexible option, backend via our Node SDK, as powering auth from your backend lets you have complete frontend control over your onboarding and login flows, plays nicely with Next.js’s server side rendering (SSR), and allows your auth and user management logic to live alongside your app’s existing backend business logic.

Next.js offers two options for routing within your application, the newer App Router and traditional Pages Router; Stytch is compatible with both.

App Router

If you’re on Next.js 13 and using the new App Router, you may use both Client and Server Components in your application with Stytch.

Our stytch-nextjs-app-router-example app uses the App Router, and you can copy any of the patterns you see there.

Implementing the StytchProvider in the App Router

If your application uses our frontend Next.js SDK, you’ll need to wrap your application in the StytchProvider. To do so, simply include the StytchProvider in your layout.tsx:

import "./globals.css";

import { ReactNode } from "react";
import Header from "@/src/components/Header";
import StytchProvider from "@/src/components/StytchProvider";

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
      <html lang="en">
        <title>Stytch Next.js 13 Example</title>
          content="An example Next.js 13 application using Stytch for authentication"
          <Header />
            <div className="container">{children}</div>

Client components

For Client Components, use our frontend Next.js SDK to interact with Stytch.

"use client";

import React from "react";
import { useStytch, useStytchSession, useStytchUser } from "@stytch/nextjs";

// The Profile component is shown to a user that is logged in and display's the user's first name.
const Profile = () => {
  const stytch = useStytch();
  // Get the Stytch User object.
  const { user } = useStytchUser();
  // Get the Stytch Session object.
  const { session } = useStytchSession();
  return (
    <div className="card">
      <h2>Hi, {user?.name.first_name}</h2>

Server components

For Server Components, you may use our backend Node SDK to interact with the Stytch API directly.

import type { NextApiRequest, NextApiResponse } from 'next';
import loadStytch from '../../../lib/loadStytch';
import Cookies from 'cookies';

type Error = {
  errorString: string;

type Response = {
  user_id: string;

POST api/sessions/authenticate_jwt authenticates a Stytch session JWT which has been stored by the frontend Next.js SDK.

The SDK stores the session token in a cookie named 'stytch_session_jwt'.
Since the API shares a domain with the cookie, the cookie is automatically included in requests to the backend.

Session authentication with a valid JWT can be accomplished locally. This means much lower latency vs token authentication.

Note that JWTs can not be revoked once issued. For this reason, Stytch Session JWTs have a fixed lifetime of 5 minutes. They can be refreshed.
If instant session revocation is a concern, try using our opaque session tokens instead.

You should do session validation with either a token or JWT on any API routes which return protected user data. 
export async function handler(req: NextApiRequest, res: NextApiResponse<Response | Error>) {
  if (req.method === 'POST') {
    // Read the stytch session token from the cookies
    const cookies = new Cookies(req, res);
    const stytchSessionJWT = cookies.get('stytch_session_jwt');
    if (!stytchSessionJWT) {
      return res.status(400).json({ errorString: 'No session token found.' });
    // Attempt to authenticate the session JWT
    const stytchClient = loadStytch();
    try {
      // Authenticate the session JWT. If an error is thrown the session authentication has failed.
      const resp = await stytchClient.sessions.authenticateJwt(stytchSessionJWT);

      // The response object contains session details
      const userID = resp.session.user_id;
      // Now that you have an active session you can safely get data and do actions for the given user. Eg...
      // database.getUserDetails(userID)

      // Session token authentication was successful.
        user_id: userID,
    } catch (e) {
      return res.status(400).json({ errorString: 'Session authentication failed.' });

export default handler;

Pages Router

Our stytch-nextjs-pages-router-example uses the older Pages Router and our frontend Next.js SDK.

We'd recommend checking our our Next.js quickstart guide, which will demonstrate how to integrate our frontend SDK into your Pages Router application.

Implementing the StytchProvider in the Pages Router

If your application uses our frontend Next.js SDK, you’ll need to wrap your application in the StytchProvider. To do so, simply include the StytchProvider in your _app.js:

import "src/styles/styles.css";
import Head from "next/head";
import { StytchProvider } from "@stytch/nextjs";
import { createStytchUIClient } from "@stytch/nextjs/ui";

// We initialize the Stytch client using our project's public token which can be found in the Stytch dashboard
const stytch = createStytchUIClient(

export default function App({ Component, pageProps }) {
  return (
        <title>Stytch Next.js Example</title>
          content="An example Next.js application using Stytch for authentication"
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <link rel="icon" href="/favicon.svg" />
      {/* Wrap the application with StytchProvider to make the SDK available in children components */}
      <StytchProvider stytch={stytch}>
          <div className="container">
            <Component {...pageProps} />

Server Side Rendering (SSR)

If you're using our pre-built UI components in Next.js you'll want to use createStytchUIClient rather than calling StytchUIClient directly. This protects you against accidentally trying to call the UI components server side where they are inoperable.

import { StytchProvider, createStytchUIClient } from '@stytch/nextjs';
import React from 'react';

const stytch = createStytchUIClient('PUBLIC_TOKEN');

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <StytchProvider stytch={stytch}>
      <Component {...pageProps} />
export default MyApp;