Protect Server Rendered Pages

What you'll cover in this guide

  • ✅ Create a server-rendered page and protect it using protectPage()
  • ✅ Customize the return URL
Using the Next.js App Router instead? See the App Router version of this guide.

Before you get started

This guide assumes you have a Next.js project set up and running. If you haven't set up authentication in your Next.js Page Router project yet, please refer to the quickstart guide.

Create and protect a server rendered page

We'll start by setting up our server-rendered page and making sure it's only accessible to authenticated users.

Open src/pages/index.tsx in your editor and replace the contents with the following code:

src/pages/index.tsx
import { protectPage } from "@monocloud/nextjs-auth";
import { SignOut } from "@monocloud/nextjs-auth/client";
import { InferGetServerSidePropsType } from "next";

export default function Home({
  user,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  return (
    <div className="flex flex-col gap-3">
      <p>Hi {user.email} from the Server Rendered Page</p>
      <SignOut>Sign Out</SignOut>
    </div>
  );
}

export const getServerSideProps = protectPage();

Let's review what this code does:

  1. We imported the protectPage() function from @monocloud/nextjs-auth which protects the page by redirecting the user to the Sign In page if they're not already authenticated. It also injects the authenticated user's profile data as a prop to the page component.
  2. We use the user property to retrieve the user's email and display a customized greeting to the authenticated user, along with a Sign Out button.
  3. Lastly, we assign protectPage() to the getServerSideProps function to ensure that the page is only accessible to authenticated users.

See it in action by running:

Terminal
npm run dev

Then visit http://localhost:3000. Since we protected the root page, you'll be redirected to the sign-in page. Sign in and then try signing out.

Custom getServerSideProps() handler

If you need more than just authentication, such as returning custom props or setting up server-side redirects, you can supply a custom getServerSideProps function to protectPage().

Let's try this by adding a getServerSideProps function that will extract the resolvedUrl from the context and include it in the page props.

To put this into action, update the src/pages/index.tsx file as follows:

src/pages/index.tsx
import { protectPage } from "@monocloud/nextjs-auth";
import { SignOut } from "@monocloud/nextjs-auth/client";
import {
  GetServerSidePropsContext,
  InferGetServerSidePropsType,
  PreviewData,
} from "next";
import { ParsedUrlQuery } from "querystring";

export default function Home({
  user,
  url,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  return (
    <div className="flex flex-col gap-3">
      <p>Hi {user.email} from the Server Rendered Page</p>
      <p>Resolved Url: {url}</p>
      <SignOut>Sign Out</SignOut>
    </div>
  );
}

export const getServerSideProps = protectPage({
  getServerSideProps: async (
    context: GetServerSidePropsContext<ParsedUrlQuery, PreviewData>
  ) => ({
    props: { url: context.resolvedUrl },
  }),
});

To test the custom getServerSideProps function, run the application and visit http://localhost:3000. Once signed in you should see / as the resolved URL on the page.

Customizing the return URL

After sign-in, the default behavior is to redirect the user back to the page which triggered the sign-in process.

You can change that by passing the returnUrl option to the protectPage() function, which will determine where to redirect the user after a successful sign-in.

Let's try it in the page we just created. Add { returnUrl: 'custom' } as the second parameter to the protectPage() function:

src/pages/index.tsx
import { protectPage } from "@monocloud/nextjs-auth";
import { SignOut } from "@monocloud/nextjs-auth/client";
import { InferGetServerSidePropsType } from "next";

export default function Home({
  user,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
  return (
    <div className="flex flex-col gap-3">
      <p>Hi {user.email} from the Server Rendered Page</p>
      <SignOut>Sign Out</SignOut>
    </div>
  );
}

export const getServerSideProps = protectPage({ returnUrl: "custom" });

Now, after a successful sign-in, the page will redirect to https://localhost:3000/custom.