Vue 3 Integration
import { Aside } from ‘@astrojs/starlight/components’;
Because <spartan-login> is a native web component, it is not integrated with Vue’s reactivity system. You need to use Vue’s lifecycle hooks to wire up event listeners and handle attribute changes.
Minimal integration
Section titled “Minimal integration”<template> <spartan-login :key="widgetKey" ref="loginWidget" :domain="authDomain" :sector="sectorId" start-mode="password" :locale="locale" redirect=""> </spartan-login></template>
<script setup lang="ts">import '@masonitestudios/spartanauth-widgets';import { ref, watch, onBeforeUnmount } from 'vue';import { useRouter } from 'vue-router';
const router = useRouter();const authDomain = import.meta.env.VITE_SPARTANAUTH_DOMAIN || 'https://api.spartanauth.com';const sectorId = import.meta.env.VITE_SPARTANAUTH_SECTOR;const locale = ref(navigator.language.slice(0, 2) || 'en');const widgetKey = ref(0);const loginWidget = ref<HTMLElement | null>(null);
function onLogin() { router.push('/');}
// Attach/detach the listener whenever the widget mounts or remounts.// Using watch on the ref handles both initial mount and remounts caused by key changes.watch(loginWidget, (newEl, oldEl) => { oldEl?.removeEventListener('spartan-login', onLogin); newEl?.addEventListener('spartan-login', onLogin);});
// Belt-and-suspenders cleanup on route leaveonBeforeUnmount(() => { loginWidget.value?.removeEventListener('spartan-login', onLogin);});
// Force a remount when locale changes so the widget re-reads the attributewatch(locale, () => { widgetKey.value++; });</script>Key rules for Vue
Section titled “Key rules for Vue”1. Attach event listeners after mount
Section titled “1. Attach event listeners after mount”The web component element does not exist in the DOM before the component mounts. Use watch(ref, ...) — not onMounted alone — because the ref watch also fires on remounts (see below).
2. Remove event listeners on unmount
Section titled “2. Remove event listeners on unmount”Always pair your addEventListener with a removeEventListener in onBeforeUnmount or in the watch cleanup. Otherwise event listeners accumulate and leak.
3. Use :key to force remount on attribute changes
Section titled “3. Use :key to force remount on attribute changes”Vue reuses DOM nodes when possible. When the locale attribute (or any attribute that the widget reads on initialization) changes, the widget needs to be destroyed and recreated to pick up the new value.
Incrementing :key forces Vue to replace the element entirely:
// Force remount when locale changeswatch(locale, () => { widgetKey.value++; });Without this, setting a new locale attribute will not take effect because the widget reads its i18n configuration once at creation time.
4. Tell Vue to treat spartan-* as custom elements
Section titled “4. Tell Vue to treat spartan-* as custom elements”If you see Vue warnings about unknown elements, configure vite.config.ts:
import vue from '@vitejs/plugin-vue';
export default { plugins: [ vue({ template: { compilerOptions: { isCustomElement: (tag) => tag.startsWith('spartan-'), }, }, }), ],};Common mistakes
Section titled “Common mistakes”| Mistake | Fix |
|---|---|
Attaching the listener in onMounted instead of watch(ref, ...) | watch handles remounts; onMounted only runs once |
Forgetting onBeforeUnmount cleanup | Always pair addEventListener with removeEventListener |
Not incrementing :key when locale changes | watch(locale, () => { widgetKey.value++ }) |
Using v-model or reactive bindings on widget attributes | Web components don’t observe attribute changes reactively — use :key remount instead |