Skip to main content

Popup Window Embedding

The openAvePopup() function opens the Ave authentication flow in a separate popup window. This is ideal for desktop applications and follows the traditional OAuth popup pattern.

Basic Usage

import { openAvePopup } from "@ave-id/embed";

const popup = openAvePopup({
  clientId: "YOUR_CLIENT_ID",
  redirectUri: "https://yourapp.com/callback",
  scope: "openid profile email",
  onSuccess: ({ redirectUrl }) => {
    window.location.href = redirectUrl;
  },
  onError: (payload) => console.error("Popup error", payload),
  onClose: () => console.log("Popup closed"),
});

// Later, programmatically close the popup if needed
// popup?.close();

Configuration Options

Required Options

OptionTypeDescription
clientIdstringYour Ave client ID
redirectUristringOAuth redirect URI for your application

Optional Options

OptionTypeDefaultDescription
scopestring"openid profile email"OAuth scopes to request
issuerstring"https://aveid.net"Ave issuer URL
widthnumber-Popup window width in pixels
heightnumber-Popup window height in pixels
onSuccessfunction-Success callback
onErrorfunction-Error callback
onClosefunction-Close callback

Examples

Button Trigger

import { openAvePopup } from "@ave-id/embed";

const signInButton = document.getElementById("sign-in-btn");

signInButton.addEventListener("click", () => {
  openAvePopup({
    clientId: "YOUR_CLIENT_ID",
    redirectUri: "https://yourapp.com/callback",
    onSuccess: ({ redirectUrl }) => {
      window.location.href = redirectUrl;
    },
    onError: (error) => {
      alert("Sign in failed. Please try again.");
    },
    onClose: () => {
      console.log("User closed the popup");
    },
  });
});

Custom Dimensions

import { openAvePopup } from "@ave-id/embed";

const popup = openAvePopup({
  clientId: "YOUR_CLIENT_ID",
  redirectUri: "https://yourapp.com/callback",
  width: 500,
  height: 700,
  onSuccess: ({ redirectUrl }) => {
    window.location.href = redirectUrl;
  },
});

React Integration

import { openAvePopup } from "@ave-id/embed";

function SignInButton() {
  const handleSignIn = () => {
    const popup = openAvePopup({
      clientId: process.env.REACT_APP_AVE_CLIENT_ID,
      redirectUri: `${window.location.origin}/callback`,
      scope: "openid profile email",
      width: 480,
      height: 640,
      onSuccess: ({ redirectUrl }) => {
        window.location.href = redirectUrl;
      },
      onError: (error) => {
        console.error("Sign-in error:", error);
      },
      onClose: () => {
        console.log("Popup closed");
      },
    });
  };

  return (
    <button onClick={handleSignIn}>
      Sign in with Ave
    </button>
  );
}

Vue Integration

<template>
  <button @click="handleSignIn">Sign in with Ave</button>
</template>

<script>
import { openAvePopup } from "@ave-id/embed";

export default {
  methods: {
    handleSignIn() {
      openAvePopup({
        clientId: process.env.VUE_APP_AVE_CLIENT_ID,
        redirectUri: `${window.location.origin}/callback`,
        scope: "openid profile email",
        width: 480,
        height: 640,
        onSuccess: ({ redirectUrl }) => {
          window.location.href = redirectUrl;
        },
        onError: (error) => {
          console.error("Sign-in error:", error);
        },
        onClose: () => {
          console.log("Popup closed");
        },
      });
    },
  },
};
</script>

Programmatic Close

You can programmatically close the popup when needed:
import { openAvePopup } from "@ave-id/embed";

const popup = openAvePopup({
  clientId: "YOUR_CLIENT_ID",
  redirectUri: "https://yourapp.com/callback",
  onSuccess: ({ redirectUrl }) => {
    window.location.href = redirectUrl;
  },
});

// Close the popup after 30 seconds if still open
setTimeout(() => {
  popup?.close();
}, 30000);

With State Parameter

Handle multiple concurrent authentication flows:
import { openAvePopup } from "@ave-id/embed";

function initiateSignIn(userId) {
  const state = btoa(JSON.stringify({ userId, timestamp: Date.now() }));
  
  openAvePopup({
    clientId: "YOUR_CLIENT_ID",
    redirectUri: `https://yourapp.com/callback?state=${state}`,
    onSuccess: ({ redirectUrl }) => {
      // Parse state from redirectUrl to match the request
      window.location.href = redirectUrl;
    },
  });
}

Return Value

The openAvePopup() function returns an object with:
{
  close: () => void // Function to programmatically close the popup
}

Callbacks

onSuccess

Called when the user successfully completes authentication:
onSuccess: ({ redirectUrl }) => {
  // redirectUrl contains the OAuth callback URL with authorization code
  window.location.href = redirectUrl;
}

onError

Called when an error occurs during the authentication flow:
onError: (payload) => {
  console.error("Authentication error:", payload);
  // Show user-friendly error message
  alert("Sign in failed. Please try again.");
}

onClose

Called when the user closes the popup window:
onClose: () => {
  console.log("User closed the popup");
  // Track analytics, show fallback UI, etc.
}
The onClose callback fires when the user closes the popup, but not when authentication succeeds (use onSuccess for that).
The popup window is automatically centered on the user’s screen. If you specify custom dimensions, they will be used to calculate the centered position:
openAvePopup({
  clientId: "YOUR_CLIENT_ID",
  redirectUri: "https://yourapp.com/callback",
  width: 600,  // 600px wide
  height: 800, // 800px tall
  // Will be centered on screen
});
Important: Popup blockers may prevent the window from opening if:
  • The popup is not triggered by a direct user action (e.g., button click)
  • There’s a delay between user action and openAvePopup() call
  • The user’s browser has strict popup blocking settings
Always call openAvePopup() synchronously in response to a user event (click, touch, etc.) to avoid popup blockers.

Handling Blocked Popups

import { openAvePopup } from "@ave-id/embed";

function handleSignIn() {
  try {
    const popup = openAvePopup({
      clientId: "YOUR_CLIENT_ID",
      redirectUri: "https://yourapp.com/callback",
      onSuccess: ({ redirectUrl }) => {
        window.location.href = redirectUrl;
      },
    });

    if (!popup) {
      alert("Please allow popups for this site to sign in.");
    }
  } catch (error) {
    console.error("Failed to open popup:", error);
    // Fallback to inline iframe or sheet
  }
}

Security Considerations

Important security notes:
  • Always use HTTPS for your redirectUri in production
  • Validate the redirectUrl origin before redirecting to prevent open redirects
  • Store your clientId securely and avoid hardcoding sensitive values
  • The popup uses postMessage for communication - ensure your CSP allows this
  • Monitor for popup closing to detect if user abandons authentication

When to Use

Choose popup windows when:
  • Building desktop-focused applications
  • You want to follow traditional OAuth patterns
  • Users may need to reference information in the parent window during sign-in
  • You want to keep the parent window in view while authenticating
  • Your application uses multi-window workflows

When to Use Alternatives

  • Modal sheet - For mobile-first applications or native app-like experiences
  • Inline iframe - For dedicated sign-in pages with embedded authentication

Browser Compatibility

Popup windows require:
  • Browser that allows opening new windows
  • postMessage API support
  • JavaScript enabled
  • Popups not blocked by browser or extensions
All modern desktop browsers (Chrome, Firefox, Safari, Edge) are supported, but some browser extensions may interfere with popup behavior.

Multi-Screen Support

On systems with multiple monitors, the popup will open on the screen containing the parent window and center itself on that screen.

Next Steps

Inline iframe

Embed authentication directly in your page

Modal sheet

Use a mobile-friendly bottom sheet

Build docs developers (and LLMs) love