Skip to content

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" with aria-label="Digit N of M".
  • The component group is wrapped with role="group" and an aria-label describing 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.