
Security News
OWASP 2025 Top 10 Adds Software Supply Chain Failures, Ranked Top Community Concern
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.
vue3-smart-captcha
Advanced tools
Adds Yandex SmartCaptcha into your Vue3 application
You need to create captcha first and get both client and server keys. This package requires only client site key
NOTE: this package does NOT provides verification of response - you still need to implement it on server side
If you have vue3-smart-captcha package already installed there are few changes - all of them related to subscriptions as every subscription property was "relocated" to emitted events, e.g.
<template>
<!-- Before -->
<SmartCaptcha
...
:on-success="onSuccess"
:on-network-error="onNetworkError"
:on-challenge-visible="onChallengeVisible"
:on-challenge-hidden="onChallengeHidden"
:on-token-expired="onTokenExpired"
/>
<!-- After -->
<SmartCaptcha
...
@success="onSuccess"
@network-error="onNetworkError"
@challenge-visible="onChallengeVisible"
@challenge-hidden="onChallengeHidden"
@token-expired="onTokenExpired"
@javascript-error="onJavascriptError" // new event
/>
</template>
Everything else you can keep as it is or migrate to a new API
Run installation command using your preferred package manager, e.g
npm install vue3-smart-captcha
Script registers window.smartCaptcha global object you can access. This come from Yandex SmartCaptcha script itself
Since version 1.0.0 this package provides two ways to use it - as component or composable
Register component globally as plugin or import it per component base
import { SmartCaptchaPlugin } from 'vue3-smart-captcha'
const app = createApp()
app.use(SmartCaptchaPlugin)
OR
<template>
<SmartCaptcha />
</template>
<script setup>
import SmartCaptcha from 'vue3-smart-captcha'
// In order to keep backward compatibility plugin can be imported this way
// import { SmartCaptcha } from 'vue3-smart-captcha'
</script>
You need to pass client key in order to activate captcha. You can either pass :sitekey component property
<template>
<SmartCaptcha :sitekey="key" />
</template>
<script setup>
import SmartCaptcha from 'vue3-smart-captcha'
const key = '__client_key'
</script>
OR register environment variable called VITE_SMARTCAPTCHA_KEY
// .env
VITE_SMARTCAPTCHA_KEY="__client_key"
Now you can see captcha being rendered
Component appends captcha script into head section of application. If you already load smartcaptcha script via direct link you can disable this behavior by passing :load-widget="false"
<template>
<SmartCaptcha :load-widget="false" />
</template>
Package checks if
window.smartCaptchaobject was defined. However when using multiple captcha instances at once all of them will havewindow.smartCaptcha === undefinedon initial load. Therefore it is better either load script on your own and disable widget loading for every captcha or disable it for every captcha but first, e.g.
<template>
<SmartCaptcha />
<SmartCaptcha :load-widget="false" />
</template>
On a mount component will try to resolve global window.smartCaptcha object. If it was not defined component will "die". You may set timeout property in milliseconds to specify amount of time package will try to resolve this object
<template>
<SmartCaptcha :timeout="5000" />
</template>
Default value is 2000 (2 seconds)
Component accepts every property from YandexSmartCaptcha widget as is. Basically it gets every parameter of window.smartCaptcha object
Every property is optional (Well, technically sitekey is not)
| Property | Type | Default |
|---|---|---|
| sitekey | string | import.meta.env.VITE_SMARTCAPTCHA_KEY |
| callback | (token: Token) => void | undefined |
| hl | 'ru', 'en', 'be', 'kk', 'tt', 'uk', 'uz', 'tr' | window.navigator.language |
| test | boolean | false |
| webview | boolean | false |
| invisible | boolean | false |
| shieldPosition | 'top-left', 'center-left', 'bottom-left', 'top-right', 'center-right', 'bottom-right' | center-right |
| hideShield | boolean | false |
Let start with special initialized event - it fires when widget ID was resolved
<template>
<SmartCaptcha @initialized="onInit" />
</template>
<script setup>
const onInit = (widgetId) => {
console.log(widgetId)
}
</script>
Every subscription represented as emit. Only success and javascript-error accepts arguments
<template>
<SmartCaptcha
...
@success="onSuccess"
@network-error="onNetworkError"
@challenge-visible="onChallengeVisible"
@challenge-hidden="onChallengeHidden"
@token-expired="onTokenExpired"
@javascript-error="onJavascriptError"
/>
</template>
<script setup>
const onSuccess = (token) => {
console.log(token)
}
const onJavascriptError = (error) => {
console.log(error)
}
// ...
</script>
If you need you may create your own Captcha component using composable methods. This is more flexible and recommended way
<template>
<div ref="container" />
</template>
<script setup>
import { useSmartCaptcha } from 'vue3-smart-captcha'
const container = ref()
// Need to pass valid CSS selector, HTMLElement or Ref to it's element as first and only required argument
const captcha = useSmartCaptcha(container)
</script>
NOTE:
useSmartCaptcha('#captcha')oruseSmartCaptcha(document.querySelector('#captcha'))are both valid options but with some restrictions - Ref typecontaineris undefined on initial load (it will be resolved lately, on mounted hook). Therefore do not passcontainer.valueinto composable. Same valid for other selectors as they are undefined on initial load so use it withinonMountedhook
When using composable there are some ways to pass sitekey into captcha
Default one is to look into .env file for a key named VITE_SMARTCAPTCHA_KEY
Second - passing it as a string in second argument
const captcha = useSmartCaptcha(container, '__sitekey')
or pass it with other render props
const captcha = useSmartCaptcha(container, {
sitekey: '__sitekey',
})
To access token or widget id use related ref values
const { token, widgetId } = useSmartCaptcha(container)
console.log(token.value, widgetId.value)
Remember that
token.valueis undefined on initial load. It will be resolved only on successful captcha response after executing captcha component
Composable appends captcha script into head section of application when being called. If you already load smartcaptcha script via direct link you can disable this behavior by setting third argument as false
const captcha = useSmartCaptcha(container, {
// render props
}, false)
Package checks if
window.smartCaptchaobject was defined. However when using multiple captcha instances at once all of them will havewindow.smartCaptcha === undefinedon initial load.. Therefore it is better either load script on your own and disable widget loading for every captcha or disable it for every captcha but first, e.g.
const firstCaptcha = useSmartCaptcha(container, {
// render props
})
const secondCaptcha = useSmartCaptcha(container, {
// render props
}, false) // disable script appending as it will be appended by first captcha
When being called composable will try to resolve global window.smartCaptcha object. If it was not defined component will "die". You may set timeout as fourth argument in milliseconds to specify amount of time package will try to resolve this object
const captcha = useSmartCaptcha(container, {
// render props
}, true, 5000)
Default value is 2000 (2 seconds)
Same as for component properties (or window.smartCaptcha object)
const captcha = useSmartCaptcha(container, {
sitekey: '__sitekey',
callback: callback,
hl: 'ru',
test: false,
invisible: false,
webview: false,
hideShield: false,
shieldPosition: 'top-center',
})
In order to subscribe on captcha events use subscribeTo method passing event name and callback function to handle it
const { subscribeTo } = useSmartCaptcha(container)
const onSuccess = (token) => {
console.log(token)
}
const onNetworkError = () => {
console.log('Good bye World!')
}
subscribeTo('success', onSuccess)
subscribeTo('network-error', onNetworkError)
Composable provides methods to deal with captcha object methods such as execute, reset, destroy and getResponse
const {
execute,
destroy,
reset,
getResponse,
} = useSmartCaptcha(container)
<template>
<div ref="container" />
<button type="button" @click="getToken">
Get token
</button>
</template>
<script lang="ts" setup>
import { useSmartCaptcha, type Token } from 'vue3-smart-captcha'
const sitekey = import.meta.env.VITE_CUSTOM_CLIENT_KEY
const container = ref()
// Dummy form code
const form = useForm({
name: '',
token: undefined,
})
const { token, execute } = useSmartCaptcha(container, {
sitekey,
invisible: true,
})
const getToken = () => {
execute()
console.log(token.value) // `undefined` see bellow
}
// Token will not be resolved instantly. Therefore you need to watch its value being changed
watch(token, (newVal) => {
if (newVal !== undefined) {
form.token = newVal
}
})
</script>
<template>
<form @submit.prevent="submit">
<!-- Fields -->
<div ref="container" />
<button type="submit">
Submit
</button>
</form>
</template>
<script lang="ts" setup>
import { useSmartCaptcha, type Token } from 'vue3-smart-captcha'
const sitekey = import.meta.env.VITE_CUSTOM_CLIENT_KEY
const container = ref()
const { execute } = useSmartCaptcha(container, {
sitekey,
invisible: true,
callback: onCaptchaFired,
})
const submit = () => {
execute() // this will trigger onCaptchaFired function when token being received
}
const onCaptchaFired = async (tkn: Token) => {
// Dummy code
// Send request to backend to validate token
try {
const response = await validateToken(tkn)
} catch (error) {
}
if (! isSuccessful(response)) {
// Handle validation error
// ...
return
}
// Send form data to backend
// ...
}
</script>
Package provides utility class with every method but render in order if you need call captcha methods "manually" outside of current captcha (since both composable and captcha do not allows you to specify "custom" widget id)
import { SmartCaptchaUtils } from 'vue3-smart-captcha'
const widgetId = 0 // example
const utils = new SmartCaptchaUtils()
utils.execute(widgetId)
Open-source under MIT license
We are using Vitest
FAQs
Yandex Smart Captcha for Vue3 projects
The npm package vue3-smart-captcha receives a total of 210 weekly downloads. As such, vue3-smart-captcha popularity was classified as not popular.
We found that vue3-smart-captcha demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OWASP’s 2025 Top 10 introduces Software Supply Chain Failures as a new category, reflecting rising concern over dependency and build system risks.

Research
/Security News
Socket researchers discovered nine malicious NuGet packages that use time-delayed payloads to crash applications and corrupt industrial control systems.

Security News
Socket CTO Ahmad Nassri discusses why supply chain attacks now target developer machines and what AI means for the future of enterprise security.