Sign in

Protect Server Components

This guide shows how to protect Server Components in a Next.js App Router application using protectPage().

Protected server components require authentication and can optionally enforce group-based authorization and customize redirects.

What you'll cover

  • Protect a Server Component with protectPage()
  • Customize where users return after signing in
  • Restrict access based on group membership
  • Render custom UI for unauthenticated users or users without required permissions

Before you begin

This guide assumes you’ve completed the Next.js App Router quickstart.

You should already have:

  • A Next.js App Router project
  • Environment variables configured in .env.local
  • Authentication middleware registered
  • Any unprotected routes explicitly configured (matched routes are protected by default)

Protect a Server Component

Create a Server Component and wrap it with protectPage().

src/app/page.tsx
import { MonoCloudUser, protectPage } from "@monocloud/auth-nextjs";

type HomePageProps = {
  user: MonoCloudUser;
};

function Home({ user }: HomePageProps) {
  return <div>Hi {user.email}</div>;
}

export default protectPage(Home);

How it works:

  • The component executes on the server
  • Unauthenticated users are redirected to sign in
  • After authentication, the user object is injected as a prop

Customize the return URL

By default, users are returned to the page they attempted to access.

To redirect users to a specific route after authentication, pass a returnUrl.

src/app/page.tsx
export default protectPage(Home, {
  returnUrl: "/dashboard",
});

After authentication, users are redirected to http://localhost:3000/dashboard

Restrict access by group

You can restrict access to users belonging to specific groups.

Enable group claims

  1. In the MonoCloud Dashboard, add groups to the application scopes
  2. Update your .env.local:
.env.local
MONOCLOUD_AUTH_SCOPES=openid profile email groups
After updating scopes, users must sign out and sign back in for the new claims to be included in their session.

Require a group

src/app/page.tsx
export default protectPage(Home, {
  groups: ["admin"],
});

With this configuration, only authenticated users in the admin group can access the page.

Handle access denied (Unauthenticated)

Use onAccessDenied to render custom UI when the user is not authenticated.

src/app/page.tsx
export default protectPage(Home, {
  onAccessDenied: () => (
    <div>
      <h1>Access Denied</h1>
      <p>Please sign in to continue.</p>
    </div>
  )
});

How it works:

  • Runs when no authenticated session exists.
  • If onAccessDenied is not provided, the user is automatically redirected to the sign-in flow.

Handle access denied (Group authorization)

Use onGroupAccessDenied to render custom UI when the user is authenticated but does not belong to the required group. This callback receives the authenticated user.

src/app/page.tsx
export default protectPage(Home, {
  groups: ['admin'],
  onGroupAccessDenied: ({ user }) => (
    <div>
      <h1>Unauthorized</h1>
      <p>User {user.email}, does not have access to this page.</p>
    </div>
  ),
});

How it works:

  • Runs when a valid session exists but the group check fails.
  • If onGroupAccessDenied is not provided, a default Access Denied message is rendered.

Next steps

Protect other parts of your application:

© 2024 MonoCloud. All rights reserved.