> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shieldlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Vue

> Identify a visitor, send a Request ID with your application action and verify the result on your server.

Identify a visitor, send a Request ID with your application action and verify the result on your server. This guide uses the supported ShieldLabs package API, not a standalone generated client.

## Before you start

An existing Vue 3.3+ application and a Public Key. For Nuxt, keep identification in the browser after hydration.

Register and verify the website domain in your [analytics dashboard](https://app.shieldlabs.ai/). Use credentials from the same domain and environment as the browser check. For a fresh account, start with [Quick Start](/quickstart).

## Get your credentials

Copy the Public Key for your domain from **Integration > API keys**. A public frontend environment variable may contain this key, but never a Private API Key or webhook signing secret.

## Install the SDK

```bash theme={null}
npm install @shieldlabs-ai/vue @shieldlabs-ai/js
```

Use `yarn add` or `pnpm add` with the same package names if your project uses that package manager. Framework packages remain the application's responsibility.

## Add the integration

Install the plugin once:

```ts theme={null}
// src/main.ts
import { createShieldLabs } from '@shieldlabs-ai/vue';
import { createApp } from 'vue';
import App from './App.vue';

createApp(App)
  .use(createShieldLabs({ publicKey: import.meta.env.VITE_SHIELDLABS_PUBLIC_KEY }))
  .mount('#app');
```

Identify when the user submits a protected form, and send the `requestId` with the request:

```vue theme={null}
<script setup lang="ts">
import { useIdentify } from '@shieldlabs-ai/vue';
import { ref } from 'vue';

const email = ref('');
const { identify, isLoading } = useIdentify();

async function onSubmit() {
  const result = await identify(); // null when there is no identification
  await fetch('/api/signup', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email: email.value, requestId: result?.requestId ?? null }),
  });
}
</script>

<template>
  <form @submit.prevent="onSubmit">
    <input v-model="email" type="email" required />
    <button :disabled="isLoading">Sign up</button>
  </form>
</template>
```

On your server, read the verdict for `requestId` with a ShieldLabs server SDK, for example
`identifications.get(requestId)` in [`@shieldlabs-ai/node`](https://github.com/ShieldLabs-ai/shieldlabs-node),
which waits until the identification has been scored. The History row appears about 1-3 seconds
after `identify()` resolves and can be refined for up to about 10 seconds as follow-up checks
finish. To keep that wait off the submit, start the identification when the user begins the action
(see [Start on the first interaction with the form ](https://github.com/ShieldLabs-ai/shieldlabs-vue/blob/67ac6b0ee9254c788fa72198c442b9071ac7b76e/README.md#start-on-the-first-interaction-with-the-form)).
Server SDKs:
[Node.js](https://github.com/ShieldLabs-ai/shieldlabs-node),
[Python](https://github.com/ShieldLabs-ai/shieldlabs-python),
[Go](https://github.com/ShieldLabs-ai/shieldlabs-go),
[PHP](https://github.com/ShieldLabs-ai/shieldlabs-php),
[Java](https://github.com/ShieldLabs-ai/shieldlabs-java) and
[.NET](https://github.com/ShieldLabs-ai/shieldlabs-dotnet).

> **Keep the page alive after `identify()` resolves.** The agent posts the identification right
> after it hands over the request ID. Send your request with `fetch()` as above, and start a full
> page navigation (`location.href = ...`, a classic form post) only after it has been sent.
> Client-side navigation with Vue Router keeps the page alive. Details:
> [`@shieldlabs-ai/js` Quick start](https://github.com/ShieldLabs-ai/shieldlabs-js#quick-start).

A complete app is in [`examples/vite`](https://github.com/ShieldLabs-ai/shieldlabs-vue/tree/67ac6b0ee9254c788fa72198c442b9071ac7b76e/examples/vite).

## Test the complete flow

1. Run the application on the registered HTTPS domain with its Public Key.
2. Trigger the protected form once and check that a Request ID is sent to your own backend.
3. Retrieve that same ID using a server SDK or locate it in the analytics dashboard.
4. Test a missing ID and an agent load failure: your backend must treat the action as unverified.

The `/api/signup` routes shown in examples belong to your application; they are not ShieldLabs API endpoints. Connect one of the [server quick starts](/api/sdks#server-packages) before testing the full action. A successful browser call does not prove scoring is complete.

## Troubleshooting

* No History row: confirm the registered domain, credential/environment match and that the browser remained open while collectors posted.
* Missing or pending verdict: scoring is asynchronous. The server helper waits within a bounded budget; handle a missing result and API errors explicitly.
* Authentication error: use the Private API Key for History, not a Public Key, Management Secret Key or MCP OAuth token.
* Invalid webhook signature: verify the original raw bytes with the endpoint's full signing secret, before trusting parsed JSON.

## Next steps

* [Runnable example](https://github.com/ShieldLabs-ai/shieldlabs-vue/tree/67ac6b0ee9254c788fa72198c442b9071ac7b76e/examples/vite)
* [SDK reference and changelog](https://github.com/ShieldLabs-ai/shieldlabs-vue)
* [Identification flow](/api/identification-flow)
* [Server API](/api/server-api)
* [Webhook setup](/setup/webhooks)
* [Content Security Policy](/setup/csp)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.