# How to Add Custom Separators Between OTP Input Fields in Vue 3

> Learn to add custom separators between OTP input fields in Vue 3 using the separator prop in vue3-otp-input. Easily inject HTML markup like characters, emojis, or styled elements.

- Repository: [Ejiro Asiuwhu/vue3-otp-input](https://github.com/ejirocodes/vue3-otp-input)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Use the `separator` prop in `vue3-otp-input` to inject any HTML markup—characters, emojis, or styled elements—between OTP input fields.**

The `vue3-otp-input` library provides a flexible way to customize the visual spacing between OTP digits. By leveraging the `separator` prop, you can insert custom characters, SVG icons, or styled HTML elements between each input field without modifying the component's internal logic.

## Understanding the Separator Prop Architecture

The separator functionality operates through a parent-child component relationship defined in the source code.

In [`src/components/vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/vue3-otp-input.vue), the main component accepts the `separator` prop and forwards it to every `SingleOtpInput` instance during iteration over the `numInputs` array【1†L30-L35】.

The child component in [`src/components/single-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/single-otp-input.vue) handles the actual rendering logic. It displays the separator only when two conditions are met: the current input is not the last child (`!isLastChild`) and a non-empty separator string is provided【2†L61-L64】.

Because the component uses `v-html` to render the separator content, Vue processes the string as raw HTML, enabling complex markup injection.

## Implementing Custom OTP Separators

### Simple Character Separators

Pass a plain string character to insert basic visual dividers between digits.

```vue
<template>
  <v-otp-input
    :num-inputs="4"
    separator="-"
    v-model:value="code"
  />
</template>

<script setup lang="ts">
import { ref } from "vue";
const code = ref("");
</script>

```

This renders a dash between each of the four input fields.

### Emoji and Symbol Separators

The `v-html` rendering supports Unicode characters and emojis.

```vue
<template>
  <v-otp-input
    :num-inputs="6"
    separator="🚀"
    v-model:value="otp"
  />
</template>

<script setup lang="ts">
import { ref } from "vue";
const otp = ref("");
</script>

```

### HTML Component Separators

For styled separators, pass HTML markup directly through the prop.

```vue
<template>
  <v-otp-input
    :num-inputs="5"
    :separator="`<span class='otp-separator'>|</span>`"
    v-model:value="pin"
  />
</template>

<style>
.otp-separator {
  color: #888;
  margin: 0 8px;
  font-weight: bold;
}
</style>

```

Note that styles must be global (not scoped) since the separator renders outside the component's style scope.

### Advanced SVG and Component Separators

For complex graphics like SVG icons, inline the markup or compute it in your script.

```vue
<script setup lang="ts">
import { ref } from "vue";

const otp = ref("");
const dotSeparator = `<svg width="12" height="12" viewBox="0 0 24 24" style="margin: 0 4px;">
  <circle cx="12" cy="12" r="3" fill="#555"/>
</svg>`;
</script>

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

```

## Technical Implementation Details

The separator rendering logic in [`src/components/single-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/src/components/single-otp-input.vue) uses a conditional template block:

```vue
<template v-if="!isLastChild && separator">
  <span v-html="separator"></span>
</template>

```

This implementation ensures that:
- No separator appears after the final input field
- Empty strings do not render unnecessary DOM elements
- Raw HTML injection occurs safely through Vue's `v-html` directive

Because `v-html` disables Vue's reactive bindings on the injected content, avoid using Vue directives (like `v-if` or `@click`) inside your separator markup. Use static HTML, CSS, or SVG instead.

## Summary

- The `separator` prop in `vue3-otp-input` accepts any HTML string and renders it between input fields using `v-html`.
- The component automatically suppresses the separator after the last digit via the `isLastChild` check in [`single-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/single-otp-input.vue).
- You can use simple characters, emojis, styled HTML spans, or SVG graphics as separators.
- Styles for custom HTML separators must be global since the content renders outside scoped style boundaries.

## Frequently Asked Questions

### Can I use Vue components as separators?

No, you cannot directly pass a Vue component reference to the `separator` prop because the content renders via `v-html`, which processes raw HTML strings only. To use a Vue component, extract its rendered HTML markup as a string (using a render function or by inlining the SVG/template markup) and pass that string to the `separator` prop.

### Why isn't my separator showing between the last two inputs?

The [`single-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/single-otp-input.vue) component explicitly checks `!isLastChild` before rendering the separator【2†L61-L64】. This design prevents a trailing separator after the final input field. If you need a separator before the last input, you would need to modify the source code or use CSS pseudo-elements on the container.

### Can I apply different styles to individual separators?

All separators receive the same HTML markup string from the `separator` prop, so you cannot pass different markup to different positions through the prop alone. However, you can use CSS selectors like `:nth-child()` or `:last-of-type` on the separator elements (if you assign them a class) to style specific instances differently.

### Is the separator prop reactive to changes?

Yes, the `separator` prop is reactive. Since it is a standard Vue prop passed from [`vue3-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/vue3-otp-input.vue) down to [`single-otp-input.vue`](https://github.com/ejirocodes/vue3-otp-input/blob/main/single-otp-input.vue) instances, any changes to the separator string in the parent component will immediately update the rendered separators in the DOM through Vue's reactivity system.