> ## Documentation Index
> Fetch the complete documentation index at: https://auth0-cq3uo.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Login to Your Next.js Application

export const SignUpForm = () => {
  return <div className="flex flex-col gap-2 items-center h-full">
      <img noZoom src="/docs/img/quickstarts/action_hero_dashboard.svg" alt="Sign up for an Auth0 account" style={{
    width: "250px",
    height: "250px"
  }} />
      <span className="text-center" style={{
    width: "400px"
  }}>
        Sign up for an{" "}
        <a href="https://auth0.com/signup" target="_blank" rel="noopener noreferrer">
          Auth0 account
        </a>{" "}
        or{" "}
        <span className="font-semibold text-primary cursor-pointer" onClick={() => console.log("log in")}>
          log in
        </span>{" "}
        to your existing account to integrate directly with your own tenant.
      </span>
      <button onClick={() => console.log("sign up")} className="bg-primary dark:bg-primary-light text-white px-4 py-2 rounded-md mt-4 font-medium" style={{
    width: "140px"
  }}>
        Sign up
      </button>
    </div>;
};

export const SideMenuSectionItem = ({id, children}) => {
  return <div id={`side-menu-item-${id}`} className="recipe-side-menu-item flex flex-col w-full h-full">
      {children}
    </div>;
};

export const SideMenu = ({sections, children}) => {
  const [visibleSection, setVisibleSection] = useState(sections[0]?.id ?? null);
  const checkVisibility = () => {
    let currentVisible = null;
    const viewportHeight = window.innerHeight;
    const scrollY = window.scrollY;
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      if (section) {
        const rect = section.getBoundingClientRect();
        const sectionTop = rect.top + scrollY;
        const sectionBottom = sectionTop + rect.height;
        const multiplier = viewportHeight > 1600 ? 0.34 : 0.22;
        if (scrollY + viewportHeight * multiplier >= sectionTop && scrollY <= sectionBottom) {
          currentVisible = id;
        }
      }
    });
    if (currentVisible && currentVisible !== visibleSection) {
      setVisibleSection(currentVisible);
    }
  };
  useEffect(() => {
    const throttledCheck = () => {
      setTimeout(checkVisibility, 100);
    };
    checkVisibility();
    window.addEventListener("scroll", throttledCheck);
    return () => {
      window.removeEventListener("scroll", throttledCheck);
    };
  }, [sections, visibleSection]);
  useEffect(() => {
    sections.forEach(({id}) => {
      const section = document.getElementById(id);
      const sideMenuItem = document.getElementById(`side-menu-item-${id}`);
      if (section) {
        if (id === visibleSection) {
          section.classList.add("active-section");
        } else {
          section.classList.remove("active-section");
        }
      }
      if (sideMenuItem) {
        if (id === visibleSection) {
          sideMenuItem.classList.add("active-side-menu-item");
        } else {
          sideMenuItem.classList.remove("active-side-menu-item");
        }
      }
    });
  }, [visibleSection, sections]);
  return <div className="recipe-side-menu sticky px-2 py-1" style={{
    height: "calc(100vh - 7rem)",
    top: "7rem",
    scrollMarginTop: "var(--scroll-mt)"
  }}>
      {children.map(child => {
    if (child.props.id === visibleSection) {
      return child;
    }
    return null;
  })}
    </div>;
};

export const Section = ({id, title, stepNumber, children, isSingleColumn = false}) => {
  return <div id={id} className={`recipe-section flex flex-col transition-opacity duration-200 ${isSingleColumn ? "opacity-100 dark:opacity-100" : "opacity-60 dark:opacity-60"}`}>
      <Step title={title} stepNumber={stepNumber} titleSize="h3">
        {children}
      </Step>
    </div>;
};

export const Content = ({title, children}) => {
  return <div className="recipe-content flex flex-col">
      {title && <h1 className="text-3xl">{title}</h1>}
      {children}
    </div>;
};

export const Recipe = ({children, isSingleColumn = false}) => {
  return <div className={`pl-4 recipe-container mx-auto grid grid-cols-1 gap-10 relative ${isSingleColumn ? "md:grid-cols-1" : "md:grid-cols-2"}`}>
      {children}
    </div>;
};

export const sections = [{
  id: "configure-auth0",
  title: "Configure Auth0"
}, {
  id: "install-auth0-nextjs-sdk",
  title: "Install the Auth0 Next.js v4 SDK"
}, {
  id: "configure-the-sdk",
  title: "Configure the SDK"
}, {
  id: "create-the-auth0-sdk-client",
  title: "Create the Auth0 SDK Client"
}, {
  id: "create-a-login-page",
  title: "Create a Login Page"
}, {
  id: "add-the-landing-page-content",
  title: "Add the Landing Page Content"
}, {
  id: "run-your-application",
  title: "Run Your Application"
}];

<Recipe>
  <Content>
    This guide demonstrates how to integrate Auth0 with any new or existing Next.js application using the Auth0 Next.js v4 SDK. We recommend that you log in to follow this quickstart with examples configured for your account.

    <Section id={sections[0].id} title={sections[0].title} stepNumber="1">
      To use Auth0 services, you'll need to have an application set up in the Auth0 Dashboard. The Auth0 application is where you will configure how you want authentication to work for the project you are developing.

      ### Configure an application

      Use the interactive selector to create a new Auth0 application or select an existing application that represents the project you want to integrate with. Every application in Auth0 is assigned an alphanumeric, unique client ID that your application code will use to call Auth0 APIs through the SDK.

      Any settings you configure using this quickstart will automatically update for your Application in the [Dashboard](https://manage.auth0.com/), which is where you can manage your Applications in the future.

      If you would rather explore a complete configuration, you can view a sample application instead.

      ### Configure Callback URLs

      A callback URL is a URL in your application that you would like Auth0 to redirect users to after they have authenticated. If not set, users will not be returned to your application after they log in.

      <Callout icon="file-lines" iconType="regular">
        If you are following along with our sample project, set this to [http://localhost:3000/auth/callback](http://localhost:3000/auth/callback).
      </Callout>

      ### Configure Logout URLs

      A logout URL is a URL in your application that you would like Auth0 to redirect users to after they have logged out. If not set, users will not be able to log out from your application and will receive an error.

      <Callout icon="file-lines" iconType="regular">
        If you are following along with our sample project, set this to [http://localhost:3000](http://localhost:3000).
      </Callout>
    </Section>

    <Section id={sections[1].id} title={sections[1].title} stepNumber="2">
      Install the Auth0 Next.js SDK using npm or yarn.

      Run the following command within your project directory to install the Auth0 Next.js SDK:

      ```bash lines theme={null}
      npm i @auth0/nextjs-auth0
      ```

      The SDK exposes methods and variables that help you integrate Auth0 with your Next.js application using [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) on the backend and [React Context](https://reactjs.org/docs/context.html) with [React Hooks](https://reactjs.org/docs/hooks-overview.html) on the frontend.
    </Section>

    <Section id={sections[2].id} title={sections[2].title} stepNumber="3">
      In the root directory of your project, add the file `.env.local` with the following environment variables:

      * `AUTH0_SECRET`: A long secret value used to encrypt the session cookie. You can generate a suitable string using `openssl rand -hex 32` on the command line.

      * `APP_BASE_URL`: The base URL of your application.

      * `AUTH0_DOMAIN`: The URL of your Auth0 tenant domain. If you are using a [Custom Domain with Auth0](/docs/customize/custom-domains), set this to the value of your Custom Domain instead of the value reflected in the "Settings" tab.

      * `AUTH0_CLIENT_ID`: Your Auth0 application's Client ID.

      * `AUTH0_CLIENT_SECRET`: Your Auth0 application's Client Secret.

      The SDK will read these values from the Node.js process environment and automatically configure itself.
    </Section>

    <Section id={sections[3].id} title={sections[3].title} stepNumber="4">
      Create a file at `src/lib/auth0.ts`. This file provides methods for handling authentication, sessions and user data.

      Then, import the `Auth0Client` class from the SDK to create an instance and export it as `auth0`. This instance is used in your app to interact with Auth0.
    </Section>

    <Section id={sections[4].id} title={sections[4].title} stepNumber="5">
      <Callout icon="file-lines" iconType="regular">
        The Next.js Middleware allows you to run code before a request is completed.
      </Callout>

      Create a file at `src/middleware.ts`. This file is used to enforce authentication on specific routes.

      The `middleware` function intercepts incoming requests and applies Auth0's authentication logic. The `matcher` configuration ensures that the middleware runs on all routes except for static files and metadata.
    </Section>

    <Section id={sections[5].id} title={sections[5].title} stepNumber="6">
      The Landing page `src/app/page.tsx` is where users interact with your app. It displays different content based on whether the users is logged in or not.

      Edit the file `src/app/page.tsx` to add the `auth0.getSession()` method to determine if the user is logged in by retrieving the user session.

      If there is no user session, the method returns `null` and the app displays the Sign up or Log in buttons. If a user sessions exists, the app displays a welcome message with the user's name and a Log out button.

      <Callout icon="file-lines" iconType="regular">
        The Logout functionality is already included in the file `src/app/page.tsx`. When the user selects the Log out button, they are redirected to the Auth0 logout endpoint, which clears their session and redirects back to your app.
      </Callout>
    </Section>

    <Section id={sections[6].id} title={sections[6].title} stepNumber="7">
      Run this command to start your Next.js development server:

      ```bash lines theme={null}
      npm run dev
      ```

      Visit the url `http://localhost:3000` in your browser.

      You will see:

      * A **Sign up** and **Log in** button if the user is not authenticated.

      * A welcome message and a **Log out** button if the user is authenticated.
    </Section>

    ## Next Steps

    Excellent work! If you made it this far, you should now have login, logout, and user profile information running in your application.

    This concludes our quickstart tutorial, but there is so much more to explore. To learn more about what you can do with Auth0, check out:

    * [Auth0 Dashboard](https://manage.auth0.com/) - Learn how to configure and manage your Auth0 tenant and applications
    * [nextjs-auth0 SDK](https://github.com/auth0/nextjs-auth0) - Explore the SDK used in this tutorial more fully
    * [Auth0 Marketplace](https://marketplace.auth0.com/) - Discover integrations you can enable to extend Auth0's functionality
  </Content>

  <SideMenu sections={sections}>
    <SideMenuSectionItem id={sections[0].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[1].id}>
      <SignUpForm />
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[2].id}>
      <CodeGroup>
        ```bash .env.local lines theme={null}
        AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
        APP_BASE_URL='http://localhost:3000'
        AUTH0_DOMAIN='https://{yourDomain}'
        AUTH0_CLIENT_ID='{yourClientId}'
        AUTH0_CLIENT_SECRET='{yourClientSecret}'
        ```

        ```typescript src/lib/auth0.ts lines theme={null}
        import { Auth0Client } from "@auth0/nextjs-auth0/server";

        export const auth0 = new Auth0Client();
        ```

        ```typescript src/middleware.ts lines theme={null}
        import type { NextRequest } from "next/server";
        import { auth0 } from "./lib/auth0";

        export async function middleware(request: NextRequest) {
         return await auth0.middleware(request);
        }

        export const config = {
         matcher: [
           /*
           * Match all request paths except for the ones starting with:
           * - _next/static (static files)
           * - _next/image (image optimization files)
           * - favicon.ico, sitemap.xml, robots.txt (metadata files)
           */
           "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
         ],
        };
        ```

        ```typescript src/app/page.tsx lines  theme={null}
        import { auth0 } from "@/lib/auth0";
        import './globals.css';

        export default async function Home() {
          // Fetch the user session
          const session = await auth0.getSession();

          // If no session, show sign-up and login buttons
          if (!session) {
            return (
              <main>
                <a href="/auth/login?screen_hint=signup">
                  <button>Sign up</button>
                </a>
                <a href="/auth/login">
                  <button>Log in</button>
                </a>
              </main>
            );
          }

          // If session exists, show a welcome message and logout button
          return (
            <main>
              <h1>Welcome, {session.user.name}!</h1>
              <p>
                <a href="/auth/logout">
                  <button>Log out</button>
                </a>
              </p>
            </main>
          );
        }
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[3].id}>
      <CodeGroup>
        ```typescript src/lib/auth0.ts lines theme={null}
        import { Auth0Client } from "@auth0/nextjs-auth0/server";

        export const auth0 = new Auth0Client();
        ```

        ```bash .env.local lines theme={null}
        AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
        APP_BASE_URL='http://localhost:3000'
        AUTH0_DOMAIN='https://{yourDomain}'
        AUTH0_CLIENT_ID='{yourClientId}'
        AUTH0_CLIENT_SECRET='{yourClientSecret}'
        ```

        ```typescript src/middleware.ts lines theme={null}
        import type { NextRequest } from "next/server";
        import { auth0 } from "./lib/auth0";

        export async function middleware(request: NextRequest) {
         return await auth0.middleware(request);
        }

        export const config = {
         matcher: [
           /*
           * Match all request paths except for the ones starting with:
           * - _next/static (static files)
           * - _next/image (image optimization files)
           * - favicon.ico, sitemap.xml, robots.txt (metadata files)
           */
           "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
         ],
        };
        ```

        ```typescript src/app/page.tsx lines  theme={null}
        import { auth0 } from "@/lib/auth0";
        import './globals.css';

        export default async function Home() {
          // Fetch the user session
          const session = await auth0.getSession();

          // If no session, show sign-up and login buttons
          if (!session) {
            return (
              <main>
                <a href="/auth/login?screen_hint=signup">
                  <button>Sign up</button>
                </a>
                <a href="/auth/login">
                  <button>Log in</button>
                </a>
              </main>
            );
          }

          // If session exists, show a welcome message and logout button
          return (
            <main>
              <h1>Welcome, {session.user.name}!</h1>
              <p>
                <a href="/auth/logout">
                  <button>Log out</button>
                </a>
              </p>
            </main>
          );
        }
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[4].id}>
      <CodeGroup>
        ```typescript src/middleware.ts lines theme={null}
        import type { NextRequest } from "next/server";
        import { auth0 } from "./lib/auth0";

        export async function middleware(request: NextRequest) {
         return await auth0.middleware(request);
        }

        export const config = {
         matcher: [
           /*
           * Match all request paths except for the ones starting with:
           * - _next/static (static files)
           * - _next/image (image optimization files)
           * - favicon.ico, sitemap.xml, robots.txt (metadata files)
           */
           "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
         ],
        };
        ```

        ```bash .env.local lines theme={null}
        AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
        APP_BASE_URL='http://localhost:3000'
        AUTH0_DOMAIN='https://{yourDomain}'
        AUTH0_CLIENT_ID='{yourClientId}'
        AUTH0_CLIENT_SECRET='{yourClientSecret}'
        ```

        ```typescript src/lib/auth0.ts lines theme={null}
        import { Auth0Client } from "@auth0/nextjs-auth0/server";

        export const auth0 = new Auth0Client();
        ```

        ```typescript src/app/page.tsx lines  theme={null}
        import { auth0 } from "@/lib/auth0";
        import './globals.css';

        export default async function Home() {
          // Fetch the user session
          const session = await auth0.getSession();

          // If no session, show sign-up and login buttons
          if (!session) {
            return (
              <main>
                <a href="/auth/login?screen_hint=signup">
                  <button>Sign up</button>
                </a>
                <a href="/auth/login">
                  <button>Log in</button>
                </a>
              </main>
            );
          }

          // If session exists, show a welcome message and logout button
          return (
            <main>
              <h1>Welcome, {session.user.name}!</h1>
              <p>
                <a href="/auth/logout">
                  <button>Log out</button>
                </a>
              </p>
            </main>
          );
        }
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[5].id}>
      <CodeGroup>
        ```typescript src/app/page.tsx lines  theme={null}
        import { auth0 } from "@/lib/auth0";
        import './globals.css';

        export default async function Home() {
          // Fetch the user session
          const session = await auth0.getSession();

          // If no session, show sign-up and login buttons
          if (!session) {
            return (
              <main>
                <a href="/auth/login?screen_hint=signup">
                  <button>Sign up</button>
                </a>
                <a href="/auth/login">
                  <button>Log in</button>
                </a>
              </main>
            );
          }

          // If session exists, show a welcome message and logout button
          return (
            <main>
              <h1>Welcome, {session.user.name}!</h1>
              <p>
                <a href="/auth/logout">
                  <button>Log out</button>
                </a>
              </p>
            </main>
          );
        }
        ```

        ```bash .env.local lines theme={null}
        AUTH0_SECRET='use [openssl rand -hex 32] to generate a 32 bytes value'
        APP_BASE_URL='http://localhost:3000'
        AUTH0_DOMAIN='https://{yourDomain}'
        AUTH0_CLIENT_ID='{yourClientId}'
        AUTH0_CLIENT_SECRET='{yourClientSecret}'
        ```

        ```typescript src/lib/auth0.ts lines theme={null}
        import { Auth0Client } from "@auth0/nextjs-auth0/server";

        export const auth0 = new Auth0Client();
        ```

        ```typescript src/middleware.ts lines theme={null}
        import type { NextRequest } from "next/server";
        import { auth0 } from "./lib/auth0";

        export async function middleware(request: NextRequest) {
         return await auth0.middleware(request);
        }

        export const config = {
         matcher: [
           /*
           * Match all request paths except for the ones starting with:
           * - _next/static (static files)
           * - _next/image (image optimization files)
           * - favicon.ico, sitemap.xml, robots.txt (metadata files)
           */
           "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
         ],
        };
        ```
      </CodeGroup>
    </SideMenuSectionItem>

    <SideMenuSectionItem id={sections[6].id}>
      <SignUpForm />
    </SideMenuSectionItem>
  </SideMenu>
</Recipe>
