{"id":15922,"library":"vue-turnstile","title":"Vue Cloudflare Turnstile Component","description":"vue-turnstile is a Vue 3 component library that simplifies the integration of Cloudflare Turnstile, a CAPTCHA alternative, into Vue applications. It provides a declarative `VueTurnstile` component that handles the underlying Turnstile API interactions, script loading, and token management. The current stable version is 1.0.11, suggesting a mature library actively maintained for Vue 3 environments. While a specific release cadence isn't published, the `1.0.x` versioning implies ongoing maintenance and minor updates as needed. Key differentiators include its tight integration with Vue's reactivity system (e.g., `v-model` for token binding), support for various Turnstile customization options like theme, size, and language, and explicit methods for resetting and re-rendering the widget. It abstracts away the complexities of directly interacting with the Cloudflare Turnstile JavaScript API, making it easier for developers to implement bot protection.","status":"active","version":"1.0.11","language":"javascript","source_language":"en","source_url":"https://github.com/ruigomeseu/vue-turnstile","tags":["javascript","cloudflare","turnstile","vue","captcha","vue3","library","typescript"],"install":[{"cmd":"npm install vue-turnstile","lang":"bash","label":"npm"},{"cmd":"yarn add vue-turnstile","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-turnstile","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This is a Vue 3 component library and requires Vue 3 as a peer dependency.","package":"vue","optional":false}],"imports":[{"note":"The library primarily uses ES Module syntax, common for Vue 3 applications. CommonJS `require` is not supported for importing the component directly.","wrong":"const VueTurnstile = require('vue-turnstile');","symbol":"VueTurnstile","correct":"import VueTurnstile from 'vue-turnstile';"},{"note":"While the main export is a component instance, you can use `import type` for type-only imports in TypeScript when referencing the component's type definition.","symbol":"VueTurnstile component type (for TypeScript)","correct":"import type { VueTurnstile } from 'vue-turnstile';"}],"quickstart":{"code":"<script lang=\"ts\">\nimport VueTurnstile from 'vue-turnstile';\n\nexport default {\n  components: { VueTurnstile },\n\n  data() {\n    return {\n      token: '',\n    };\n  },\n  methods: {\n    // Example of how to access component methods via ref\n    resetTurnstile() {\n      (this.$refs.turnstileWidget as typeof VueTurnstile & { reset: () => void } | undefined)?.reset();\n    }\n  }\n};\n</script>\n\n<template>\n  <div>\n    <p>Please complete the CAPTCHA:</p>\n    <vue-turnstile\n      site-key=\"1x00000000000000000000AA\" <!-- Replace with your actual site key -->\n      v-model=\"token\"\n      theme=\"auto\"\n      size=\"normal\"\n      language=\"en\"\n      ref=\"turnstileWidget\"\n    />\n    <div v-if=\"token\">\n      <p>Turnstile Token: <code>{{ token }}</code></p>\n      <button @click=\"resetTurnstile\">Reset Turnstile</button>\n    </div>\n    <div v-else>\n      <p>Awaiting Turnstile token...</p>\n    </div>\n  </div>\n</template>\n\n<style>\n/* Basic styling for demonstration */\ndiv {\n  font-family: Arial, sans-serif;\n  margin-bottom: 10px;\n}\nbutton {\n  padding: 8px 15px;\n  background-color: #007bff;\n  color: white;\n  border: none;\n  border-radius: 4px;\n  cursor: pointer;\n}\nbutton:hover {\n  background-color: #0056b3;\n}\n</style>","lang":"typescript","description":"This quickstart demonstrates how to integrate the `VueTurnstile` component into a Vue 3 application, bind the generated token using `v-model`, and display the token. It also shows how to access component methods like `reset()` via a template ref."},"warnings":[{"fix":"Implement server-side validation for the Turnstile token immediately after form submission. Consider using the `reset-interval` prop to automatically refresh tokens if user interaction is expected to be lengthy.","message":"Cloudflare Turnstile tokens are valid only for a limited time (typically 5 minutes). Ensure your backend validates the token promptly upon submission. If the user delays, the token might expire. The `reset-interval` prop can automatically refresh the token client-side.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Replace the placeholder `site-key` with your actual production site key from Cloudflare Turnstile dashboard.","message":"The `site-key` prop is mandatory. Using the placeholder `1x00000000000000000000AA` (which is a test key) is fine for development, but for production, you must use a valid site key obtained from your Cloudflare account.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Update your CSP to include `script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com; frame-src 'self' https://challenges.cloudflare.com;` (adjusting for your specific policy).","message":"Cloudflare Turnstile relies on loading scripts and resources from `challenges.cloudflare.com`. If your application uses a Content Security Policy (CSP), you must configure it to allow these resources, otherwise the widget will fail to render.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"<vue-turnstile site-key=\"YOUR_SITE_KEY\" v-model=\"token\" />","cause":"The `site-key` prop was not provided to the `VueTurnstile` component.","error":"[vue-turnstile] site-key is required"},{"fix":"Modify your Content Security Policy (CSP) to permit scripts and frames from `https://challenges.cloudflare.com`. For example, add `script-src https://challenges.cloudflare.com; frame-src https://challenges.cloudflare.com;` to your CSP headers or meta tag.","cause":"Your browser's Content Security Policy (CSP) is blocking the necessary Cloudflare Turnstile scripts from loading.","error":"Refused to load the script 'https://challenges.cloudflare.com/turnstile/v0/api.js' because it violates the following Content Security Policy directive..."},{"fix":"Ensure you have a `ref` attribute on the `VueTurnstile` component (e.g., `<vue-turnstile ref=\"turnstileWidget\" ... />`) and access its methods using `this.$refs.turnstileWidget.reset()` after the component is mounted. Use optional chaining for robustness: `(this.$refs.turnstileWidget as any)?.reset()`.","cause":"Attempting to call a component method (like `reset()`) on a `VueTurnstile` instance that hasn't been properly assigned a ref or is not yet mounted.","error":"Error in beforeUpdate: 'TypeError: Cannot read properties of undefined (reading 'reset')'"}],"ecosystem":"npm"}