← Back
auth0 gist typescript

Auth0 typescript boilerplate

Here's the Typescript version of Auth0 boilerplate:

src/lib/auth0.tsx:

import React, { useState, useEffect, useContext } from "react";
import createAuth0Client from "@auth0/auth0-spa-js";
import Auth0Client from "@auth0/auth0-spa-js/dist/typings/Auth0Client";

interface Auth0Context {
isAuthenticated: boolean;
user: any;
loading: boolean;
popupOpen: boolean;
loginWithPopup(options: PopupLoginOptions): Promise<void>;
handleRedirectCallback(): Promise<RedirectLoginResult>;
getIdTokenClaims(o?: getIdTokenClaimsOptions): Promise<IdToken>;
loginWithRedirect(o: RedirectLoginOptions): Promise<void>;
getTokenSilently(o?: GetTokenSilentlyOptions): Promise<string | undefined>;
getTokenWithPopup(o?: GetTokenWithPopupOptions): Promise<string | undefined>;
logout(o?: LogoutOptions): void;
}

interface Auth0ProviderOptions {
children: React.ReactElement;
onRedirectCallback?(result: RedirectLoginResult): void;
}

const DEFAULT_REDIRECT_CALLBACK = () =>
window.history.replaceState({}, document.title, window.location.pathname);

export const Auth0Context = React.createContext<Auth0Context | null>(null);

export const useAuth0 = () => useContext(Auth0Context)!;

export const Auth0Provider = ({
children,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
...initOptions
}: Auth0ProviderOptions & Auth0ClientOptions
) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [user, setUser] = useState();
const [client, setClient] = useState<Auth0Client>();
const [loading, setLoading] = useState(true);
const [popupOpen, setPopupOpen] = useState(false);

useEffect(() => {
const initAuth0 = async () => {
const auth0 = await createAuth0Client(initOptions);
setClient(auth0);

if (window.location.search.includes("code=")) {
const { appState } = await auth0.handleRedirectCallback();
onRedirectCallback(appState);
}

const isAuthenticated = await auth0.isAuthenticated();

setIsAuthenticated(isAuthenticated);

if (isAuthenticated) {
const user = await auth0.getUser();
setUser(user);
}

setLoading(false);
};
initAuth0();
// eslint-disable-next-line
}, []);

const loginWithPopup = async (o: PopupLoginOptions) => {
setPopupOpen(true);
try {
await client!.loginWithPopup(o);
} catch (error) {
console.error(error);
} finally {
setPopupOpen(false);
}
const user = await client!.getUser();
setUser(user);
setIsAuthenticated(true);
};

const handleRedirectCallback = async () => {
setLoading(true);
const result = await client!.handleRedirectCallback();
const user = await client!.getUser();
setLoading(false);
setIsAuthenticated(true);
setUser(user);
return result;
};
return (
<Auth0Context.Provider
value=
>
{children}
</Auth0Context.Provider>
);
};

Usage:

src/App.tsx:

const config = {
domain: "your-domain.auth0.com",
clientId: "<client-id>",
redirect_uri: "http://localhost:3000",
audience: "<must-be-a-registered-API-at-auth0>",
};

// A function that routes the user to the right place
// after login
const onRedirectCallback = (appState: any) => {
window.history.replaceState(
{},
document.title,
appState && appState.targetUrl
? appState.targetUrl
: window.location.pathname
);
};

ReactDOM.render(
<React.StrictMode>
<Auth0Provider
domain={config.domain}
client_id={config.clientId}
audience={config.audience}
redirect_uri={config.redirect_uri}
onRedirectCallback={onRedirectCallback}
>

<App />
</Auth0Provider>
</React.StrictMode>,
document.getElementById("root")
);

And a possible header component:

src/components/Header.tsx:

import React from "react";
import { useAuth0 } from "../lib/auth0";
import { Link } from "react-router-dom";

const Header: React.FC = () => {
const {
loading,
isAuthenticated,
loginWithRedirect,
logout,
user,
} = useAuth0();

return (
<header className="bg-orange-500 p-4">
{loading ? (
<div>Loading...</div>
) : isAuthenticated ? (
<div>
{user && <img src={user.picture} alt="avatar" />}
<button className="auth-button" onClick={() => logout()}>
Log out
</button>
</div>
) : (
<div>
<button className="auth-button" onClick={() => loginWithRedirect({})}>
Login
</button>
</div>
)}
</header>
);
};

export default Header;