
Create secure and user-friendly Vue.js one-time password input fields with automatic navigation, paste support, validation, and customizable options for modern authentication flows.
Available in Other JavaScript Frameworks
CoreUI Vue One-Time Password (OTP) Input Component is also available for Angular, Bootstrap, and React. Explore framework-specific implementations below:
Overview
The Vue One-Time Password (OTP) Component is a powerful, user-friendly solution for implementing secure authentication flows in your Vue.js applications. Whether you’re building two-factor authentication, email verification, or SMS confirmation systems, this OTP component provides an intuitive interface with advanced features like auto-navigation between fields, intelligent paste handling, and comprehensive keyboard support.
Key features of this Vue OTP component include:
- Auto-navigation between input fields
- Smart paste support with auto-fill
- Number and text input validation
- Linear and non-linear input modes
- Auto-submit functionality
- Keyboard navigation with RTL support
- Full accessibility compliance
- Bootstrap-based styling with size variants
Basic Example
A straightforward demonstration of how to implement a basic OTP input field with 4 digits.
<template>
<CForm>
<div class="mb-3">
<COneTimePassword label="Enter OTP Code" id="basicOTP" name="otp" v-model="value">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div v-if="value" class="text-body-secondary small">Current value: {{ value }}</div>
</CForm>
</template>
<script setup>
import { ref } from 'vue'
import { CForm } from '@coreui/vue'
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
const value = ref('')
</script> The basic implementation requires wrapping COneTimePasswordInput components within a COneTimePassword container. Each input field automatically handles single character input and navigation.
One-time password types
The OTP component supports both numeric and text input types through the type prop:
<template>
<div class="mb-3">
<COneTimePassword label="Numeric OTP (default)" type="number">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div class="mb-3">
<COneTimePassword label="Text OTP" type="text">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div>
<COneTimePassword label="Masked OTP (hidden characters)" masked>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> type="number"(default) - Restricts input to digits 0-9type="text"- Allows any single character
Placeholders
Customize placeholder text for better user guidance:
<template>
<div class="mb-3">
<COneTimePassword label="Single character placeholder" placeholder="0">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div class="mb-3">
<COneTimePassword label="Different placeholders per field" placeholder="123456">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div>
<COneTimePassword label="Letter placeholders" type="text" placeholder="ABCDEF">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> - Single character placeholders apply to all fields
- Multi-character strings apply character-by-character to each field
Pre-filled values
Use v-model for controlled components with pre-filled or dynamic values:
<template>
<CForm>
<div class="mb-3">
<COneTimePassword
label="OTP with pre-filled value (v-model)"
id="prefilledOTPModel"
name="otp1"
v-model="value"
>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div class="mb-3">
<COneTimePassword
label="OTP with pre-filled value (value prop)"
id="prefilledOTPValue"
name="otp2"
:value="valueWithProp"
@change="handleChange"
>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</CForm>
</template>
<script setup>
import { ref } from 'vue'
import { CForm } from '@coreui/vue'
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
const value = ref('123456')
const valueWithProp = ref('654321')
const handleChange = (newValue) => {
valueWithProp.value = newValue
}
</script> The component supports both v-model and value property.
Input modes
Control user input behavior with linear and non-linear modes.
<template>
<div className="mb-3">
<COneTimePassword label="Linear mode (sequential input)" :linear="true">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div>
<COneTimePassword label="Non-linear mode (free navigation)" :linear="false">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> linear="true"(default) - Users must fill fields in sequential orderlinear="false"- Users can fill any field in any order
Auto-submit
Automatically submit the form when all OTP fields are completed:
<template>
<form @submit.prevent="handleSubmit">
<COneTimePassword
label="Auto-submit OTP (fill all 6 digits)"
:auto-submit="true"
@complete="onComplete"
v-model="otpValue"
>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
<div class="mt-2">
<small v-if="submitted" class="text-success">Form submitted with code: {{ otpValue }}</small>
<small v-else class="text-muted">Fill all fields to auto-submit</small>
</div>
</form>
</template>
<script setup>
import { ref } from 'vue'
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
const otpValue = ref('')
const submitted = ref(false)
const onComplete = (value) => {
console.log('OTP completed:', value)
}
const handleSubmit = (event) => {
event.preventDefault()
submitted.value = true
setTimeout(() => {
submitted.value = false
}, 3000)
}
</script> The auto-submit prop triggers form submission when all fields are filled. The @complete event fires when the OTP is fully entered.
Custom layouts
Create different layouts and field counts to match your requirements:
<template>
<div class="mb-3">
<COneTimePassword label="6-digit OTP with separators">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<div class="px-2 text-body-tertiary fw-bold">-</div>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div class="mb-3">
<COneTimePassword label="9-digit OTP with separators">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<div class="px-2 text-body-tertiary fw-bold">•</div>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<div class="px-2 text-body-tertiary fw-bold">•</div>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div>
<COneTimePassword label="4-digit PIN" masked>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> You can create any number of input fields and even separate them into multiple OTP components for complex layouts.
Sizing
Use the size prop to adjust the height and padding of the OTP inputs:
<template>
<div class="mb-3">
<COneTimePassword label="Large OTP input" size="lg">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div class="mb-3">
<COneTimePassword label="Default OTP input">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
<div>
<COneTimePassword label="Small OTP input" size="sm">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</div>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> size="sm"– Small inputssize="lg"– Large inputs
Disabled state
Disable all OTP input fields using the disabled prop:
<template>
<COneTimePassword label="Disabled OTP" value="123456">
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</template>
<script setup>
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
</script> Read-only state
Make the OTP component read-only while preserving visual feedback:
<template>
<COneTimePassword v-model="value" readonly>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>
</template>
<script setup>
import { ref } from 'vue'
import { COneTimePassword, COneTimePasswordInput } from '@coreui/vue-pro'
const value = ref('1234')
</script> Form Integration
The OTP component integrates seamlessly with CoreUI’s form system, supporting validation states and form controls:
<COneTimePassword
label="Verification Code"
text="Enter the 4-digit code sent to your email"
:invalid="hasError"
feedback-invalid="Please enter a valid verification code"
required
>
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
<COneTimePasswordInput />
</COneTimePassword>