How to Set Placeholder Text for Individual OTP Input Fields in Vue 3

Pass an array of strings to the placeholder prop, where each array element corresponds to one OTP input field.

The vue3-otp-input library provides a composable OTP (One-Time Password) input solution for Vue 3 applications. When you need to set placeholder text for individual OTP input fields in Vue 3, the component exposes a placeholder prop that accepts an array of strings, mapping each index to a specific input box for granular visual control.

Understanding the Placeholder Architecture

The placeholder functionality spans two core components in the ejirocodes/vue3-otp-input repository:

Wrapper Component (vue3-otp-input.vue)

Located at src/components/vue3-otp-input.vue, this component defines the placeholder prop as a string[] with a default value of an empty array. During rendering, it iterates through the number of inputs specified by numInputs and passes the corresponding placeholder element using the expression :placeholder="placeholder?.[i]" (lines 28-42).

Single Input Component (single-otp-input.vue)

Located at src/components/single-otp-input.vue, this component receives the placeholder prop as a string type. It binds this value directly to the native HTML input attribute via :placeholder="placeholder" (lines 23-38), rendering the visual hint in the specific input field.

How to Set Placeholder Text for Individual OTP Input Fields

Basic Syntax with Static Array

To set individual placeholders, bind an array to the placeholder prop where each index matches the corresponding input position:

<script setup lang="ts">
import { ref } from 'vue'
import VOtpInput from 'vue3-otp-input'

const otp = ref('')
</script>

<template>
  <v-otp-input
    v-model:value="otp"
    :num-inputs="4"
    :placeholder="['✱', '✱', '✱', '✱']"
    @on-complete="console.log('OTP entered:', $event)"
  />
</template>

This renders four input fields, each displaying the "✱" character as placeholder text.

Custom Placeholder Patterns

You can assign distinct characters to specific positions for visual guidance:

<v-otp-input
  v-model:value="otp"
  :num-inputs="6"
  :placeholder="['A', 'B', 'C', 'D', 'E', 'F']"
/>

Each box displays its corresponding letter, useful for indicating entry order or segment labels.

Dynamic Placeholder Values

For reactive placeholder changes based on application state, bind a reactive array:

<script setup lang="ts">
import { ref, watch } from 'vue'

const placeholders = ref(['·', '·', '·', '·'])
const isSecureMode = ref(false)

watch(isSecureMode, (val) => {
  placeholders.value = val ? ['*', '*', '*', '*'] : ['·', '·', '·', '·']
})
</script>

<template>
  <v-otp-input
    v-model:value="otp"
    :num-inputs="4"
    :placeholder="placeholders"
  />
</template>

Implementation Details and Source Code Analysis

The placeholder propagation follows a specific data flow within the ejirocodes/vue3-otp-input codebase:

  1. Prop Definition: In src/components/vue3-otp-input.vue, the placeholder prop is typed as Array as PropType<string[]> with a default factory returning an empty array. This ensures type safety while allowing optional configuration.

  2. Index Mapping: The wrapper uses Vue's template syntax to access array elements by index: :placeholder="placeholder?.[i]". The optional chaining operator prevents errors when the array is shorter than numInputs, passing undefined to unmatched inputs.

  3. Native Binding: In src/components/single-otp-input.vue, the child component receives the placeholder as a String prop and binds it to the native input element: <input ... :placeholder="placeholder" />. This direct binding ensures the browser renders the placeholder text according to HTML5 specifications.

Common Use Cases for OTP Placeholders

Security Indicators

Use asterisks or bullet characters (['*', '*', '*', '*']) to indicate password-style entry without revealing length constraints.

Position Markers

Sequential letters or numbers (['1', '2', '3', '4']) guide users through multi-step verification codes.

Visual Separators

Different characters for specific segments (['·', '·', '-', '-']) can indicate groupings within the OTP (e.g., prefix vs. suffix).

Summary

  • The vue3-otp-input component accepts a placeholder prop as an array of strings (string[]) to set individual hints for each input field.
  • The wrapper component (src/components/vue3-otp-input.vue) maps array indices to child inputs using :placeholder="placeholder?.[i]".
  • The single input component (src/components/single-otp-input.vue) binds the received string to the native HTML input element.
  • Array length does not need to match numInputs; unmatched inputs render without placeholders when using optional chaining.
  • Placeholders can be static arrays, distinct character patterns, or reactive values bound to component state.

Frequently Asked Questions

Can I use the same placeholder for all OTP input fields?

Yes, though the prop requires an array format. To apply identical placeholders across all fields, create an array with repeated values: :placeholder="Array(4).fill('•')". Each input will display the same character. If you pass an array with fewer elements than numInputs, the remaining inputs will simply have no placeholder text due to the optional chaining implementation in src/components/vue3-otp-input.vue.

What happens if the placeholder array length doesn't match numInputs?

The component handles mismatched lengths gracefully through optional chaining (placeholder?.[i]). If your array contains fewer strings than the number of inputs specified by numInputs, the unmatched input fields receive undefined as their placeholder value, resulting in no placeholder text being displayed. If the array contains more elements than needed, the excess values are simply ignored during the mapping iteration.

Can I change placeholders dynamically based on user input?

Yes, you can bind the placeholder prop to a reactive reference. Define your placeholder array using Vue's ref() or reactive() API, then update the array values in response to user actions, validation states, or other application logic. The component will reactively update the displayed placeholders because the placeholder prop is reactive and the child components re-render when the bound values change.

Are there any accessibility considerations for OTP placeholders?

While placeholders provide visual guidance, they should not replace proper labels for accessibility. Screen readers may not consistently announce placeholder text, and placeholder characters (like asterisks or bullets) might confuse users with cognitive disabilities. Ensure your OTP implementation includes proper <label> elements or aria-label attributes describing the input purpose, using placeholders only as supplementary visual hints. The vue3-otp-input component renders native HTML inputs, so standard ARIA attributes can be applied via the component's prop binding or wrapper elements.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →