This guide will discuss the various capabilities within the Frontegg client-side SDKs that handle authentication. All the methods that are discussed below can be found under the @frontegg folder in your node_modules. Frontegg has two main login implementation options:
- Hosted Login
- Embedded Login
While the Frontegg Hosted Login relies on OAuth2 authentication protocol, the embedded login relies directly on Frontegg APIs for authentication. The methods for each of these login types differ. Both methods rely on fe_refresh cookie that is stores in the browser to check whether a user is authenticated or not.
useLoginWithRedirect() is a react hook that is designed for Frontegg's hosted login and checks whether the user is authenticated by sending a request to /silent route with the fe_refresh cookie (if exists). In case disableSilentRefresh is passed as true, the authentication will be handled through /authorize route, per the OIDC protocol.
If a user is not authenticated, they will be automatically redirected to[your-frontegg-domain]/oauth/account/login for authentication. In order to avoid auto-redirect, please use loadUserOnFirstLoad.
useLoginWithRedirectV2() is the extended version of useLoginWithRedirect for Frontegg's hosted login. Like the original hook, it returns an async function that starts the hosted login flow. Both versions run the same silent-authorize-first flow: they attempt a silent authorize before anything else, and generate the PKCE code_challenge, nonce, and state only if that silent check fails and a redirect actually happens (in useLoginWithRedirect the underlying call is refreshOrRequestHostedLoginAuthorize). Migrating to V2 does not add PKCE, state, or the silent round trip, because V1 already performs all of them.
What V2 adds is a different call shape and a few options. Instead of a flat additionalParams argument it accepts a single payload object, and that object exposes shouldRedirectToLogin, firstTime, and loginDirectAction alongside additionalParams. The most common reason to reach for it is loginDirectAction, which opens the hosted login box directly on a specific action, such as the sign-up tab.
The hook is exported from @frontegg/react and returns an async function:
import { useLoginWithRedirectV2 } from '@frontegg/react';
const loginWithRedirect = useLoginWithRedirectV2();
// loginWithRedirect signature:
// (payload?: {
// additionalParams?: Record<string, string>;
// shouldRedirectToLogin?: boolean;
// firstTime?: boolean;
// loginDirectAction?: LoginDirectAction;
// }) => Promise<void>The payload options are:
additionalParams(Record<string, string>): extra query parameters that are merged into the/oauth/authorizerequest, alongside the SDK-managedresponse_type,client_id,scope,redirect_uri,code_challenge, andnonce.shouldRedirectToLogin(boolean): controls what happens when the silent session check finds no active session. Set it totrueto redirect the user to the hosted login box. When it is omitted orfalse, the hook stops loading and returns without redirecting, so you can render your own unauthenticated state.firstTime(boolean): when set,refreshOrRequestHostedLoginAuthorizeV2setsisLoading: truefirst, and if the active URI is exactly/oauth/callback(theisOauthCallbackRoutecheck is a strict equality) it returns immediately, skipping both the silent authorize and the redirect. Off the callback route the flag has no effect beyond the loading state. This is the flag the SDK bootstrap passes internally alongsideloadUserOnFirstLoad, so application code rarely needs to set it.loginDirectAction(LoginDirectAction): opens the hosted login box directly on a specific action. See below.
The LoginDirectAction type is:
interface LoginDirectAction {
type: 'direct' | 'signup' | 'social-login' | 'custom-social-login';
data: any;
additionalQueryParams?: Record<string, string>;
}Under the hood the SDK base64-encodes the loginDirectAction object and passes it to the hosted login as the login_direct_action parameter. The meaning of data depends on the action type (from createLoginActionComponent and validateLoginAction in useLoginHint.tsx):
type | Meaning of data |
|---|---|
signup | Unused. validateLoginAction returns true before data is read, so the sign-up action never touches it. |
direct | An allowlisted absolute URL string (see the allowlist note below). |
social-login | A provider name, for example google. |
custom-social-login | The custom social provider id. |
The additionalQueryParams interface field is read narrowly. Today the only value consumed is prompt: 'consent' on a social-login action, so it is best kept out of the main call.
To send the user straight to the sign-up tab of the hosted login box, use the purpose-built signup action, which takes no data:
import { useLoginWithRedirectV2 } from '@frontegg/react';
const loginWithRedirect = useLoginWithRedirectV2();
const goToSignUp = () => {
loginWithRedirect({
shouldRedirectToLogin: true,
loginDirectAction: { type: 'signup' },
});
};validateLoginAction returns true for signup before it inspects data, and the action redirects to calculatedBasename + signUpUrl from useAuthRoutes(). That means it automatically respects a customized routes.signUpUrl and the shadow-DOM basename. Prefer this over a direct action pointing at a hardcoded /oauth/account/sign-up path, which breaks for any tenant that overrode signUpUrl. Use the direct type for its actual purpose: opening an allowlisted social or custom-social authorize URL, not the sign-up tab.
direct URLs are checked against an allowlist
direct URLs are checked against an allowlist
The data of a direct action is not a free-form URL. It is validated as a security allowlist that prevents the login box from being driven as an open redirect. A direct URL is accepted only if it matches one of:
- the theme's
loginBox.login.directLoginActionConfig.allowList(operatorsstartWith,endWith,contains,equals), - a known social-login authorize URL from
socialLoginUrlMapper, or - a prefix derived from the SDK's configured
baseUrl:${baseUrl}/oauth/,${baseUrl}/identity/resources/auth/v2/user/sso/default/, or${baseUrl}/frontegg/identity/resources/auth/v2/user/sso/default/.
Being absolute is necessary but not sufficient. An absolute URL on a different host (for example https://[some-other-host]/oauth/account/sign-up) is rejected exactly like a relative path. When a direct URL is rejected, the box logs the reason to the console, strips login_direct_action from the URL via history.replaceState, and falls back to the default tab.
When a direct action appears to do nothing
When a direct action appears to do nothing
Two conditions in useLoginHint.tsx explain most actions that seem to be ignored:
- The login box ignores
login_direct_actionentirely unless the landing pathname matchesroutes.loginUrlorroutes.signUpUrl. useLoginHintreturns{}and does nothing whileisLoading || isAuthenticatedistrue. So for a user who already has a valid session, the silent authorize succeeds, the hook resolves without navigating anywhere, and a Sign-up button wired to this snippet appears to do nothing.
To force the hosted login screen for a user who still holds a valid session, pass additionalParams: { prompt: 'login' }. This is the supported way to skip the silent check and always show the box. login_direct_action survives this path: it is injected into additionalParams before the additionalParams?.['prompt'] === 'login' check in refreshOrRequestHostedLoginAuthorizeV2, so your direct action still applies. The trade-off is that you always show the box and never reuse an existing session.
You can also open the hosted sign-up page with a plain link or navigation to [your-frontegg-domain]/oauth/account/sign-up. The difference is coordination, not OAuth state:
- Plain
/oauth/account/sign-uplink. Simple to add, but a raw navigation to the hosted page never starts an authorize request, so there is no PKCE verifier or state to lose. The practical consequences are that nothing coordinates the return trip back into your app, and an existing session is not checked first. useLoginWithRedirectV2with asignupaction. Opens the same sign-up tab through the SDK, so the return trip is coordinated and an existing session is checked by the silent authorize before the box is shown. Use it whenever the sign-up entry point is part of your app's authenticated flow.
This variable is supported in all client-side SDKs. The below example showcases how to pull query params or user's original route or query params. This data can be then used for redirecting a user to the original route they've tried to access, or if you use UTM, you can send these to your marketing platform.
useEffect(() => {
if (!isAuthenticated && !isLoading) {
console.log( window.location.search.toString())
window.localStorage.setItem('FRONTEGG_AFTER_AUTH_REDIRECT_URL', `/${window.location.search.toString()}`)
loginWithRedirect();
}
}, [isAuthenticated, loginWithRedirect]);This is a react hook that is designed to check whether the user is authenticated and allows to pull the user's data if they are. Unlike UseAuthUser, this hook, does not handle redirects OOTB.
This is a react hook that is designed for Frontegg's embedded login and checks whether the user is authenticated by sending a request to /refresh route with the fe_refresh cookie (if exists). If the cookie exists and valid, the user will get automatically logged in. If the cookie is does not exist or is expired, the user will get redirected automatically to the embedded login box on /account/login.
This is a react hook that is designed to check whether the user is authenticated and allows to pull the user's data if they are. Unlike UseAuthUser, and similar to UseAuth, this hook, does not handle redirects OOTB.
This method is designed to force a hard refresh of the page and user's token. The request will handle either a refresh for embedded or for a hosted login, depending on what is being passed for hostedLoginBox to the application.
This method is designed for Frontegg's embedded login. It will delete the active fe_refresh cookie in the browser and the user will get logged out. Note that if you're using Frontegg's hosted login, you should explicitly call:
${baseUrl}/oauth/logout?post_logout_redirect_uri=${window.location} as described in the hosted login guides.
Usage
Usage
See below the examples of how these methods can be imported and used in your application. For details, please refer to the integration guides.
import {
useAuth,
useAuthUser,
useAuthOrNull,
useAuthActions,
} from '@frontegg/react'
const { requestAuthorize } = useAuthActions()
const { user, isAuthenticated, isLoading } = useAuth()