Skip to main content

Vue.js integration: getting started

This guide covers integrating Weavr Web SDK UI components with Vue.js 3 using the Composition API. You'll learn the correct patterns for script loading, lifecycle management, and the four distinct component integration patterns.

Overview and quick start

Prerequisites

  • Vue.js 3.x with Composition API
  • A Weavr account with API credentials (UI key)
  • Basic understanding of Vue.js reactivity and lifecycle hooks

5-minute minimal example

This example demonstrates a working password input component:

1. Add the SDK to your index.html:

<!doctype html>
<html>
<head>
<script src="https://sandbox.weavr.io/app/secure/static/client.1.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>

2. Create a Vue component:

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";

const containerRef = ref<HTMLElement | null>(null);
let form: any = null;
let input: any = null;

onMounted(() => {
if (!window.OpcUxSecureClient) {
console.error("Weavr SDK not loaded - check index.html script tag");
return;
}

window.OpcUxSecureClient.init("your_ui_key_here");
form = window.OpcUxSecureClient.form();
input = form.input("password", "password", {
placeholder: "Enter password",
});
input.mount(containerRef.value);
});

onUnmounted(() => {
// Defensive cleanup to prevent errors if SDK component wasn't initialized
try {
if (input && typeof input.unmount === "function") {
input.unmount();
}
} catch (e) {
console.error("Error unmounting component:", e);
}
});

const handleSubmit = () => {
form.tokenize((tokens: Record<string, string>) => {
console.log("Password token:", tokens.password);
// Send tokens.password to your server
});
};
</script>

<template>
<form @submit.prevent="handleSubmit">
<div ref="containerRef"></div>
<button type="submit">Submit</button>
</form>
</template>

Script loading

Critical requirement

The Weavr SDK must be loaded via a <script> tag in index.html. Do not import it through Vite or any bundler.

See Framework Integration Overview for details on why this is required.

Vite configuration

Add the SDK to index.html in your project root:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Your App</title>

<!-- Weavr SDK - MUST be loaded here, not via import -->
<script src="https://sandbox.weavr.io/app/secure/static/client.1.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

Bundler configuration

For Vue command-line tool projects, add the SDK to public/index.html:

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<title><%= htmlWebpackPlugin.options.title %></title>

<!-- Weavr SDK -->
<script src="https://sandbox.weavr.io/app/secure/static/client.1.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>

Environment-based SDK URLs

For production deployments, use different SDK URLs per environment:

<script>
// Determine SDK URL based on environment
const sdkUrl = import.meta.env.PROD
? 'https://secure.weavr.io/app/secure/static/client.1.js'
: 'https://sandbox.weavr.io/app/secure/static/client.1.js';

const script = document.createElement('script');
script.src = sdkUrl;
document.head.appendChild(script);
</script>

Or use separate HTML files for each environment.

SDK initialization

Create a Vue plugin to initialize the SDK once when your app starts:

// src/plugins/weavr.ts
import type { App } from "vue";

declare global {
interface Window {
OpcUxSecureClient: {
init: (
uiKey: string,
options?: { fonts?: Array<{ cssSrc: string }> }
) => void;
form: () => WeavrForm;
span: (type: string, token: string, options?: object) => WeavrSpan;
associate: (
token: string,
onSuccess: () => void,
onError?: (e: Error) => void
) => void;
kyb: () => { init: (...args: any[]) => void };
kyc: () => { init: (...args: any[]) => void };
consumer_kyc: () => { init: (options: object) => void };
};
}
}

interface WeavrForm {
input: (name: string, type: string, options?: object) => WeavrInput;
tokenize: (callback: (tokens: Record<string, string>) => void) => void;
}

interface WeavrInput {
mount: (element: HTMLElement | null) => void;
unmount: () => void;
on: (event: string, callback: () => void) => void;
}

interface WeavrSpan {
mount: (element: HTMLElement | null) => void;
unmount: () => void;
}

export const weavrPlugin = {
install(
app: App,
options: { uiKey: string; fonts?: Array<{ cssSrc: string }> }
) {
// Check SDK is loaded
if (!window.OpcUxSecureClient) {
console.error("Weavr SDK not loaded. Add script tag to index.html.");
return;
}

// Initialize SDK
window.OpcUxSecureClient.init(options.uiKey, {
fonts: options.fonts,
});

// Make available globally
app.config.globalProperties.$weavr = window.OpcUxSecureClient;
},
};

Register the plugin in your main entry:

// src/main.ts
import { createApp } from "vue";
import App from "./App.vue";
import { weavrPlugin } from "./plugins/weavr";

const app = createApp(App);

app.use(weavrPlugin, {
uiKey: import.meta.env.VITE_WEAVR_UI_KEY,
fonts: [
{ cssSrc: "https://fonts.googleapis.com/css?family=Inter:400,500,600" },
],
});

app.mount("#app");

Per-component initialization

For simpler setups, initialize in each component:

<script setup lang="ts">
import { onMounted } from "vue";

onMounted(() => {
if (window.OpcUxSecureClient) {
window.OpcUxSecureClient.init("your_ui_key");
}
});
</script>
caution

Calling init() multiple times is safe, but wasteful. Prefer the plugin pattern for larger applications.

Next steps