Install @teamhanko/hanko-elements

Install hanko-elements to access the pre-built hanko-auth and hanko-profile components.
npm install @teamhanko/hanko-elements

Add the Hanko API URL

Retrieve the API URL from the Hanko console and place it in your .env file.
.env
 VITE_HANKO_API_URL=https://f4****-4802-49ad-8e0b-3d3****ab32.hanko.io
If you are self-hosting you need to provide the URL of your running Hanko backend.

Add <hanko-auth> component

Add the <hanko-auth> web component to create a login interface. Import the register function from @teamhanko/hanko-elements and call it with your Hanko API URL to register the component with the browser’s CustomElementRegistry.
components/HankoAuth.tsx
import { onMount, createSignal, onCleanup } from "solid-js";
import { register, Hanko } from "@teamhanko/hanko-elements";
import { useNavigate } from "@solidjs/router";

const hankoApi = import.meta.env.VITE_HANKO_API_URL;

export default function HankoAuth() {
  const navigate = useNavigate();
  const hanko = new Hanko(hankoApi);

  const redirectAfterLogin = () => {
    navigate("/dashboard");
  };

  onMount(() => {
    hanko.onSessionCreated(() => {
      redirectAfterLogin();
    });

    register(hankoApi).catch((error) => {
      // handle error
    });
  });

  onCleanup(() => {
    // cleanup logic if needed
  });

  return <hanko-auth />;
}

type GlobalJsx = JSX.IntrinsicElements;

declare module "solid-js" {
  namespace JSX {
    interface IntrinsicElements {
      "hanko-auth": GlobalJsx["hanko-auth"];
    }
  }
}
By now, your sign-up and sign-in features should be working. You should see an interface similar to this 👇
sign up

Add <hanko-profile> component

The <hanko-profile> component provides an interface, where users can manage their email addresses and passkeys.
components/HankoProfile.tsx
import { onMount } from "solid-js";
import { register } from "@teamhanko/hanko-elements";

const hankoApi = import.meta.env.VITE_HANKO_API_URL;

export default function HankoProfile() {
    onMount(() => {
        register(hankoApi).catch((error) => {
            // handle error
        });
    });

    return <hanko-profile />;
}

type GlobalJsx = JSX.IntrinsicElements;

declare module "solid-js" {
    namespace JSX {
        interface IntrinsicElements {
            "hanko-profile": GlobalJsx["hanko-profile"];
        }
    }
}
It should look like this 👇
profile page

Implement logout functionality

Create a logout button component using @teamhanko/hanko-elements to manage user logouts:
components/LogoutButton.tsx
import { useNavigate } from "@solidjs/router";
import { Hanko } from "@teamhanko/hanko-elements";

const hankoApi = import.meta.env.VITE_HANKO_API_URL;

function LogoutBtn() {
    const navigate = useNavigate();
    let hanko = new Hanko(hankoApi ?? "");

    const logout = async () => {
        try {
            await hanko.user.logout();
            navigate("/auth");
        } catch (error) {
            console.error("Error during logout:", error);
        }
    };

    return <button onClick={logout}>Logout</button>;
}

export default LogoutBtn;

Customize component styles

You can customize the appearance of hanko-auth and hanko-profile components using CSS variables and parts. Refer to our customization guide.

Authenticate backend requests

To authenticate requests on your backend with Hanko, refer to our backend guide.

Try it yourself

Solid.js example

It uses Express.js for the backend, full source code available on our GitHub.