Last updated

App router hosted login quickstart

Important notes and prerequisites

Frontegg Next.js integration is dependent on SSR (Server Side Rendering). Consequently, Frontegg hooks will not work with Static Site Generation (SSG).
Required minimum versions:
Next.js ≥ 12
Typescript ≥ 3.9.7
@frontegg/nextjs@7.0.0


Getting your Frontegg subdomain and clientId

Frontegg creates a unique subdomain and clientId 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 Keys & domains menu, copy the Frontegg domain and clientId and use them in .env.local file.

Step 1: Create a Frontegg Next.js app


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


npx create-next-app@latest my-nextjs-app-name

cd my-nextjs-app-name

Step 2: Install @frontegg/nextjs

Run the following command to install @frontegg/nextjs.


npm install @frontegg/nextjs@latest

Step 3: Configure the app file, router, middleware files

When integrating Next.js application with Frontegg, Next.js custom app and several files should be added. Make sure that these exist in the project you cloned from our sample or created.

Next.js appDir Architecture

Create custom Next.js files under app directory and paste the snippets below. Note, that the [...frontegg-middleware].ts which handles SSR should be located in pages directory as below:

import { FronteggAppProvider } from '@frontegg/nextjs/app';

export default function RootLayout({ children }: { children: React.ReactNode }) {
    const authOptions = {
      keepSessionAlive: true // Uncomment this in order to maintain the session alive
    }
    
    return (
      <html>
        <head></head>
        <body>
            {/* @ts-expect-error Server Component for more details visit: https://github.com/vercel/next.js/issues/42292 */}
            <FronteggAppProvider authOptions={authOptions} hostedLoginBox={true}>
                {children}
            </FronteggAppProvider>
        </body>
      </html>
    );
}

Step 4: 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:

# 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 environment's Client ID
FRONTEGG_CLIENT_ID='[YOUR_CLIENT_ID]'

# Your Frontegg application ID
# Available from @frontegg/nextjs@9.2.0
FRONTEGG_APP_ID='[YOUR_APP_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='[64_CHAR_SESSION_ENCRYPTION_PASSWORD]'

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

FRONTEGG_HOSTED_LOGIN='true'

# For printing verbose log messages in regards to nextjs middleware activity
#FRONTEGG_LOG_LEVEL="debug"

# For improving nextjs perfomrance by providing environment public key to the nextjs middleware.
# The values can be found under [ENVIRONMENT] → Authentication → Identity provider → OIDC endpoints → JSON web key. 
# Extract the object from within the `keys` array and use it as the below variable.
#FRONTEGG_JWT_PUBLIC_KEY='{"kty":"RSA", "kid":"xxx", "use":"sig", "alg":"RS256", "n":"xxxx", "e":"xxx"}'

Remember to replace the relevant fields in this file with your account's information!

Step 5: (optional) NextRequest

It is recommended to check for the user's session either on the middleware.ts or per each page. It is not recommended to use several sources for getting or checking for a user's session.

Frontegg uses getInitialProps in the Next.js wrapper, therefore, there is no need to call default getInitialProps and instead use context. Frontegg wrapper holds this data already.


import { NextRequest } from 'next/server';
import { handleSessionOnEdge } from '@frontegg/nextjs/edge';

export const middleware = async (request: NextRequest) => {
  const { pathname, searchParams } = request.nextUrl;
  const headers = request.headers;

  // shouldByPassMiddleware from getSessionOnEdge was moved under the hood of handleSessionOnEdge

  // Additional logic if needed

  return handleSessionOnEdge({ request, pathname, searchParams, headers });
};

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