[{"data":1,"prerenderedAt":116},["ShallowReactive",2],{"doc:\u002Fdocs\u002Fsdks\u002Fvue":3},{"page":4,"toc":106,"updated":115},{"path":5,"title":6,"seoTitle":7,"description":8,"blocks":9},"\u002Fdocs\u002Fsdks\u002Fvue","Vue","Vue SDK: Plugin and Composables","A plugin and composables for Vue 3.3 and newer. One shared identification per app, readonly reactive state, and safe under server rendering.",[10,13,18,23,27,30,43,46,52,54,57,63,66,79,81,83,86,91,93,96,101,104],{"type":11,"text":12},"p","`@fingerly\u002Fvue` installs the [JavaScript SDK](\u002Fdocs\u002Fsdks\u002Fjavascript) as a Vue plugin. Composables read one shared identification as readonly refs.",{"type":14,"level":15,"text":16,"id":17},"heading",2,"Requirements","requirements",{"type":19,"items":20},"list",[21,22],"Vue 3.3 or newer.","A [public key](\u002Fdocs\u002Fapi-keys) with your site in its allowed origins.",{"type":24,"tone":25,"text":26},"callout","note","Using Nuxt? Install the [Nuxt module](\u002Fdocs\u002Fsdks\u002Fnuxt) instead. It registers this plugin and auto-imports the composables.",{"type":14,"level":15,"text":28,"id":29},"Install","install",{"type":31,"samples":32},"code",[33,37,40],{"label":34,"lang":35,"code":36},"npm","bash","npm install @fingerly\u002Fvue",{"label":38,"lang":35,"code":39},"pnpm","pnpm add @fingerly\u002Fvue",{"label":41,"lang":35,"code":42},"yarn","yarn add @fingerly\u002Fvue",{"type":14,"level":15,"text":44,"id":45},"Install the plugin","install-the-plugin",{"type":31,"samples":47},[48],{"label":49,"lang":50,"code":51},"main.ts","ts","import { createApp } from 'vue'\nimport { createFingerly } from '@fingerly\u002Fvue'\nimport App from '.\u002FApp.vue'\n\ncreateApp(App)\n  .use(createFingerly({ apiKey: 'fly_pk_us_production_…' }))\n  .mount('#app')",{"type":11,"text":53},"Installing collects nothing. `createFingerly` accepts `apiKey`, `endpoint`, `endpoints`, `fallbackToDefaultEndpoint`, `submit` and `consent`. Change consent at runtime with `useFingerly().setConsent()`.",{"type":14,"level":15,"text":55,"id":56},"Identify on an action","identify-on-an-action",{"type":31,"samples":58},[59],{"label":60,"lang":61,"code":62},"Checkout.vue","vue","\u003Cscript setup lang=\"ts\">\nimport { useIdentify } from '@fingerly\u002Fvue'\n\nconst props = defineProps\u003C{ orderId: string }>()\nconst { identify, isLoading, error } = useIdentify({ tag: () => 'checkout:' + props.orderId })\n\nasync function onSubmit() {\n  const { requestId } = await identify()\n  await submitOrder({ orderId: props.orderId, requestId })\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"onSubmit\">\n    \u003Cbutton :disabled=\"isLoading\">{{ isLoading ? 'Checking…' : 'Pay now' }}\u003C\u002Fbutton>\n    \u003Cp v-if=\"error\">{{ error.message }}\u003C\u002Fp>\n  \u003C\u002Fform>\n\u003C\u002Ftemplate>",{"type":14,"level":15,"text":64,"id":65},"useIdentify","useidentify",{"type":67,"title":68,"fields":69},"fields","Options",[70,75],{"name":71,"type":72,"text":73,"default":74},"immediate","boolean","Identify in `onMounted`.","false",{"name":76,"type":77,"text":78},"tag","MaybeRefOrGetter\u003Cstring | undefined>","The tag to send, read at the moment of submission.",{"type":11,"text":80},"Returns the same state as the [React hook](\u002Fdocs\u002Fsdks\u002Freact#useidentify), with every field a readonly ref and `isReady` and `isSuspicious` as computed refs, plus `identify({ tag?, force? })` and `refresh({ tag? })`.",{"type":11,"text":82},"A call while an identification is in flight gets that identification, and a finished result is reused until you call `refresh()`. A failure is not cached.",{"type":14,"level":15,"text":84,"id":85},"useVerdict","useverdict",{"type":31,"samples":87},[88],{"label":89,"lang":61,"code":90},"AutomationNotice.vue","\u003Cscript setup lang=\"ts\">\nimport { useVerdict } from '@fingerly\u002Fvue'\n\nconst { matched, confidence } = useVerdict('automation', { min: 'high' })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Caside v-if=\"matched\">Automated access suspected ({{ confidence }})\u003C\u002Faside>\n\u003C\u002Ftemplate>",{"type":11,"text":92},"Both arguments accept refs and getters. Verdict names are `incognito`, `shields`, `tor`, `emulator`, `automation` and `farm`.",{"type":14,"level":15,"text":94,"id":95},"Options API","options-api",{"type":31,"samples":97},[98],{"label":99,"lang":61,"code":100},"Legacy.vue","\u003Cscript lang=\"ts\">\nexport default {\n  async mounted() {\n    const { requestId } = await this.$fingerly.identify()\n  },\n}\n\u003C\u002Fscript>",{"type":14,"level":15,"text":102,"id":103},"Server rendering","server-rendering",{"type":11,"text":105},"`immediate` runs in `onMounted`, which never runs on the server. Calling `identify()` during server rendering rejects with `FingerlyServerError`. In a custom SSR setup, create the plugin per app instance rather than at module scope.",[107,108,109,110,111,112,113,114],{"id":17,"text":16,"level":15},{"id":29,"text":28,"level":15},{"id":45,"text":44,"level":15},{"id":56,"text":55,"level":15},{"id":65,"text":64,"level":15},{"id":85,"text":84,"level":15},{"id":95,"text":94,"level":15},{"id":103,"text":102,"level":15},"2026-09-17T16:57:29.000Z",1789667797793]