1. Frontend
  2. Next.js Frontend Reference

Your project can also have backend APIs (using API Routes) which are covered in our API route reference.

Installation

$ npm install --save @propelauth/react

Set up AuthProvider

AuthProvider is the provider of a React context that manages the current user’s access token and metadata. You cannot use the other hooks without it. AuthProvider is the component that manages authentication information and all other components fetches from it.

It is recommended to put the AuthProvider component at the top level of your application, so it never unmounts.

You should place it in pages/_app.jsx or pages/_app.tsx:

import { AuthProvider } from "@propelauth/react";

const MyApp = ({ Component, pageProps }) => {
  return (
    <AuthProvider authUrl={process.env.NEXT_PUBLIC_AUTH_URL}>
      <Component {...pageProps} />
    </AuthProvider>
  );
};

export default MyApp;

RequiredAuthProvider

If your entire application requires a user to be logged in, you can instead use RequiredAuthProvider.

import { RequiredAuthProvider, RedirectToLogin } from "@propelauth/react";

const MyApp = ({ Component, pageProps }) => {
  return (
    <RequiredAuthProvider
        authUrl={process.env.NEXT_PUBLIC_AUTH_URL}
        displayWhileLoading={<Loading />}
        displayIfLoggedOut={<RedirectToLogin />}
    >
      <Component {...pageProps} />
    </RequiredAuthProvider>
  );
};

export default MyApp;

RequiredAuthProvider has two additional props:

  1. displayWhileLoading: A React element to display while the AuthProvider is fetching auth information. Defaults to an empty element
  2. displayIfLoggedOut: A React element to display if the current user is logged out. Defaults to RedirectToLogin

Get current user information

There are three options for getting the current user’s information.

withAuthInfo

withAuthInfo wraps a component and automatically adds auth information to the props of the component.

withAuthInfo(Component, {
    // A React element to display while the AuthProvider is fetching auth information. Defaults to an empty element
    displayWhileLoading: <div>Loading...</div>,
});

The following props are injected to the underlying component:

PropDescription
accessTokenIf user is logged in, this string can be passed in and validated by your backend. Otherwise, null.
isLoggedInReturns user logged in status
orgHelperA class with useful functions for managing organizations
accessHelperA class with useful functions for accessing role and permissions (RBAC)
userIf user is logged in, this contains metadata about them. Otherwise, null

withRequiredAuthInfo

This is identical to withAuthInfo, except Component is only rendered if the user is logged in. You are guaranteed that isLoggedIn is true and the accessToken is not null.

withRequiredAuthInfo(Component, {
    // A React element to display while the AuthProvider is fetching auth information. Defaults to an empty element
    displayWhileLoading: <div>Loading...</div>,
    // A React element to display if the current user is logged out. Defaults to <RedirectToLogin />
    displayIfLoggedOut: <div>You are logged out</div>,
});

useAuthInfo

import { useAuthInfo } from "@propelauth/react";

function MinimalExample() {
  const authInfo = useAuthInfo();

  // Unlike the higher order functions, we need to check the loading case now
  if (authInfo.loading) {
    return <div>Loading...</div>;
  } else if (authInfo.isLoggedIn) {
    return <div>You are logged in as {props.user.email}</div>;
  } else {
    return <div>You are not logged in</div>;
  }
}

export default MinimalExample;

A React hook which gets auth information. authInfo contains:

KeyDescription
loadingTrue if the AuthProvider is still fetching auth information. This will only happen once when the application is first loaded.
accessTokenIf user is logged in, this string can be passed in and validated by your backend. Otherwise, null.
isLoggedInReturns user logged in status
orgHelperA class with useful functions for managing organizations
accessHelperA class with useful functions for accessing role and permissions (RBAC)
userIf user is logged in, this contains metadata about them. Otherwise, null

When is an external API call made?

The AuthProvider context manages all external API requests. The functions withAuthInfo, withRequiredAuthInfo, and useAuthInfo only extract information from requests without making their own requests. For this reason, you can (and should) add as many of these functions as you need.

Logout

function LogoutButton() {
    const logoutFn = useLogoutFunction(); // (1)
    return <button onClick={() => logoutFn(true) /*(2)*/}>Logout</button>
}
  1. A React hook that returns a function which logs the current user out.
  2. The function takes a single parameter redirectOnLogout. If true, the function will redirect the user to the logout URL configured in the Frontend Integration section of your project.

useRedirectFunctions

function SignupAndLoginButtons() {
  const { redirectToSignupPage, redirectToLoginPage } = useRedirectFunctions();
  return (
    <div>
      <button onClick={redirectToSignupPage}>Signup</button>
      <button onClick={redirectToLoginPage}>Login</button>
    </div>
  );
}

A React hook that returns a collection of functions which redirect the user to useful locations.

FunctionDescription
redirectToAccountPage()Redirects the user to the account hosted authentication page, where they can view/modify their user information.
redirectToSignupPage(options?: RedirectToSignupOptions)Redirects the user to the signup hosted authentication page.
redirectToLoginPage(options?: RedirectToLoginOptions)Redirects the user to the login hosted authentication page.
redirectToOrgPage(orgId?)Redirects the user to an organization management hosted authentication page. If orgId is specified, redirect to that organization’s page. If none is specified, a default is chosen deterministically.
redirectToCreateOrgPage()Redirects the user to the hosted authentication page where they can create organizations.

Redirecting to the signup or login page allows you to specify some options:

export interface RedirectToSignupOptions {
    // This must be a full URL and can only be a URL for a domain you have verified
    postSignupRedirectUrl: string
}

export interface RedirectToLoginOptions {
    // This must be a full URL and can only be a URL for a domain you have verified
    postLoginRedirectUrl: string
}

RedirectToLogin

A React component that redirects the user to the login hosted authentication page when rendered. This is identical to calling redirectToLoginPage from useRedirectFunctions.

function Private(props) {
  return <div>You are logged in as {props.user.email}</div>;
}

export default withRequiredAuthInfo(Private, {
  // When this component is rendered, if the user isn't logged in, it will redirect to the login page
  displayIfLoggedOut: <RedirectToLogin />,
});

RedirectToSignup

A React component that redirects the user to the signup hosted authentication page when rendered. This is identical to calling redirectToSignupPage from useRedirectFunctions.

function Private(props) {
  return <div>You are logged in as {props.user.email}</div>;
}

export default withRequiredAuthInfo(Private, {
  // When this component is rendered, if the user isn't logged in, it will redirect to the signup page
  displayIfLoggedOut: <RedirectToSignup />,
});

Schemas

The User object

type User = {
    userId: string

    email: string
    emailConfirmed: boolean,

    hasPassword: boolean,

    username?: string
    firstName?: string,
    lastName?: string,
    pictureUrl?: string,

    locked: boolean,
    enabled: boolean,
    mfaEnabled: boolean,

    createdAt: number,
    lastActiveAt: number,

    legacyUserId?: string
}

orgHelper

The orgHelper helps manage the current user’s organization information with ease. It’s an object which has the following functions (types included):

type OrgHelper = {
    // returns all orgs that the user is a member of
    getOrgs: () => OrgMemberInfo[],
    // returns all org ids that the user is a member of
    getOrgIds: () => string[],
    // returns org information for a given orgId
    getOrg: (orgId: string) => OrgMemberInfo | undefined,
    // returns org information for a given org by name
    getOrgByName: (orgName: string) => OrgMemberInfo | undefined,
}
type OrgMemberInfo = {
    orgId: string,
    orgName: string,
    urlSafeOrgName: string
    // The role of the user within this organization
    userAssignedRole: string
    userPermissions: string[]
}

You can either get the orgHelper from useAuthInfo, withAuthInfo, or withRequiredAuthInfo - or you can access it directly from the hook useOrgHelper.

accessHelper

Your users will have a role in an organization. By default, these roles are Owner, Admin, and Member - but you can configure them. Each role can have permissions associated with them. See roles and permissions for more details.

The accessHelper, provided by withAuthInfo, withRequiredAuthInfo, or useAuthInfo, helps check the current user’s role and permission(s) within a specific organization.

type AccessHelper = {
    isRole: (orgId: string, role: string) => boolean
    isAtLeastRole: (orgId: string, role: string) => boolean
    hasPermission: (orgId: string, permission: string) => boolean
    hasAllPermissions: (orgId: string, permissions: string[]) => boolean
}

Active Organization

Since users can be in more than one organization, one common use case is to pick a single organization that your user is currently operating within.

Commonly, developers use localStorage, a path parameter, or subdomain (e.g. https://CUSTOMER.yourproduct.com or https://app.yourproduct.com/CUSTOMER) to indicate which organization the user is currently operating within.

The AuthProvider and RequiredAuthProvider optionally take in a getActiveOrgFn which enables you to select the currently active organization, like so:

// Get the active org from a path parameter grabbed from our router
<AuthProvider authUrl={AUTH_URL} getActiveOrgFn={() => router.query.orgName}>

useActiveOrg allows you to fetch the active organization later on. It will also verify that the current user is actually in that organization.

function OrgName() {
  const org = useActiveOrg();
  return <div>{org.orgName}</div>;
}

Examples

Display the users email for logged in users

function Example(props) {
  // isLoggedIn and user are injected automatically from withAuthInfo below
  if (props.isLoggedIn) {
    return <div>Email: {props.user.email}</div>;
  } else {
    return <div>Email: None</div>;
  }
}

export default withAuthInfo(Example);

Display buttons for signup and login

function SignupAndLoginButtons() {
  const { redirectToSignupPage, redirectToLoginPage } = useRedirectFunctions();
  return (
    <div>
      <button onClick={redirectToSignupPage}>Signup</button>
      <button onClick={redirectToLoginPage}>Login</button>
    </div>
  );
}

Display Signup and Login buttons (for logged out users) or a Logout button (for logged in users)

import {
  withAuthInfo,
  useLogoutFunction,
  useRedirectFunctions,
} from "@propelauth/react";

function AuthenticationButtons({ isLoggedIn }) {
  const logoutFn = useLogoutFunction();
  const { redirectToSignupPage, redirectToLoginPage } = useRedirectFunctions();

  if (isLoggedIn) {
    return <button onClick={() => logoutFn(true)}>Logout</button>;
  } else {
    return (
      <div>
        <button onClick={redirectToSignupPage}>Signup</button>
        <button onClick={redirectToLoginPage}>Login</button>
      </div>
    );
  }
}

export default withAuthInfo(AuthenticationButtons);

Display the user’s profile picture

You must enable Profile Picture support first.

import { withAuthInfo } from "@propelauth/react";

function ProfilePicture({ isLoggedIn, user }) {
  if (isLoggedIn) {
    return <img src={user.pictureUrl} />;
  } else {
    return null;
  }
}

export default withAuthInfo(ProfilePicture);

Note: Client Side Rendering vs Server Side Rendering

PropelAuth currently supports Client Side Rendering (CSR) Next.js workflows. You can still use Server Side Rendering (SSR) anywhere in your application, but to fetch authenticated content, you’ll need to perform a fetch client side. You can read more about the differences here.