@zitadel/sdk-vue

Vue 3 components for the Zitadel auth UI (client-side SPA).
3,175 28
Install
npm install @zitadel/sdk-vue
Latest Version:0.1.0
Vue:3
License:MIT
Last Updated:Oct 23, 2026
Links: GitHub  ·  npm
Maintainer: bastionstack

@zitadel/sdk-vue

Vue 3 components for the Zitadel auth UI, for client-side SPAs (Vite, etc.).

Installation

pnpm add @zitadel/sdk-vue@latest

Requirements

Peer dependencies: vue >=3.2.

TypeScript ≥ 5.0, the floor shared by every SDK; see the compatibility notes.

Usage

<script setup lang="ts">
import { ZitadelLogin, configureZitadel } from '@zitadel/sdk-vue';

const project = configureZitadel({
  projectId: import.meta.env.VITE_ZITADEL_PROJECT_ID,
  proxyPath: '/__nextgen',
});
</script>

<template>
  <ZitadelLogin :project="project" purpose="login" postSignInUrl="/" />
</template>

<ZitadelLogout :project="project" postSignOutUrl="/login" /> works the same way.

ZitadelLogin also takes resumeFlowId, an existing flow to resume instead of starting a new one; unset, null or "" falls back to the flow query parameter.

The signed-in session card is <ZitadelSession :project="project" /> (exported as ZitadelSession).

Widget props and events

ZitadelLogin, ZitadelLogout and ZitadelSession take the props below, spelled the same in every SPA SDK. An unset prop keeps the widget's own default.

Prop Type Default Widgets Description
project ZitadelProject unset Login, Logout, Session The handle from configureZitadel(...). Wins over projectId and proxyPath.
projectId string unset Login, Logout, Session Project id, read when no project handle is passed.
proxyPath string "/__nextgen" Login, Logout, Session Same-origin path the widget calls.
purpose CreateFlowBodyPurpose "login" Login Flow purpose.
flowName string unset Login Runs the flow definition with this name; unset runs the project's default flow for the purpose.
postSignInUrl string unset Login Where to navigate after a completed sign-in. When the page's next query parameter names a path on the same origin, as the server SDKs' middleware sets it for a signed-out visit to a protected route, the widget returns there instead.
forcePostSignInUrl boolean false Login Navigates to postSignInUrl even when the page's next query parameter names a path, for a page that uses next for something of its own.
postSignOutUrl string unset Logout, Session Where to navigate after sign-out.
resumeFlowId string or null unset Login An existing flow's id to resume instead of starting a new flow; unset, null or "" falls back to the flow query parameter, and an id that no longer resolves starts a new flow.
variant "widget" or "page" "widget" Login, Session widget is content-sized and paints no page chrome; page claims the viewport, paints the surface background and loads the brand font, and on Login focuses the first field.
theme "light", "dark" or "auto" unset Login, Logout, Session Colour mode. Unset follows the tenant's branding theme on Login, then the variant default (dark for page, auto for widget); Logout defaults to auto. auto follows prefers-color-scheme.
suppressHeader boolean false Login, Session Visually hides the widget's own heading block while keeping it in the accessibility tree, for pages that already carry the heading.
suppressPasswordToggle boolean false Login Hides the show/hide button on password fields.
heading string "Signed in as" Session Heading text override.
logoutLabel string "Sign out" Session Logout action label override.
locales Record<string, Partial<Record<string, string>>> unset Login Copy overrides merged over the builtin dictionaries, keyed by primary language subtag, for example { en: { "identifier.title": "Welcome back" } }.
lang string browser language Login BCP-47 language override.

Each widget event reaches the callback in the last column, which receives the event's detail payload.

Widget event Fires when Detail Widgets Callback
zitadel-flow-step Login shows a step, the first one included. { step } Login @flowStep
zitadel-flow-input The visitor edits a field. { name, value } Login @flowInput
zitadel-flow-complete The flow reaches a terminal step. { behavior, redirect_uri?, handoff_token?, handoff_token_expires_at? } Login @flowComplete
zitadel-flow-redirect The widget hands the browser to an identity provider; nobody is signed in yet. { redirect_url, step } Login @flowRedirect
zitadel-flow-error The flow reports an error. { message } Login @flowError
zitadel-signout The user signs out. { display, identifier } Logout, Session @signout
<ZitadelLogin :project="project" theme="light" @flowComplete="track" />

The zitadel-flow-complete, zitadel-flow-redirect and zitadel-signout details carry a waitUntil(promise); call it from your handler to make the widget wait for your async work before it navigates.

Standard HTML attributes

ZitadelLogin, ZitadelLogout and ZitadelSession also take the standard HTML attributes (class, style, id, title, slot, hidden, role, tabindex, data-* and aria-*) and pass them to the widget element, so you can position, style and label the widget without an extra wrapper element. Nothing else reaches the element: any other prop is ignored.

<ZitadelLogin :project="project" class="login" data-testid="login" aria-label="Sign in" />

Vue's strictTemplates rejects data-* attributes on a component whose props type does not declare them, and this one cannot declare them without breaking Vue's own overloads.

Server rendering

If your app renders on the server, mount the widget on the client only, after hydration (the ZitadelLogin wrapper sets projectId and proxyPath as element properties, so adding them to the wrapper does not put them in server markup), or use a raw <zitadel-login> element with project-id and proxy-path as attributes, because a widget that starts before its configuration arrives shows an error instead of the flow.

Proxying to the backend (deployment)

The widgets call ${proxyPath}/… same-origin (default /__nextgen). In production the same-origin path must come from your hosting platform — until the CLI can scaffold those configs, production SPA deployment is not yet supported; see ADR 036 and zitadel/nextgen#560. The CLI dev proxy covers local development.

For local development you can also skip the proxy and point proxyPath straight at the backend (cross-origin), e.g. proxyPath: "http://localhost:8080" (the zitadel start local runtime default port).

Related Packages

@zitadel/sdk-nuxt

Nuxt proxy middleware and helpers for the pre-release Zitadel preview.

3,260 28
@zitadel/vue-auth

A comprehensive authentication integration for Vue applications with TypeScript...

2,151 27
@zitadel/nuxt-auth

A comprehensive authentication integration for Nuxt 4 applications with TypeScri...

1,627 1
@zitadel/vue

Wraps vue-oidc-client to provide a simple interface for ZITADEL

32,961

Version History

Version Released Vue License
0.1.0 >=3.2 MIT
0.0.0 >=3 MIT
Pre-releases (24)
Version Released Vue License
1.0.0-alpha.28 >=3.2 MIT
1.0.0-alpha.25 >=3 MIT
1.0.0-alpha.24 >=3 MIT
1.0.0-alpha.23 >=3 MIT
1.0.0-alpha.22 >=3 MIT