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
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
Global plugin pattern (recommended)
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>
Calling init() multiple times is safe, but wasteful. Prefer the plugin pattern for larger applications.
Next steps
- Component patterns—Learn the four SDK integration patterns and composables
- Reusable components—Production-ready wrapper components
- Troubleshooting—Error handling, common pitfalls, and solutions