---
title: Hooks and overrides
description: Customize the authentication flow to trigger events like analytics or database updates.
sidebar:
  order: 5
---

**SuperTokens** exposes a set of constructs that allow you to trigger different actions during the authentication lifecycle or to even fully customize the logic based on your use case.
The following sections describe how you can adjust the `thirdparty` recipe to your needs.

Explore the [references pages](/references) for a more in depth guide on hooks and overrides.

## Frontend hook

<UITypeSwitch />

<VariantContent storageKey="ui-type" value="prebuilt">

This method gets fired, with the `SUCCESS` action, immediately after a successful sign in or sign up.
Follow the code snippet to determine if the user is signing up or signing in.

With this method you can fire events immediately after a successful sign in.
You can use it to send analytics events.

<CodeGroup group="frontend-prebuilt-ui">
<Tab title="Reactjs" value="reactjs">
```tsx
import SuperTokens from "supertokens-auth-react";
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    ThirdParty.init({
      onHandleEvent: async (context) => {
        if (context.action === "SUCCESS") {
          if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
            // TODO: Sign up
          } else {
            // TODO: Sign in
          }
        }
      },
    }),
    Session.init(),
  ],
});
```
</Tab>
<Tab title="Angular" value="angular">
```tsx check=false reason="This example omits surrounding application and SuperTokens configuration."
// this goes in the auth route config of your frontend app (once the pre-built UI script has been loaded)

supertokensUIInit({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  recipeList: [
    supertokensUIThirdParty.init({
      onHandleEvent: async (context) => {
        if (context.action === "SUCCESS") {
          if (context.isNewRecipeUser && context.user.loginMethods.length === 1) {
            // TODO: Sign up
          } else {
            // TODO: Sign in
          }
        }
      },
    }),
    supertokensUISession.init(),
  ],
});
```
</Tab>
</CodeGroup>

</VariantContent>

<VariantContent storageKey="ui-type" value="custom">

:::warning[Not applicable]
This section is not applicable for custom UI since you are calling the `signInUp` API yourself anyway. You can do anything you want post `signIn` / `signUp` based on the result of the API call.
:::

</VariantContent>

## Backend override

Overriding the `signInUp` function allows you to introduce your own logic for the sign in process.
Use it to persist different types of data or trigger actions.

<CodeGroup group="backend-language">
<Tab title="Node.js" value="nodejs">
```tsx
import SuperTokens from "supertokens-node";
import ThirdParty from "supertokens-node/recipe/thirdparty";
import Session from "supertokens-node/recipe/session";

SuperTokens.init({
  appInfo: {
    apiDomain: "...",
    appName: "...",
    websiteDomain: "...",
  },
  supertokens: {
    connectionURI: "...",
  },
  recipeList: [
    ThirdParty.init({
      signInAndUpFeature: {
        providers: [
          /* ... */
        ],
      },
      override: {
        functions: (originalImplementation) => {
          return {
            ...originalImplementation,
            signInUp: async function (input) {
              // First we call the original implementation of signInUp.
              let response = await originalImplementation.signInUp(input);

              // Post sign up response, we check if it was successful
              if (response.status === "OK") {
                let { id, emails } = response.user;

                // This is the response from the OAuth 2 provider that contains their tokens or user info.
                let providerAccessToken = response.oAuthTokens["access_token"];
                let firstName = response.rawUserInfoFromProvider.fromUserInfoAPI!["first_name"];

                if (input.session === undefined) {
                  if (response.createdNewRecipeUser && response.user.loginMethods.length === 1) {
                    // TODO: Post sign up logic
                  } else {
                    // TODO: Post sign in logic
                  }
                }
              }
              return response;
            },
          };
        },
      },
    }),
    Session.init({
      /* ... */
    }),
  ],
});
```
</Tab>
<Tab title="Go" value="go">
```go
import (
	"fmt"

	"github.com/supertokens/supertokens-golang/recipe/thirdparty"
	"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
	"github.com/supertokens/supertokens-golang/supertokens"
)

func main() {
	supertokens.Init(supertokens.TypeInput{
		RecipeList: []supertokens.Recipe{
			thirdparty.Init(&tpmodels.TypeInput{
				Override: &tpmodels.OverrideStruct{
					Functions: func(originalImplementation tpmodels.RecipeInterface) tpmodels.RecipeInterface {
						// create a copy of the originalImplementation
						originalSignInUp := *originalImplementation.SignInUp

						// override the sign in up function
						(*originalImplementation.SignInUp) = func(thirdPartyID string, thirdPartyUserID string, email string, oAuthTokens map[string]interface{}, rawUserInfoFromProvider tpmodels.TypeRawUserInfoFromProvider, tenantId string, userContext *map[string]interface{}) (tpmodels.SignInUpResponse, error) {

							// First we call the original implementation of SignInUp.
							response, err := originalSignInUp(thirdPartyID, thirdPartyUserID, email, oAuthTokens, rawUserInfoFromProvider, tenantId, userContext)
							if err != nil {
								return tpmodels.SignInUpResponse{}, err
							}

							if response.OK != nil {
								// sign in / up was successful

								// user object contains the ID and email of the user
								user := response.OK.User
								fmt.Println(user)
								fmt.Println(user.ID)
								fmt.Println(user.Email)

								providerAccessToken := response.OK.OAuthTokens["access_token"].(string)
								firstname := response.OK.RawUserInfoFromProvider.FromUserInfoAPI["first_name"].(string)

								fmt.Println(providerAccessToken)
								fmt.Println(firstname)

								if response.OK.CreatedNewUser {
									// TODO: Post sign up logic
								} else {
									// TODO: Post sign in logic
								}

							}
							return response, nil
						}

						return originalImplementation
					},
				},
			}),
		},
	})
}
```
</Tab>
<Tab title="Python" value="python">
```python check=false reason="This example omits surrounding application and SuperTokens configuration."
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import thirdparty
from supertokens_python.recipe.thirdparty.interfaces import (
    RecipeInterface,
    SignInUpOkResult,
)
from supertokens_python.recipe.thirdparty.types import RawUserInfoFromProvider
from typing import Dict, Any, Optional, Union
from supertokens_python.recipe.session.interfaces import SessionContainer


def override_thirdparty_functions(
    original_implementation: RecipeInterface,
) -> RecipeInterface:
    original_sign_in_up = original_implementation.sign_in_up

    async def sign_in_up(
        third_party_id: str,
        third_party_user_id: str,
        email: str,
        is_verified: bool,
        oauth_tokens: Dict[str, Any],
        raw_user_info_from_provider: RawUserInfoFromProvider,
        session: Optional[SessionContainer],
        should_try_linking_with_session_user: Union[bool, None],
        tenant_id: str,
        user_context: Dict[str, Any],
    ):
        result = await original_sign_in_up(
            third_party_id,
            third_party_user_id,
            email,
            is_verified,
            oauth_tokens,
            raw_user_info_from_provider,
            session,
            should_try_linking_with_session_user,
            tenant_id,
            user_context,
        )

        if isinstance(result, SignInUpOkResult):
            # user object contains the ID and email of the user
            user = result.user
            print(user)

            # This is the response from the OAuth 2 provider that contains their tokens or user info.
            provider_access_token = result.oauth_tokens["access_token"]
            print(provider_access_token)

            if result.raw_user_info_from_provider.from_user_info_api is not None:
                first_name = result.raw_user_info_from_provider.from_user_info_api[
                    "first_name"
                ]
                print(first_name)

            if session is None:
                if (
                    result.created_new_recipe_user
                    and len(result.user.login_methods) == 1
                ):
                    print("New user was created")
                    # TODO: Post sign up logic
                else:
                    print("User already existed and was signed in")
                    # TODO: Post sign in logic

        return result

    original_implementation.sign_in_up = sign_in_up

    return original_implementation


init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework="...",
    recipe_list=[
        thirdparty.init(
            override=thirdparty.InputOverrideConfig(
                functions=override_thirdparty_functions
            ),
            sign_in_and_up_feature=thirdparty.SignInAndUpFeature(providers=[]),
        )
    ],
)
```
</Tab>
</CodeGroup>


---

## See also

<CardGroup cols={3}>
  <Card title="Frontend function overrides" href="/references/frontend-sdks/function-overrides" />
  <Card title="Frontend hooks" href="/references/frontend-sdks/hooks" />
  <Card title="React component override" href="/references/frontend-sdks/prebuilt-ui/override-react-components" />
  <Card title="Backend function overrides" href="/references/backend-sdks/function-overrides" />
  <Card title="Backend API overrides" href="/references/backend-sdks/api-overrides" />
  <Card title="Invite based sign up" href="/authentication/social/custom-invite-flow" />
</CardGroup>
