- This page is accesible to both logged in and logged out users. No middleware is defined for
+ This page is accessible to both logged in and logged out users. No middleware is defined for
this page.
- This page is accesible to both logged in and logged out users. No middleware is defined for
+ This page is accessible to both logged in and logged out users. No middleware is defined for
this page. Use the navigation above to navigate to other pages.
diff --git a/playground/pages/user.vue b/playground/pages/user.vue
index 33740e91..e81f05c9 100644
--- a/playground/pages/user.vue
+++ b/playground/pages/user.vue
@@ -3,9 +3,9 @@ definePageMeta({
middleware: ['hanko-logged-in'],
})
-const hanko = useHanko()
+const { $hanko } = useNuxtApp()
function logout() {
- hanko!.user.logout()
+ $hanko!.logout()
}
const result = ref()
diff --git a/src/runtime/composables/index.ts b/src/runtime/composables/index.ts
index 56b9a59e..10d7d041 100644
--- a/src/runtime/composables/index.ts
+++ b/src/runtime/composables/index.ts
@@ -1,5 +1,4 @@
-import { Hanko } from '@teamhanko/hanko-elements'
-import { useRuntimeConfig, useState, toValue } from '#imports'
+import { useNuxtApp } from '#app'
/**
* This composable returns a Hanko instance.
@@ -10,17 +9,5 @@ export function useHanko() {
if (import.meta.server) {
return null
}
- const hankoConfig = useRuntimeConfig().public.hanko
-
- const hanko = useState(
- 'single-hanko-instance',
- () =>
- new Hanko(hankoConfig.apiURL, {
- cookieName: hankoConfig.cookieName,
- localStorageKey: hankoConfig.storageKey,
- cookieSameSite: hankoConfig.cookieSameSite,
- cookieDomain: hankoConfig.cookieDomain,
- }),
- )
- return toValue(hanko)
+ return useNuxtApp().$hanko
}
diff --git a/src/runtime/plugins/components.client.ts b/src/runtime/plugins/components.client.ts
index 878abb62..8db1162c 100644
--- a/src/runtime/plugins/components.client.ts
+++ b/src/runtime/plugins/components.client.ts
@@ -1,6 +1,18 @@
-import { register } from '@teamhanko/hanko-elements'
+import { Hanko, register } from '@teamhanko/hanko-elements'
import { defineNuxtPlugin, useRuntimeConfig } from '#imports'
+declare module '#app' {
+ interface NuxtApp {
+ $hanko: InstanceType | null
+ }
+}
+
+declare module 'vue' {
+ interface ComponentCustomProperties {
+ $hanko: InstanceType | null
+ }
+}
+
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
nuxtApp.hook('app:mounted', async () => {
@@ -13,4 +25,12 @@ export default defineNuxtPlugin((nuxtApp) => {
...config.public.hanko.components,
})
})
+
+ const hankoConfig = useRuntimeConfig().public.hanko
+ nuxtApp.provide('hanko', new Hanko(hankoConfig.apiURL, {
+ cookieName: hankoConfig.cookieName,
+ localStorageKey: hankoConfig.storageKey,
+ cookieSameSite: hankoConfig.cookieSameSite,
+ cookieDomain: hankoConfig.cookieDomain,
+ }))
})
From df09451b6cb48af7e34fa97913f2b4d2a00b5444 Mon Sep 17 00:00:00 2001
From: harmzeinstra
Date: Mon, 5 Jan 2026 11:51:53 +0100
Subject: [PATCH 5/5] docs: update README to clarify `useHanko` and `$hanko`
usage and improve wording
---
README.md | 4 ++--
src/runtime/middleware/logged-in.ts | 4 ++--
src/runtime/middleware/logged-out.ts | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
index 2afc2dae..762facfc 100644
--- a/README.md
+++ b/README.md
@@ -83,11 +83,11 @@ You can also create your own middleware for full control.
### Auto-imports
-`useHanko` is exposed in the Vue part of your app to allow you direct access to the Hanko API. You can access the current user and much more. **Note**: It will return `null` on the server.
+`useHanko` and `$hanko` is exposed in the Vue part of your app to allow you direct access to the Hanko API. You can access the current user and much more. **Note**: It will return `null` on the server.
### Server utilities
-By default you can access a verified JWT context on `event.context.hanko`. (It will be undefined if the user is not logged in.) If you want to handle this yourself you can set `augmentContext: false`.
+By default, you can access a verified JWT context on `event.context.hanko`. (It will be undefined if the user is not logged in.) If you want to handle this yourself you can set `augmentContext: false`.
`verifyHankoEvent` is exposed in the Nitro part of your app to expose the underlying utility used to create `event.context.hanko` if you want to handle things manually.
diff --git a/src/runtime/middleware/logged-in.ts b/src/runtime/middleware/logged-in.ts
index d40e5eb0..96be4f27 100644
--- a/src/runtime/middleware/logged-in.ts
+++ b/src/runtime/middleware/logged-in.ts
@@ -1,5 +1,5 @@
import { withQuery } from 'ufo'
-import { defineNuxtRouteMiddleware, navigateTo, useRouter, useAppConfig, useHanko, useRequestEvent } from '#imports'
+import { defineNuxtRouteMiddleware, navigateTo, useRouter, useAppConfig, useNuxtApp, useRequestEvent } from '#imports'
export default defineNuxtRouteMiddleware(async (to) => {
const redirects = useAppConfig().hanko.redirects
@@ -13,7 +13,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
return
}
- const hanko = useHanko()!
+ const hanko = useNuxtApp().$hanko!
if (!(await hanko.getUser().catch(() => null)) && to.path !== redirects.login) {
return navigateTo(withQuery(redirects.login, { redirect: to.path }))
diff --git a/src/runtime/middleware/logged-out.ts b/src/runtime/middleware/logged-out.ts
index fac59c54..f4947e42 100644
--- a/src/runtime/middleware/logged-out.ts
+++ b/src/runtime/middleware/logged-out.ts
@@ -1,4 +1,4 @@
-import { defineNuxtRouteMiddleware, navigateTo, useRouter, useAppConfig, useHanko, useRequestEvent } from '#imports'
+import { defineNuxtRouteMiddleware, navigateTo, useRouter, useAppConfig, useNuxtApp, useRequestEvent } from '#imports'
export default defineNuxtRouteMiddleware(async (to) => {
const redirects = useAppConfig().hanko.redirects
@@ -12,7 +12,7 @@ export default defineNuxtRouteMiddleware(async (to) => {
return
}
- const hanko = useHanko()!
+ const hanko = useNuxtApp().$hanko!
if ((await hanko.getUser().catch(() => null)) && to.path !== redirects.home) {
return navigateTo(redirects.home)