Embed Next.js-old-12-only

Overview

In this quickstart, we will embed Frontegg login box to your Next.JS application.

🚧

We are working on supporting Next.js version 13. Contact us to get updates!


The code in the sample below is available in our Frontegg Samples repository


âš¡ Before you start: âš¡

📘

Getting your Frontegg subdomain and clientId

Frontegg creates a unique subdomain and client id for every environment created on the account. In order to retrieve the clientId subdomain that will act as the FRONTEGG_BASE_URL in the integration, navigate to your environment 'Settings' menu, copy the Frontegg domain and clientId and use them in .env.local file.


STEP 1: Create Frontegg Next.js sample app that is based on Next.js version 12

📘

If you have an existing app with Next.js version 12, skip this step.


To create a new app based on our sample, run the below commands.

npx create-next-app --example "https://github.com/frontegg/frontegg-nextjs" --example-path "apps/example" my-nextjs-app-name

cd my-nextjs-app-name
yarn create next-app --example "https://github.com/frontegg/frontegg-nextjs" --example-path "apps/example" my-nextjs-app-name

cd my-nextjs-app-name

STEP 2: Install

Run the following command to install the project with all its dependencies.

npm install
yarn

🚧

Breaking Changes from v5

@frontegg/nextjs v5 and above have been updated to support nextjs SSR, and thus have breaking changes.

📘

Note - the files in this guide are in typescript - if you are working in js, simply change the file types and remove the typing

STEP 3: Configure

Wrap the default export with withFronteggApp in ./pages/_app.tsx :

import { withFronteggApp } from '@frontegg/nextjs';

function CustomApp({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />;
}

export default withFronteggApp(CustomApp, 
  {
    hostedLoginBox: false, 
    authOptions: {
    // keepSessionAlive: true // Uncomment this in order to maintain the session alive
    }
});

If you did not set http://localhost:3000 as your app url during integration, in the frontegg portal under hosted login configuration add http://localhost:3000/oauth/callback as the allowed redirectUrl

Create files for frontegg middleware under ./pages/api/frontegg/[...frontegg-middleware].ts :

export { fronteggMiddleware as default } from '@frontegg/nextjs';

STEP 4 (optional) NextRequest

📘

Support for NextJS middleware is available from @frontegg/nextjs v6.4.0

To prevent access of an unauthenticated user to all routes, use Next.js middlewares.

NOTE: If you were using Middleware prior to 12.2, please see the upgrade guide.

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
import { getSession } from '@frontegg/nextjs';

export const middleware = async (request: NextRequest) => {
  const session = await getSession(request);

  console.log("middleware session", session);
  
  if(!session){
    // redirect unauthenticated user to /account/login page
    return NextResponse.redirect(new URL('/account/login', req.url))
  }
  
  return NextResponse.next();
};

export const config = {
  matcher: "/(.*)",
};

Create placeholder pages for frontegg router under ./pages/[...frontegg-router].tsx :

export {
  FronteggRouter as default,
  FronteggRouterProps as getServerSideProps,
} from '@frontegg/nextjs';

Setup Environment

To setup your Next.js application to communicate with Frontegg, you have to create a new file named .env.local under your root project directory, this file will be used to store environment variables that will be used, configuration options:

Remember to replace the relevant fields in this file with your personal information!

# The AppUrl you set during integration - this is to tell Frontegg your application hostname
FRONTEGG_APP_URL='http://localhost:3000'

# The Frontegg domain is your unique URL to connect to the Frontegg gateway
FRONTEGG_BASE_URL='https://[YOUR_SUBDOMAIN].frontegg.com'

# Your Frontegg application's Client ID
FRONTEGG_CLIENT_ID='[YOUR_CLIENT_ID]'

# The statless session encruption password, used to encrypt
# jwt before sending it to the client side.
#
# For quick password generation use the following command:
#    node -e "console.log(crypto.randomBytes(32).toString('hex'))"
FRONTEGG_ENCRYPTION_PASSWORD='[SESSION_ENCRYPTION_PASSWORD]'

# The statless session cookie name - you should not change this
FRONTEGG_COOKIE_NAME='fe_session'

STEP 5: Redirect to login

You can use the Frontegg withSSRSession , you can automatically redirect users to the login screen if they are not authenticated.

📘

note - in the getServerSideProps method you can get data from an external service to pull relevant data for a logged in user, we used the prop products. See the commented code for an example:

import { GetServerSideProps } from 'next';
import { withSSRSession, useAuth } from '@frontegg/nextjs';

export default function MyPage({ products }) {
  const {user} = useAuth();
  
  //baseUrl should be your FRONTEGG_APP_URL from .env.local
  const baseUrl =  'FRONTEGG_APP_URL'
  
  const logout = () => {
    window.location.href = `${baseUrl}/account/logout`;
  };

  return (
    <div>
      <h1>My Page</h1>
       {products}
      <div>
        <img src={user?.profilePictureUrl} alt={user?.name}/>
      </div>
      <div>
        <span>Logged in as: {user?.name}</span>
      </div>
            <div>
        <button onClick={logout}>Log out</button>
      </div>
    </div>
  );
}

export const getServerSideProps: GetServerSideProps = withSSRSession(
  async (context, session) => {
//     const { data } = await fetch('{external}/product', {
//      headers: {
//        Authorization: 'bearer ' + session.accessToken,
//      },
//    });
    return { props: { } };
  }
);

Great, Frontegg is now integrated with your app!

Try it now!

Run your app and you should be automatically redirected to your hosted login box.


STEP 6 (optional) getSession

As an extension of step 4, for any page that requires an AccessToken on the server side (e.g. you'd like to load the data only if a user is logged in), you can use the getSession method. Remember to replace external with the link to your external service.

import { GetServerSideProps } from 'next';
import { getSession } from '@frontegg/nextjs';

export default function MyPage({ products }) {
  return (
    <div>
      <h1>My Page</h1>
      {products}
    </div>
  );
}

export const getServerSideProps: GetServerSideProps = async (context) => {
  const session = await getSession(context.req);
  if (session) {
    const { data } = await fetch('{external}/product', {
      headers: {
        Authorization: 'bearer ' + session.accessToken,
      },
    });
    return { props: { products: data } };
  }

  return { props: { products: [] } };
};

STEP 7 (optional) customLoader

import "../styles/globals.css";

export default withFronteggApp(CustomApp, 
  {
    hostedLoginBox: false, 
    customLoader: true,
    authOptions: {
    // keepSessionAlive: true // Uncomment this in order to maintain the session alive
    }
});

Add _document.tsx file under the pages folder.

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
        <div className="custom-loader"> I am a custom loader!</div>
      </body>
    </Html>
  );
}

Add the following styles to styles/globals.css:

.custom-loader {
    width: 100vw;
    height: 100vh;
    background: red;
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    text-align: center;
    justify-content: center;
    align-items: center;
    font-size: 50px;
    color: white;
}

body.frontegg-loading .custom-loader {
    display: flex;
}

  • Signup screen is at http://localhost:3000/account/sign-up
  • Login screen is at http://localhost:3000/account/login

If you are already logged in, go to http://localhost:3000/account/logout and log out.

Give it a try now!

Open http://localhost:3000/account/sign-up and sign up with your first user.