Next.js

Integrate Passage into your Next.js application

To see a full example of using Passage in a Next.js application, please visit our sample app on Github.

Next.js is a front-end framework that builds additional functionality on top of React. Next.js by default pre-renders pages server-side to speed up delivering rendered pages and provide better SEO support. When using Passage in pre-rendered pages there are some specific changes to the standard React development workflow that need to be considered.

We have a blog post entitled Building a Next.js App with Biometrics (opens in a new tab)that provides further information on implementing with Next.js.

Importing and using the Passage-Auth custom Element

The easiest way to add authentication to a web frontend is with a Passage Auth custom element. First you'll need to install the passage-elements (opens in a new tab) package from npm:

npm i --save @passageidentity/passage-elements

Then import the package in the module where you intend to use the custom element

import '@passageidentity/passage-elements/passage-auth';

Calling the import statement on the Passage npm package triggers a side-effect that will register the custom element with the client browser for usage. Since Next.js pre-renders pages on the server this presents a common issue with using web components, such as the Passage elements, in pre-rendered pages - when the server side pre-render occurs there is no client window defined to call window.customElements.define() on, which results in an error being thrown.

The most common solution when using custom elements in pre-rendered applications is to defer the registration of the custom element to a lifecycle hook so that the code is only executed when the client app is executed in browser. See example:

export default function Home() {
 
    useEffect(()=>{
        require('@passageidentity/passage-elements/passage-auth');
    }, []);
 
    return (
        <div>
            ...
        </div>
    )
}

Typescript support

If you are using TypeScript with your Next.js application, you’ll need to add the following type declaration to your typings.d.ts file:

declare namespace JSX {
    import { PassageElement, PassageProfileElement } from '@passageidentity/passage-elements';
    interface IntrinsicElements {
        'passage-auth': PassageElement;
        'passage-login': PassageElement;
        'passage-register': PassageElement;
        'passage-profile': PassageProfileElement;
    }
}

Getting Authentication Status and User Information with Server-Side Rendering

After the user has logged in with Passage, all requests need to be authenticated using the JWT provided by Passage. Use the Passage Node.js SDK (opens in a new tab) to authenticate requests and retrieve user data for your application.

In this example, we handle authentication securely in Next.js's server-side rendering function getServerSideProps() (opens in a new tab). Per Next.js documention you can import modules in top-level scope for use in getServerSideProps. Imports used in getServerSideProps will not be bundled for the client-side. This means you can write server-side code directly in getServerSideProps.

The JWT provided by Passage is stored in both cookies and localstorage. Next.js provides the cookies set for an application to getServerSideProps which allows passing the JWT from the client browser to the server to handle authentication.

This is done in this example in pages/dashboard.js.

Note: Handling authentication in a server-side pre-rendered function is not strictly necessary. If you prefer to call an authentication endpoint on your server after the page is delivered to the client you can still do so as you otherwise might in React