Hooks
Handle user actions for logging, analytics, or side effects using the Handle Event Hook.
Overview
Hooks are a way to trigger custom logic when certain actions happen in the authentication process.
Handle event hook
Each frontend recipe emits events when certain actions happen. You can use this hook to trigger side effects when something happens in the authentication process. This can address things like logging or analytics.
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
EmailPassword.init({
onHandleEvent: (context) => {
if (context.action === "PASSWORD_RESET_SUCCESSFUL") {
} else if (context.action === "RESET_PASSWORD_EMAIL_SENT") {
} else if (context.action === "SUCCESS") {
if (context.createdNewSession) {
let user = context.user;
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// sign up success
} else {
// sign in success
}
} else {
// during step up or second factor auth with email password
}
}
},
});
ThirdParty.init({
onHandleEvent: (context) => {
if (context.action === "SUCCESS") {
if (context.createdNewSession) {
let user = context.user;
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// sign up success
} else {
// sign in success
}
} else {
// during linking a social account to an existing account
}
}
},
});// this goes in the auth route config of your frontend app (once the pre-built UI script has been loaded)
supertokensUIEmailPassword.init({
onHandleEvent: (context) => {
if (context.action === "PASSWORD_RESET_SUCCESSFUL") {
} else if (context.action === "RESET_PASSWORD_EMAIL_SENT") {
} else if (context.action === "SUCCESS") {
if (context.createdNewSession) {
let user = context.user;
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// sign up success
} else {
// sign in success
}
} else {
// during step up or second factor auth with email password
}
}
},
});
supertokensUIThirdParty.init({
onHandleEvent: (context) => {
if (context.action === "SUCCESS") {
if (context.createdNewSession) {
let user = context.user;
if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
// sign up success
} else {
// sign in success
}
} else {
// during linking a social account to an existing account
}
}
},
});Pre-API hook
This function calls the backend before any API call. You can use this to change the request properties.
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
ThirdParty.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "GET_AUTHORISATION_URL") {
} else if (action === "THIRD_PARTY_SIGN_IN_UP") {
// Note: this could either be sign in or sign up.
// we don't know that at the time of the API call
// since all we have is the authorisation code from
// the social provider
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});
EmailPassword.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "EMAIL_EXISTS") {
} else if (action === "EMAIL_PASSWORD_SIGN_IN") {
} else if (action === "EMAIL_PASSWORD_SIGN_UP") {
} else if (action === "SEND_RESET_PASSWORD_EMAIL") {
} else if (action === "SUBMIT_NEW_PASSWORD") {
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});// this goes in the auth route config of your frontend app (once the pre-built UI script has been loaded)
supertokensUIThirdParty.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "GET_AUTHORISATION_URL") {
} else if (action === "THIRD_PARTY_SIGN_IN_UP") {
// Note: this could either be sign in or sign up.
// we don't know that at the time of the API call
// since all we have is the authorisation code from
// the social provider
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});
supertokensUIEmailPassword.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "EMAIL_EXISTS") {
} else if (action === "EMAIL_PASSWORD_SIGN_IN") {
} else if (action === "EMAIL_PASSWORD_SIGN_UP") {
} else if (action === "SEND_RESET_PASSWORD_EMAIL") {
} else if (action === "SUBMIT_NEW_PASSWORD") {
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});import ThirdParty from "supertokens-web-js/recipe/thirdparty";
import EmailPassword from "supertokens-web-js/recipe/emailpassword";
EmailPassword.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "EMAIL_EXISTS") {
} else if (action === "EMAIL_PASSWORD_SIGN_IN") {
} else if (action === "EMAIL_PASSWORD_SIGN_UP") {
} else if (action === "SEND_RESET_PASSWORD_EMAIL") {
} else if (action === "SUBMIT_NEW_PASSWORD") {
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});
ThirdParty.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "GET_AUTHORISATION_URL") {
} else if (action === "THIRD_PARTY_SIGN_IN_UP") {
// Note: this could either be sign in or sign up.
// we don't know that at the time of the API call
// since all we have is the authorisation code from
// the social provider
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});supertokensEmailPassword.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "EMAIL_EXISTS") {
} else if (action === "EMAIL_PASSWORD_SIGN_IN") {
} else if (action === "EMAIL_PASSWORD_SIGN_UP") {
} else if (action === "SEND_RESET_PASSWORD_EMAIL") {
} else if (action === "SUBMIT_NEW_PASSWORD") {
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});
supertokensThirdParty.init({
preAPIHook: async (context) => {
let url = context.url;
let requestInit = context.requestInit;
let action = context.action;
if (action === "GET_AUTHORISATION_URL") {
} else if (action === "THIRD_PARTY_SIGN_IN_UP") {
// Note: this could either be sign in or sign up.
// we don't know that at the time of the API call
// since all we have is the authorisation code from
// the social provider
}
// events such as sign out are in the
// session recipe pre API hook (See the info box below)
return {
requestInit,
url,
};
},
});import SuperTokens from "supertokens-react-native";
SuperTokens.init({
apiDomain: "...",
preAPIHook: async (context) => {
let requestInit = context.requestInit;
if (context.action === "REFRESH_SESSION") {
requestInit.headers = {
...requestInit.headers,
customHeader: "custom-header",
};
} else if (context.action === "SIGN_OUT") {
requestInit.headers = {
...requestInit.headers,
customHeader: "custom-header",
};
}
return {
...context,
requestInit,
};
},
});import android.app.Application
import com.supertokens.session.CustomHeaderProvider
import com.supertokens.session.SuperTokens
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
SuperTokens.Builder(applicationContext, "...").customHeaderProvider(object : CustomHeaderProvider {
override fun getRequestHeaders(requestType: CustomHeaderProvider.RequestType?): MutableMap<String, String> {
var headers: MutableMap<String, String> = HashMap()
if (requestType == CustomHeaderProvider.RequestType.REFRESH) {
headers["custom-header"] = "custom-value"
} else if (requestType == CustomHeaderProvider.RequestType.SIGN_OUT) {
headers["custom-header"] = "custom-value"
}
return headers
}
}).build()
}
}import UIKit
import SuperTokensIOS
fileprivate class MyApplicationDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
do {
try SuperTokens.initialize(
apiDomain: "...",
preAPIHook: {
action, request in
let mutableRequest = (request as NSURLRequest).mutableCopy() as! NSMutableURLRequest
if action == .REFRESH_SESSION {
mutableRequest.addValue("custom-value", forHTTPHeaderField: "custom-header")
}
if action == .SIGN_OUT {
mutableRequest.addValue("custom-value", forHTTPHeaderField: "custom-header")
}
return mutableRequest.copy() as! URLRequest
}
)
} catch SuperTokensError.initError(let message) {
// TODO: Handle initialization error
} catch {
// Some other error
}
return true
}
}import 'package:supertokens_flutter/supertokens.dart';
void main() {
SuperTokens.init(
apiDomain: "...",
preAPIHook: (action, req) {
if (action == APIAction.SIGN_OUT) {
req.headers["custom-header"] = "custom-value";
} else if (action == APIAction.REFRESH_TOKEN) {
req.headers["custom-header"] = "custom-value";
}
return req;
},
);
}Alternatively you could also declare the pre-API hook when calling the function:
import EmailPassword from "supertokens-web-js/recipe/emailpassword";
EmailPassword.doesEmailExist({
email: "...",
options: {
preAPIHook: async (input) => {
let url = input.url;
let requestInit = input.requestInit;
// TODO: add your code here
return { url, requestInit };
},
},
});supertokensEmailPassword.doesEmailExist({
email: "...",
options: {
preAPIHook: async (input) => {
let url = input.url;
let requestInit = input.requestInit;
return { url, requestInit };
},
},
});Redirection callback hook
Use this function to change where the system redirects the user after certain actions.
For example, you can use this to redirect a user to a specific URL post sign in or sign up.
If you’re embedding the UI components in a popup and wish to disable redirection entirely, return null.
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import SuperTokens from "supertokens-auth-react";
SuperTokens.init({
appInfo: {
appName: "SuperTokens",
apiDomain: "http://localhost:3000",
websiteDomain: "http://localhost:3000",
},
getRedirectionURL: async (context) => {
if (context.action === "SUCCESS" && context.newSessionCreated) {
// called on a successful sign in / up. Where should the user go next?
let redirectToPath = context.redirectToPath;
if (redirectToPath !== undefined) {
// we are navigating back to where the user was before they authenticated
return redirectToPath;
}
if (context.createdNewUser) {
// user signed up
return "/onboarding";
} else {
// user signed in
return "/dashboard";
}
} else if (context.action === "TO_AUTH") {
// called when the user is not authenticated and needs to be redirected to the auth page.
return "/auth";
}
// return undefined to let the default behaviour play out
return undefined;
},
recipeList: [
EmailPassword.init({
getRedirectionURL: async (context) => {
if (context.action === "RESET_PASSWORD") {
// called when the user clicked on the forgot password button
}
// return undefined to let the default behaviour play out
return undefined;
},
}),
],
});// this goes in the auth route config of your frontend app (once the pre-built UI script has been loaded)
supertokensUIInit({
appInfo: {
appName: "SuperTokens",
apiDomain: "http://localhost:3000",
websiteDomain: "http://localhost:3000",
},
getRedirectionURL: async (context) => {
if (context.action === "SUCCESS" && context.newSessionCreated) {
// called on a successful sign in / up. Where should the user go next?
let redirectToPath = context.redirectToPath;
if (redirectToPath !== undefined) {
// we are navigating back to where the user was before they authenticated
return redirectToPath;
}
if (context.createdNewUser) {
// user signed up
return "/onboarding";
} else {
// user signed in
return "/dashboard";
}
} else if (context.action === "TO_AUTH") {
// called when the user is not authenticated and needs to be redirected to the auth page.
return "/auth";
}
// return undefined to let the default behaviour play out
return undefined;
},
recipeList: [
supertokensUIEmailPassword.init({
getRedirectionURL: async (context) => {
if (context.action === "RESET_PASSWORD") {
// called when the user clicked on the forgot password button
}
// return undefined to let the default behaviour play out
return undefined;
},
}),
],
});