Pro Component — This component requires an Aura UI Pro license.
Overview
The OTP Input component renders a series of individual input fields for entering one-time passwords or verification codes. It automatically moves focus to the next field as digits are entered, supports pasting full codes, and handles backspace navigation. Integrates with Livewire via wire:model for server-side verification.
Basic Usage
-
<x-aura::otp-input
name="otp_code"
wire:model="otpCode"
/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
length |
int |
6 |
Number of input fields (digits in the code). |
type |
string |
'number' |
Input type: number for numeric-only, text for alphanumeric codes. |
autofocus |
bool |
true |
Automatically focus the first input field on mount. |
Examples
Standard 6-Digit OTP
-
<div class="text-center">
<h2 class="text-lg font-semibold mb-2">Verify Your Identity</h2>
<p class="text-sm text-gray-500 mb-6">
Enter the 6-digit code sent to your email.
</p>
<x-aura::otp-input
name="otp_code"
:length="6"
type="number"
:autofocus="true"
wire:model="otpCode"
/>
@error('otpCode')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
4-Digit PIN
<x-aura::otp-input
name="pin"
:length="4"
type="number"
wire:model="pin"
/>
Alphanumeric Code
<x-aura::otp-input
name="invite_code"
:length="8"
type="text"
wire:model="inviteCode"
/>
Full 2FA Verification Flow with Livewire
<!-- Blade view -->
<div class="mx-auto max-w-sm text-center">
<div class="mb-6">
<x-aura::icon name="shield-check" class="mx-auto h-12 w-12 text-indigo-500" />
<h2 class="mt-3 text-xl font-bold">Two-Factor Authentication</h2>
<p class="mt-1 text-sm text-gray-500">
Enter the code from your authenticator app.
</p>
</div>
<form wire:submit="verify">
<x-aura::otp-input
name="totp_code"
:length="6"
type="number"
:autofocus="true"
wire:model="totpCode"
/>
@error('totpCode')
<p class="mt-3 text-sm text-red-600">{{ $message }}</p>
@enderror
<x-aura::button type="submit" class="mt-6 w-full" wire:loading.attr="disabled">
<span wire:loading.remove>Verify</span>
<span wire:loading>Verifying...</span>
</x-aura::button>
</form>
<p class="mt-4 text-sm text-gray-500">
Lost your device?
<a href="/recovery" class="text-indigo-600 hover:underline">Use a recovery code</a>
</p>
</div>
// Livewire component
class TwoFactorChallenge extends Component
{
public string $totpCode = '';
protected function rules(): array
{
return [
'totpCode' => 'required|string|size:6',
];
}
public function verify(): void
{
$this->validate();
$user = auth()->user();
if (! $user->validateTwoFactorCode($this->totpCode)) {
$this->addError('totpCode', 'The code is invalid or has expired.');
$this->reset('totpCode');
return;
}
session()->put('two_factor_confirmed', true);
$this->redirect(intended('/dashboard'));
}
}
Without Autofocus
-
<x-aura::otp-input
name="confirmation_code"
:length="6"
:autofocus="false"
wire:model="confirmationCode"
/>
Slots
| Slot | Description |
|---|---|
| default | Not used. The input fields are generated automatically based on the length prop. |
Accessibility
- Each individual input uses
role="textbox"witharia-label="Digit N of M". - The component group is wrapped with
role="group"and anaria-labeldescribing the OTP input. inputmode="numeric"is set for number-type inputs to trigger numeric keyboards on mobile.autocomplete="one-time-code"enables browser autofill from SMS on supported devices.- Backspace moves focus to the previous field and clears its value.
- Arrow Left/Right navigates between fields without clearing values.
- Paste distributes characters across all fields from a clipboard value.
- Focus is visually indicated with a ring/border highlight on the active field.