Quickstart: Integrating MyAuth with Next.js (App Router)

In this guide, you’ll integrate MyAuth into a fresh Next.js App Router project, protect routes with middleware, authenticate users using redirects, and access the current user securely on both the server and client.

  • Server-first authentication using HttpOnly cookies
  • Route protection via Next.js middleware
  • Correct session handling in production

Setup

1. Create Next.js Project

MyAuth is designed specifically for the Next.js App Router. It relies on Server Components, Route Handlers, and middleware to ensure authentication is handled securely on the server.

⚠️ Pages Router is not supported.

npx create-next-app@latest myauth-app

2. Install MyAuth SDK

The @myauth/next package provides:

  • Middleware for route protection
  • Server helpers like auth() and currentUser()
  • Client hooks and providers for UI state
npm install @myauth/next

3. Environment Variables

These credentials identify your application to MyAuth and are used during secure server-side token exchanges.

  • CLIENT_ID – Safe to expose to the browser
  • CLIENT_SECRETServer-only, never exposed
NEXT_PUBLIC_CLIENT_ID=your_client_id_here
NEXT_PUBLIC_CLIENT_SECRET=your_client_secret_here

Protect Routes

4. Middleware (recommended)

This middleware runs at the edge before a request reaches your application.

  • Validates authentication cookies
  • Redirects unauthenticated users to login
  • Prevents protected routes from rendering at all

Middleware is recommended for coarse-grained access control.

import { withAuthMiddleware } from "@myauth/next";

export default withAuthMiddleware({
  clientId: process.env.NEXT_PUBLIC_CLIENT_ID!,
});

export const config = {
  matcher: ["/dashboard/:path*", "/profile/:path*"],
};

Handle Authentication

5. Root Layout + AuthProvider

MyAuth follows a server-first model. Authentication is resolved on the server and then hydrated into the client.

  • auth() runs on the server and reads HttpOnly cookies
  • The session is passed into AuthProvider
  • Client components never read cookies directly
// app/layout.tsx
import { AuthProvider } from "@myauth/next";
import { auth } from "@myauth/next"; 

export default async function RootLayout({ children }: { children: React.ReactNode }) {
  const session = await auth();

  return (
    <html lang="en">
      <body>
        <AuthProvider 
           initialSession={session}           
           clientId={process.env.NEXT_PUBLIC_CLIENT_ID!}
        >
          {children}
        </AuthProvider>
      </body>
    </html>
  );
}

6. Callback Page

After a user authenticates with MyAuth, they are redirected back to this page.

  • Exchanges authorization data for a session
  • Sets secure HttpOnly cookies
  • Redirects the user back to your app
import { AuthenticateWithRedirectCallback } from "@myauth/next";

export default function CallbackPage() {
  return <AuthenticateWithRedirectCallback />;
}

7. Token Exchange Route

This route runs only on the server and is responsible for securely exchanging authentication data for a valid session.

Your client secret is never exposed to the browser.

import { createAuthCallbackHandler } from "@myauth/next";

export const POST = createAuthCallbackHandler({
  clientId: process.env.NEXT_PUBLIC_CLIENT_ID!,
  clientSecret: process.env.NEXT_PUBLIC_CLIENT_SECRET!,
});

What’s next?

  • Use currentUser() in Server Components
  • Use useUser() for client-side UI
  • Deploy safely to production