Hanko Fullstack Integration Guide
About Hanko: Hanko is a privacy-first authentication and user management provider that offers customizable, open-source authentication solutions focused on the passkey era. It provides both hosted cloud services and self-hosted options, supporting flexible login methods including passkeys, passwords, OAuth providers, and email passcodes.What This Guide Covers: This comprehensive guide demonstrates integrating Hanko authentication into your fullstack application using the @teamhanko/hanko-elements
package. You’ll learn to set up authentication components, implement session management, secure routes with middleware, and handle user data across both client and server-side contexts.Key Technologies: Modern fullstack framework with TypeScript, server-side rendering capabilities, Hanko Elements, Hanko Cloud Console, session management, and middleware protectionPrerequisites: Node.js, basic knowledge of your chosen fullstack framework, Hanko Cloud account (free at cloud.hanko.io)Integration Tasks You’ll Complete:
- Install and configure Hanko Elements package for your framework
- Set up HankoAuth component with session event handling and navigation
- Create HankoProfile component for user credential management
- Implement logout functionality with proper session cleanup and redirects
- Secure routes using framework-specific middleware with Hanko session validation
- Retrieve user data both client-side and server-side using appropriate APIs
- Handle authentication redirects, error states, and edge cases
- Configure server-side rendering integration and hydration
- Customize component appearance and behavior for your application
Create a SvelteKit application
Create a new SvelteKit application using the official SvelteKit starter.
Run the following command to create a new SvelteKit application:
npx sv create project-name
Install @teamhanko/hanko-elements
The Hanko Elements package provides pre-built authentication components (hanko-auth
, hanko-profile
) that work with Svelte’s reactive system.
Install the package:
cd project-name
npm install @teamhanko/hanko-elements
Setup your Hanko project
Create a Hanko project in the cloud console to get your API URL.
Go to the Hanko console and create a project for this application.
Add your Hanko API URL
Add your Hanko API URL to your environment file. The PUBLIC_
prefix makes it accessible in both server and client-side code in SvelteKit.
Retrieve your API URL from the Hanko console and add it to your .env
file:
PUBLIC_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.
Create Hanko components
Create a components
folder with two files: HankoAuth.svelte
and HankoProfile.svelte
.
Hanko Auth
Now let’s setup the HankoAuth.tsx
file to create a functioning login page.
Here we subscribe to the onSessionCreated
event, this triggers when a user successfully logs in. You can use these event to perform any desired action.(e.g. redirect to your dashboard).
For more information please refer to the Auth Component Page.
Svelte authentication component that uses reactive stores, handles session events, and implements navigation to dashboard after successful login
components/HankoAuth.svelte
<script>
import { onMount } from "svelte";
import { goto } from "$app/navigation";
import { register } from "@teamhanko/hanko-elements";
import { env } from "$env/dynamic/public";
const hankoApi = env.PUBLIC_HANKO_API_URL;
const redirectAfterLogin = () => {
//Successfully logged in
goto("/dashboard");
};
onMount(async () => {
register(hankoApi).catch((error) => {
// handle error
});
});
</script>
<hanko-auth on:onSessionCreated={redirectAfterLogin} />
Now simply import the component you just created into any page.
Main page route that imports and renders the HankoAuth component for user login and registration
<script>
import HankoAuth from "../components/HankoAuth.svelte";
</script>
<div>
<HankoAuth/>
</div>
By now, your sign-up and sign-in features should be working. You should see an interface similar to this 👇
Hanko profile
After setting up the HankoAuth let’s set up the HankoProfile.jsx
file to create an interface where users can
manage their Email Addresses
and credentials.
For more information please refer to the Profile Component Page.
Svelte profile component that allows users to manage their email addresses, passkeys, and authentication credentials using Hanko’s built-in interface
components/HankoProfile.svelte
<script>
import { register } from "@teamhanko/hanko-elements";
import { onMount } from "svelte";
import { env } from "$env/dynamic/public";
const hankoApi = env.PUBLIC_HANKO_API_URL;
onMount(async () => {
register(hankoApi).catch((error) => {
// handle error
});
});
</script>
<hanko-profile />
Now simply import the component you just created into any page.
Protected dashboard page route that imports and displays the HankoProfile component for user account management
routes/dashboard/+page.svelte
<script>
import HankoProfile from "../../components/HankoProfile.svelte";
</script>
<div>
<HankoProfile/>
</div>
It should look something like this 👇
Implement logout functionality
You can use @teamhanko/hanko-elements
to easily logout users. Here we will make a logout button.
Create LogoutButton.tsx
and insert the code below.
Svelte logout button component that terminates the user session and navigates back to the home page
components/LogoutButton.svelte
<script>
import { Hanko } from "@teamhanko/hanko-elements";
import { goto } from "$app/navigation";
import { env } from "$env/dynamic/public";
const hankoApi = env.PUBLIC_HANKO_API_URL;
const hanko = new Hanko(hankoApi);
const logout = () => {
hanko.logout().catch((error) => {
//Handle Error
});
goto("/")//Path to redirect the user to
};
</script>
<button on:click={logout}>Logout</button>
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.
Securing routes
To verify the session token in your SvelteKit application, we’re using the session/validate API request. By checking for a valid session token this middleware will ensure secure access to specific routes, like /dashboard
and /protected
.
The middleware hook extracts and verifies the session token, and redirect unauthorized users back to the home or login page.
For more info on middlewares / hooks in SvelteKit and where to put the hooks.server.ts
file,
please refer to SvelteKit Hooks.
What happens here is that during each request the handle function will be called.
It then verifies the session token and redirects the user back if he is on a private route and the session token is not valid.
Hooks like these tends to not always work after creating it, if this is the case try restarting your SvelteKit app.
SvelteKit server hooks that implement route protection by validating session tokens and redirecting unauthorized users away from protected routes
import { type RequestEvent, redirect, type Handle } from "@sveltejs/kit";
import { env } from "$env/dynamic/public";
const hankoApiUrl = env.PUBLIC_HANKO_API_URL;
export const handle: Handle = async ({ event, resolve }) => {
const verified = await authenticatedUser(event);
if (event.url.pathname.startsWith("/dashboard") && !verified) {
throw redirect(303, "/");
}
if (event.url.pathname.startsWith("/profile") && !verified) {
throw redirect(303, "/");
}
const response = await resolve(event);
return response;
};
const authenticatedUser = async (event: RequestEvent) => {
const { cookies } = event;
const cookieToken = cookies.get("hanko");
const validationOptions = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: `{"session_token":"${cookieToken}"}`
}
try {
const response = await fetch(hankoApiUrl + '/sessions/validate', validationOptions);
if (!response.ok) throw new Error('Session validation failed');
const verifiedResponse = await response.json();
console.log(verifiedResponse)
return verifiedResponse.is_valid;
} catch (error) {
console.log(error)
return false;
}
};
Getting user data
Let’s use the Hanko SDK to get user data.
Let’s update the dashboard
page to display some of the information from the user.
Enhanced dashboard page that retrieves and displays user data (email and ID) using the Hanko SDK alongside the profile management component
routes/dashboard/+page.svelte
<script>
import { onMount } from 'svelte';
import { env } from "$env/dynamic/public";
import { Hanko } from '@teamhanko/hanko-elements';
const hankoApi = env.PUBLIC_HANKO_API_URL;
import HankoProfile from "../../components/HankoProfile.svelte";
let email = '';
let id = '';
async function fetchUserData() {
const hanko = new Hanko(hankoApi);
const _email = (await hanko.getUser()).emails?.[0]?.address;
const _id = (await hanko.getUser()).user_id;
return { email: _email, id: _id };
}
onMount(async () => {
const data = await fetchUserData();
email = data.email;
id = data.id;
});
</script>
<div>
<HankoProfile/>
<h2>{email}</h2>
<h2>{id}</h2>
</div>
Try out yourself
SvelteKit example
Full source code available on our GitHub