Vue Integration
Add the EmbedAuth iframe to a Vue 3 app with a Composition-API component that manages the postMessage listener and auto-resizes the frame.
In Vue 3 the embed is a single-file component. The message listener is registered in onMounted and removed in onUnmounted, mirroring the same lifecycle discipline every EmbedAuth integration needs.
A composable
Keep the listener logic in a composable so it is reusable and testable:
// useEmbedAuth.ts
import { onMounted, onUnmounted } from 'vue';
// The embed URL on embedauth.com redirects to the widget's copy on the CDN,
// so its messages come from the CDN's origin.
const EMBED_ORIGIN = 'https://cdn.embedauth.com';
type AuthSuccess = {
token: string;
refreshToken: string;
user: { id: string; email: string; name?: string };
};
export function useEmbedAuth(onSuccess: (result: AuthSuccess) => void) {
function handleMessage(event: MessageEvent) {
if (event.origin !== EMBED_ORIGIN) return;
if (event.data?.type === 'authframe:auth-success') {
onSuccess(event.data.data);
}
}
onMounted(() => window.addEventListener('message', handleMessage));
onUnmounted(() => window.removeEventListener('message', handleMessage));
}
The component
<script setup lang="ts">
import { ref } from 'vue';
import { useEmbedAuth } from './useEmbedAuth';
const props = defineProps<{ mode?: 'signin' | 'signup' | 'forgot-password' }>();
const CLIENT_ID = 'YOUR_CLIENT_ID';
const height = ref(600);
useEmbedAuth(async ({ token }) => {
await fetch('/api/session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token }),
});
window.location.assign('/dashboard');
});
const src = `https://embedauth.com/embed/${CLIENT_ID}?mode=${props.mode ?? 'signin'}`;
</script>
<template>
<iframe
title="Sign in"
:src="src"
:height="height"
width="420"
style="border: none; width: 100%; max-width: 420px"
/>
</template>
Auto-resizing
To grow the frame with its content, also handle authframe:resize and bind the height:
function handleMessage(event: MessageEvent) {
if (event.origin !== EMBED_ORIGIN) return;
if (event.data?.type === 'authframe:resize') {
height.value = event.data.data.height;
}
}
Bind height to the iframe's :height attribute and the form will never show an inner scrollbar as it switches between sign-in, sign-up, and error states.
Nuxt
In Nuxt, keep the embed inside a <ClientOnly> wrapper (or a .client.vue component) so it never runs during SSR — window does not exist on the server. Verify the token in a server route (server/api/session.post.ts) exactly as shown in the Next.js guide; the verification code is identical.
Next steps
- Verify the token on your backend: Node.js, Python, or Go.
- Configure your Content Security Policy before deploying.
- Full event reference: PostMessage Events.