Input OTP
Input OTP components allow users to enter a one-time password by typing one character per input field in a series.
Examples
This section demonstrates various ways to use the Input OTP component, including different layouts and customization options.
Basic 6-digit OTP with divider
This example shows a standard 6-digit OTP input split into two groups of three, separated by a dash. Each input accepts a single digit, and users can paste the entire code for convenience.
<div class="otp-wrapper">
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
<span class="dash mx-2">-</span>
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>
<div class="otp-wrapper"> <div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> </div>
<span class="dash mx-2">-</span> <div class="input-group
otp-group"> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> <input
type="text" maxlength="1" class="form-control otp-input
text-center" /> </div> </div>
6-digit OTP without divider
This example displays a continuous 6-digit OTP input without any visual divider. All six input fields are grouped together, suitable for codes that do not require separation.
<div class="otp-wrapper">
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>
<div class="otp-wrapper"> <div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> <input
type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> </div>
</div>
6-digit OTP with two dividers
This example demonstrates a 6-digit OTP input split into three groups of two, each group separated by a dash. This layout is useful for codes formatted as XX-XX-XX.
<div class="otp-wrapper">
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
<span class="dash mx-2">-</span>
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
<span class="dash mx-2">-</span>
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>
<div class="otp-wrapper"> <div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> </div> <span
class="dash mx-2">-</span> <div class="input-group
otp-group"> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> </div>
<span class="dash mx-2">-</span> <div class="input-group
otp-group"> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> </div>
</div>
OTP input with helper text
This example combines the OTP input with a helper text below, guiding users to enter their one-time password. This is helpful for accessibility and clarity.
Enter your one-time password.
<div class="d-flex flex-column align-items-center">
<div class="otp-wrapper mb-2">
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
<input type="text" maxlength="1" class="form-control otp-input text-center" />
</div>
</div>
<p class="text-body mb-0">Enter your one-time password.</p>
</div>
<div class="d-flex flex-column align-items-center"> <div
class="otp-wrapper mb-2"> <div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> <input
type="text" maxlength="1" class="form-control otp-input
text-center" /> <input type="text" maxlength="1"
class="form-control otp-input text-center" /> <input type="text"
maxlength="1" class="form-control otp-input text-center" /> </div>
</div> <p class="text-body mb-0">Enter your one-time password.</p>
</div>
Complete OTP form with label and submit button
This example presents a full OTP input form, including a label, helper text, and a submit button. It demonstrates how to integrate the OTP input into a typical authentication flow.
<form class="otp-validate-form" novalidate>
<label for="otp-group" class="form-label">One-Time Password</label>
<div class="otp-wrapper mb-2">
<div class="input-group otp-group">
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
<input type="text" maxlength="1" class="form-control otp-input text-center" required />
</div>
</div>
<p class="text-muted mb-1">Please enter the one-time password sent to your phone.</p>
<div class="otp-error-message text-danger mb-3 d-none">
Your one-time password must be 6 characters.
</div>
<button class="btn btn-primary" type="submit">Submit</button>
</form>
<form class="otp-validate-form" novalidate> <label for="otp-group"
class="form-label">One-Time Password</label> <div class="otp-wrapper
mb-2"> <div class="input-group otp-group"> <input
type="text" maxlength="1" class="form-control otp-input
text-center" required /> <input type="text" maxlength="1"
class="form-control otp-input text-center" required /> <input
type="text" maxlength="1" class="form-control otp-input
text-center" required /> <input type="text" maxlength="1"
class="form-control otp-input text-center" required /> <input
type="text" maxlength="1" class="form-control otp-input
text-center" required /> <input type="text" maxlength="1"
class="form-control otp-input text-center" required /> </div> </div>
<p class="text-muted mb-1">Please enter the one-time password sent to your
phone.</p> <div class="otp-error-message text-danger mb-3 d-none"> Your
one-time password must be 6 characters. </div> <button class="btn
btn-primary" type="submit">Submit</button> </form>
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('.otp-validate-form');
const inputs = form.querySelectorAll('.otp-input');
const label = form.querySelector('.form-label');
const errorMessage = form.querySelector('.otp-error-message');
form.addEventListener('submit', function (e) {
e.preventDefault(); // prevent submission
// Convert NodeList to Array for easier handling
const inputArray = Array.from(inputs);
// Count filled inputs
const filledInputs = inputArray.filter(input => input.value.trim() !== '');
if (filledInputs.length < 6) {
// Show error message
errorMessage.classList.remove('d-none');
// Make label red
label.classList.add('text-danger');
// Focus the first empty input
const firstEmpty = inputArray.find(input => input.value.trim() === '');
if (firstEmpty) firstEmpty.focus();
} else {
// All inputs filled — proceed
errorMessage.classList.add('d-none');
label.classList.remove('text-danger');
form.submit();
}
});
});
document.addEventListener('DOMContentLoaded', function () { const form =
document.querySelector('.otp-validate-form'); const inputs =
form.querySelectorAll('.otp-input'); const label =
form.querySelector('.form-label'); const errorMessage =
form.querySelector('.otp-error-message'); form.addEventListener('submit',
function (e) { e.preventDefault(); // prevent submission // Convert NodeList to Array for easier
handling const inputArray = Array.from(inputs); // Count filled inputs const filledInputs =
inputArray.filter(input => input.value.trim() !== ''); if (filledInputs.length <
6) { // Show error message errorMessage.classList.remove('d-none'); // Make label red
label.classList.add('text-danger'); // Focus the first empty input const firstEmpty =
inputArray.find(input => input.value.trim() === ''); if (firstEmpty)
firstEmpty.focus(); } else { // All inputs filled — proceed
errorMessage.classList.add('d-none'); label.classList.remove('text-danger');
form.submit(); } }); });