Guide
React, Vue, Svelte and the rest
React
import { Combobox } from '@devix-labs/combobox/react';
import '@devix-labs/combobox/styles.css';
<Combobox
name="labels"
value={labels}
onChange={setLabels}
maxTags={5}
options={suggestions}
placeholder="Add a label"
/>
Controlled (value + onChange) or uncontrolled (defaultValue). The component renders a plain
<input> and enhances it after mount, so server rendering produces working markup and hydration
matches — and because values are written through the native setter, React's change tracking never goes
stale, which is tagify's open React issue.
Vue
<script setup>
import { Combobox } from '@devix-labs/combobox/vue';
const labels = ref(['design']);
</script>
<template>
<Combobox v-model="labels" name="labels" :options="{ maxTags: 5 }" />
</template>
Svelte
<script>
import { combobox } from '@devix-labs/combobox/svelte';
</script>
<input use:combobox={{ name: 'labels', maxTags: 5 }} />
Web component
<script type="module" src="https://www.devix.pk/cdn/oss/combobox@1.0.0/element.js"></script>
<form>
<dx-combobox name="topics" max-tags="5" placeholder="Add a topic"></dx-combobox>
</form>
Form-associated: the tags post as topics repeated, exactly like a multi-select, with no hidden input
of your own.
Laravel
<input id="labels" name="labels" value="{{ old('labels', $post->labels->implode(',')) }}">
$request->validate(['labels' => ['nullable', 'string']]);
$labels = collect(explode(',', $request->string('labels')))->filter()->unique();
The hidden input holds a comma-separated list, so a plain controller needs no JSON parsing. With the
web component you get labels[] as an array instead.
Updated 15 Sep 2026