Pages router embedded login quickstart
This guide walks you through integrating Frontegg’s login box into your Next.js app, with built-in support for Sign In, Sign Up, SSO, and automatic redirects—all in just a few lines of code.
Important notes and prerequisites
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
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 pages
architecture
Create custom Next.js files under the pages
directory and paste the snippets below. If you have a custom app already (the file _app.tsx
exists), wrap and replace the default export component with withFronteggApp
function and pass your original component.
import { withFronteggApp } from "@frontegg/nextjs/pages";
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
},
});
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'
# By default on each refresh of the page the next middleware will try to refresh the access token even if it’s still valid. The below option allows to disable that behavior and re-use the access token and thus to improve refresh times
# Only for pages directory.
DISABLE_INITIAL_PROPS_REFRESH_TOKEN=true
FRONTEGG_HOSTED_LOGIN='false' // required from @frontegg/nextjs@9.1.1
# 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!
Working with SAML / OIDC on Frontegg Embedded Login and using SSR
Working with SAML / OIDC on Frontegg Embedded Login and using SSR
You will need to configure the Single Sign On URL on your IDP to use
git[your-application-url]/api/frontegg/saml/callback
, instead of the ACS URL that you have configured on the Frontegg portal. The configuration on the Frontegg portal can stay the same as configured per Configuring SAML guide.
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: '/(.*)',
};
Step 6: Redirect to login from a page
Alternatively to middleware.ts
, you can use the Frontegg withSSRSession
on each page, to redirect users to the login screen if they are not authenticated.
import { useCallback } from "react";
import { GetServerSideProps } from "next";
import { getSession } from "@frontegg/nextjs/pages";
import { useAuth } from "@frontegg/nextjs";
import { useRouter } from "next/router"
export default function MyPage({ products }) {
const { user } = useAuth();
const router = useRouter();
const logout = useCallback(() => {
router.replace('/account/logout');
}, [router]);
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>
);
}
// 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.
export const getServerSideProps: GetServerSideProps = withSSRSession(
async (context, session) => {
// const { data } = await fetch('{external}/product', {
// headers: {
// Authorization: 'bearer ' + session.accessToken,
// },
// });
return { props: {} };
}
);
Step 7: (optional) getSession
As an extension of step 6, 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/pages';
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: [] } };
};