Zum Inhalt springen
    WingoUI
    KomponentenVorlagenDokuPreiseKI-AgentenBlogChangelog
    1. Startseite
    2. Blog
    3. Komponenten-Guides
    4. React Tag Input: Chips aus Tippen, Einfügen und Vorschlägen
    Read in English
    1. Blog
    2. Komponenten-Guides
    3. React Tag Input: Chips aus Tippen, Einfügen und Vorschlägen
    Komponenten-Guides
    Komponenten-Guides

    React Tag Input: Chips aus Tippen, Einfügen und Vorschlägen

    SR
    Serban Rusu · Gründer von Wingo UI
    13. Okt. 2026 · 8 Min. Lesezeit

    Auf dieser Seite

    0%
    1. Was muss ein React Tag Input können?
    2. Welche Props sind am wichtigsten?
    3. Wie nutze ich einen Tag Input mit react-hook-form und zod?
    4. Ist der Tag Input barrierefrei?
    5. Wie verhält sich der Tag Input auf dem Smartphone?
    6. Wann ist ein Multi-Select die bessere Wahl?
    7. Wie gehe ich mit einer Liste von E-Mail-Adressen um?
    8. Wie schneidet der Tag Input im Vergleich zu shadcn und anderen Bibliotheken ab?
    9. Wo fängst du am besten an?
    10. Häufige Fragen
      1. Wie baue ich einen Tag Input in React?
      2. Hat shadcn/ui einen Tag Input?
      3. Wie gehe ich mit einer eingefügten Liste in einem Tag Input um?
      4. Was ist der Unterschied zwischen einem Tag Input und einem Multi-Select?
      5. Wie sende ich Tags mit einem Formular in React ab?

    Kurz gesagt

    Ein React Tag Input macht aus freiem Text entfernbare Chips: Enter, ein Komma oder ein Semikolon fügt einen hinzu, eine eingefügte Liste wird auf einen Schlag zu mehreren, Duplikate und ungültige Einträge bleiben mit sichtbarem Grund draußen, und Backspace im leeren Feld bearbeitet den letzten Chip. Nimm ihn, wenn Leute ihre eigenen Werte tippen, etwa Keywords, Hashtags oder E-Mail-Adressen. Kommt jeder Wert aus einer bekannten Liste, ist ein Multi-Select mit Checkboxen die bessere Wahl.

    Veröffentlicht am 13. Okt. 2026

    Ein React Tag Input sieht aus wie ein Textfeld mit Chips darin, und die Basisversion hat zwanzig Zeilen: ein Array im State, ein Chip pro Eintrag, Hinzufügen bei Enter. Dann fügt jemand „emma@acme.com, liam@acme.com; olivia@acme.com“ ein und bekommt einen einzigen langen Chip. Leute tippen einen Tag, den es schon gibt, laufen in ein Limit, das niemand erklärt hat, oder sollen auf dem Smartphone ein 12px kleines × treffen. Dieser Guide zeigt, was eine React Tag Input Komponente abfangen muss, welche Props beim Tag Input von Wingo UI (der Bibliothek, die wir bauen) wirklich zählen, wie es um Barrierefreiheit und das Verhalten auf dem Smartphone steht und wann ein Multi Select oder ein Email Input die bessere Wahl ist.

    Was muss ein React Tag Input können?

    Ein React Tag Input muss acht Dinge abdecken: Hinzufügen, Einfügen, Duplikate, Validierung, Limits, Bearbeiten, Tastatur und Formulare. An dieser Checkliste messen wir jeden React Chips Input, unseren eingeschlossen:

    • Hinzufügen. Enter fügt immer hinzu. Ein Komma oder ein Semikolon auch, und ebenso das Verlassen des Felds, damit getippter Text nie verloren geht.
    • Einfügen. Eine eingefügte Liste mit Kommas, Semikolons, Tabs oder Zeilenumbrüchen wird zu einem Chip pro Eintrag, getrimmt, Duplikate nur einmal.
    • Duplikate. Ein Tag, den es schon gibt, kommt nicht noch einmal dazu (Groß- und Kleinschreibung und Akzente zählen beim Vergleich nicht), und der vorhandene Chip zeigt, wo er steht.
    • Validierung. Ein ungültiger Eintrag bleibt im Textfeld stehen, mit einem Grund darunter, statt zu verschwinden.
    • Limits. Eine maximale Anzahl Tags und eine maximale Länge pro Tag, beides in der Beschreibung erklärt.
    • Bearbeiten. Backspace im leeren Feld holt den letzten Chip als Text zurück. Ein Chip lässt sich direkt an Ort und Stelle bearbeiten.
    • Tastatur. Pfeiltasten wechseln zwischen den Chips, Delete entfernt den fokussierten, Escape springt zurück in den Text.
    • Formulare. Die Werte landen ohne Glue-Code in FormData und react-hook-form.

    Der Tag Input kann all das. Installier ihn und rendere ihn mit Vorschlägen:

    bash
    npx wingo-ui@latest add tag-input
    tsx
    "use client";
    import { useState } from "react";
    import { TagInput } from "@/components/ui/tag-input";
    const TOPICS = [
    { value: "react", label: "React" },
    { value: "nextjs", label: "Next.js" },
    { value: "tailwind", label: "Tailwind CSS" },
    { value: "typescript", label: "TypeScript" },
    { value: "accessibility", label: "Barrierefreiheit" },
    ];
    export function PostTopics() {
    const [tags, setTags] = useState<string[]>(["react"]);
    return (
    <TagInput
    label="Themen"
    description="Bis zu 5 Themen. Drück nach jedem Thema Enter oder tippe ein Komma."
    value={tags}
    onValueChange={setTags}
    suggestions={TOPICS}
    max={5}
    maxLength={24}
    name="topics"
    />
    );
    }

    Ein gewählter Vorschlag speichert seinen value, der Chip zeigt sein label. Aus „nextjs“ in deinen Daten wird auf dem Bildschirm also „Next.js“. Tippt jemand ein Label exakt so ein, landet ebenfalls der Value in der Liste.

    Tippe ein Wort und drück Enter, dann füg „city, commuter; steel“ ein, um drei Tags auf einmal hinzuzufügen. Tippe einen vorhandenen Tag wie bike: Sein Chip pulsiert, statt dass eine Kopie erscheint
    $ npx wingo-ui@latest add tag-input
    ProDoku: Tag Input

    Welche Props sind am wichtigsten?

    delimiters, max, maxLength, transform und validate decken die meisten Formulare ab. Der Rest legt fest, wie sich Duplikate, strikte Listen, Backspace, Blur und Einfügen verhalten:

    Prop und StandardwertFunktion
    delimiters, Standard [",", ";"]Zeichen, die den aktuellen Text als Tag hinzufügen. Enter fügt immer hinzu.
    max, Standard 0 (kein Limit)Ist das Limit erreicht, wird das Textfeld ausgeblendet und die Beschreibung weist darauf hin.
    maxLength, Standard 0 (kein Limit)Zeichen pro Tag; längerer Text wird beim Tippen oder Einfügen gekürzt.
    transform, Standard: trimmen und Leerzeichen zusammenfassenNormalisiert den Text vor der Validierung, etwa durch Kleinschreibung.
    validate, kein StandardGib false oder eine Meldung als String zurück, um einen Tag abzulehnen.
    allowDuplicates, Standard falseAus: Eine Wiederholung wird abgewiesen und der vorhandene Chip pulsiert.
    restrictToSuggestions, Standard falseNur Vorschläge können zu Tags werden.
    backspace, Standard "edit"Backspace im leeren Feld: den letzten Tag bearbeiten, ihn erst auswählen oder ihn entfernen.
    addOnBlur, addOnPaste, Standard trueGetippten Text beim Blur hinzufügen; eine eingefügte Liste aufteilen.

    transform und validate zusammen decken die meisten eigenen Regeln ab. Hashtags sind ein gutes Beispiel: Text in Kleinbuchstaben, Leerzeichen raus, # davor, dann das Ergebnis mit dem fertigen Validator prüfen:

    tsx
    import { TagInput, tagValidators } from "@/components/ui/tag-input";
    export function Hashtags() {
    return (
    <TagInput
    label="Hashtags"
    defaultValue={["#newyork"]}
    transform={(tag) => "#" + tag.toLowerCase().replace(/^#+/, "").replace(/\s+/g, "")}
    validate={tagValidators.hashtag}
    labels={{ invalid: () => "Nur Buchstaben, Ziffern und _" }}
    />
    );
    }

    tagValidators hat außerdem email und url. Mit dem E-Mail-Validator wechselt die Smartphone-Tastatur auf das E-Mail-Layout. Jeder Grund, aus dem ein Tag abgewiesen wird ("invalid", "duplicate", "limit", "notInList"), geht zusätzlich an onReject, falls du sie zählen oder eine eigene Meldung zeigen willst.

    Wie nutze ich einen Tag Input mit react-hook-form und zod?

    Pack den Tag Input in einen Controller und validiere das Array mit zod (unser Tutorial zum React Multi Step Form zeigt dasselbe Muster über mehrere Schritte). register passt nicht, weil es kein einzelnes natives Input-Element gibt, das den Wert hält:

    tsx
    "use client";
    import { Controller, useForm } from "react-hook-form";
    import { zodResolver } from "@hookform/resolvers/zod";
    import { z } from "zod";
    import { TagInput } from "@/components/ui/tag-input";
    import { Button } from "@/components/ui/button";
    const schema = z.object({
    title: z.string().trim().min(1, { error: "Gib einen Titel ein" }),
    tags: z
    .array(z.string())
    .min(1, { error: "Füg mindestens einen Tag hinzu" })
    .max(8, { error: "Höchstens 8 Tags" }),
    });
    type Listing = z.infer<typeof schema>;
    export function ListingForm({ save }: { save: (listing: Listing) => Promise<void> }) {
    const form = useForm<Listing>({ resolver: zodResolver(schema), defaultValues: { title: "", tags: [] } });
    return (
    <form onSubmit={form.handleSubmit(save)} className="flex flex-col gap-4">
    <Controller
    name="tags"
    control={form.control}
    render={({ field, fieldState }) => (
    <TagInput
    label="Tags"
    value={field.value}
    onValueChange={field.onChange}
    onBlur={field.onBlur}
    ref={field.ref}
    transform={(tag) => tag.trim().toLowerCase()}
    max={8}
    error={fieldState.error?.message}
    />
    )}
    />
    <Button type="submit">Speichern</Button>
    </form>
    );
    }

    ref und onBlur landen auf dem Textfeld, damit react-hook-form das Feld fokussieren kann, wenn das Array die Validierung nicht besteht. Behalte max in der Komponente und die .max()-Regel im Schema: Das eine bremst Leute früh, das andere schützt den Server.

    Ohne react-hook-form übergibst du name, und der Tag Input rendert pro Tag einen Hidden Input. Eine Server Action liest sie mit getAll:

    tsx
    // app/actions.ts
    "use server";
    import { z } from "zod";
    // dieselben Limits wie in der Komponente: Hidden Inputs lassen sich wie jedes andere Feld bearbeiten
    const topicsSchema = z.array(z.string().trim().min(1).max(24)).max(5);
    export async function saveTopics(formData: FormData) {
    const topics = topicsSchema.parse(formData.getAll("topics"));
    // hier die Themen speichern
    return { topics };
    }

    Ist der Tag Input barrierefrei?

    Das Textfeld behält sein Label, und die Box ist eine Gruppe, die nach diesem Label benannt ist. Jeder Chip ist fokussierbar und hat einen Namen, der sagt, was zu tun ist: „Tag bike, zum Entfernen Delete drücken“; über labels.tag kannst du ihn ändern. Hinzufügen, Entfernen, Duplikate und das Limit werden über eine Live Region mit aria-live="polite" angesagt. Wer einen Screenreader nutzt, hört also „bike wurde bereits hinzugefügt“ statt gar nichts.

    Das Tastaturmodell folgt dem Text: Pfeil nach links am Anfang des Texts springt auf die Chips, Links und Rechts wandern zwischen ihnen, Home und End springen zum ersten oder letzten Chip, Delete oder Backspace entfernt den fokussierten Chip und setzt den Fokus auf den Nachbarn, Enter oder F2 bearbeitet ihn direkt, und Escape bringt dich zurück in den Text. Vorschläge öffnen sich mit Pfeil nach unten unter dem Feld; Enter wählt den markierten.

    Wie verhält sich der Tag Input auf dem Smartphone?

    Drei Details entscheiden, ob ein Tag Input auf dem Smartphone funktioniert:

    • 16px Schriftgröße. iOS Safari zoomt in Inputs mit kleinerer Schrift hinein. Der Tag Input nutzt auf Smartphones 16px, egal welche size gesetzt ist.
    • Trennzeichen werden aus dem Wert gelesen. Virtuelle Tastaturen auf Android feuern keydown meist mit key: "Unidentified" (keyCode 229). Ein Handler, der auf event.key === "," wartet, sieht das Komma also nie. Die Komponente prüft stattdessen den Text in onChange, deshalb trennt ein Komma immer.
    • Touch Targets. Das × auf jedem Chip hat eine Trefferfläche, die größer ist als das Icon, und die Vorschläge bleiben im Seitenfluss unter dem Feld, über der Tastatur, statt in einer schwebenden Ebene, die die Tastatur verdecken kann.

    Mehr zu diesen Regeln steht in Mobile-first React-Komponenten.

    Wann ist ein Multi-Select die bessere Wahl?

    Nimm einen Multi-Select, wenn die Optionen bekannt und endlich sind: zuständige Personen, Kategorien, Länder, Berechtigungen. Leute können die ganze Liste überfliegen, sie können sich nicht vertippen, und in deinen Daten landen nie „Tailwind“, „tailwind“ und „tailwindcss“ als drei Werte.

    Herkunft der WerteKomponente
    Von der Person, offen (Keywords, Hashtags, Skills)Tag Input
    Von der Person, aber du willst zu bekannten Werten lenkenTag Input mit suggestions
    Nur aus einer Liste (strikt)Multi Select, oder Tag Input mit restrictToSuggestions
    Aus einer Liste, plus ab und zu ein neuer WertMulti Select mit creatable und onCreate
    E-Mail-AdressenEmail Input mit multiple

    Der Multi Select, ausführlich im Guide zum React Multi Select behandelt, zeigt Chips mit einem +N-Überlauf, hat bei mehr als acht Optionen eine Suchzeile oben, selectAll, maxSelected und asynchrones loadOptions. Auf dem Smartphone öffnet er ein Bottom Sheet mit 48px hohen Checkbox-Zeilen und einem Fertig-Button:

    tsx
    import { useState } from "react";
    import { MultiSelect, type MultiSelectOption } from "@/components/ui/multi-select";
    const ASSIGNEES: MultiSelectOption[] = [
    { value: "emma", label: "Emma Carter" },
    { value: "liam", label: "Liam Brooks" },
    { value: "olivia", label: "Olivia Bennett" },
    ];
    export function Assignees() {
    const [ids, setIds] = useState<string[]>([]);
    return <MultiSelect label="Zuständig" options={ASSIGNEES} value={ids} onValueChange={setIds} maxSelected={3} name="assignees" />;
    }
    Öffne die Liste und hak ein paar Zeilen an: Die Chips fallen zu +N zusammen, sobald sie nicht mehr in eine Zeile passen. Auf dem Smartphone öffnet sich die Liste als Bottom Sheet mit einem Fertig-Button
    $ npx wingo-ui@latest add multi-select
    ProDoku: Multi Select

    Wie gehe ich mit einer Liste von E-Mail-Adressen um?

    E-Mail-Empfänger sehen aus wie Tags, brauchen aber mehr: einen Namen neben der Adresse, Kontakte zum Auswählen und Hinweise auf Tippfehler. Der Email Input mit multiple macht aus einem eingefügten „Emma Carter emma@acme.com, liam@acme.com“ Chips mit Namen, behält eine falsche Adresse als roten Chip, den du später korrigierst (wie in einer Mail-App), und markiert einen wahrscheinlichen Tippfehler wie gmial.com bernsteinfarben und bietet die Korrektur mit einem Antippen an:

    tsx
    <EmailInput multiple label="Per E-Mail einladen" value={to} onValueChange={setTo} contacts={CONTACTS} max={20} name="invites" clearable />
    Füg „Ava Reed <ava@acme.com>, olivia@gmial.com“ ein: Der erste Chip zeigt den Namen, der zweite wird bernsteinfarben und bietet die Korrektur des Tippfehlers mit einem Antippen an
    $ npx wingo-ui@latest add email-input
    ProDoku: Email Input

    Wie schneidet der Tag Input im Vergleich zu shadcn und anderen Bibliotheken ab?

    shadcn/ui hat keinen Tag Input, Mantines TagsInput kommt Feature für Feature am nächsten, und react-tag-input ist das ältere Standalone-Paket, bei dem Umsortieren per Drag-and-drop standardmäßig aktiv ist. Die Details, Stand Oktober 2026 (Mantine-v9.7-Doku, README von react-tag-input):

    Wingo UI Tag Inputshadcn/uiMantine TagsInputreact-tag-input
    Getippte WerteJaKein Tag Input; Combobox multiple mit Chips wählt aus einer ListeJaJa
    Trennt bei, ; Enter, Einfügen mit Zeilenumbrüchen und Tabsentfälltstandardmäßig , (splitChars), auch beim Einfügenstandardmäßig Enter und Tab; separators ergänzt Space, Comma oder Semicolon
    DuplikateStandardmäßig aus, vorhandener Chip pulsiertentfälltStandardmäßig aus (allowDuplicates)Standardmäßig eindeutig (allowUnique)
    Limitmax, maxLengthentfälltmaxTagsmaxTags, maxLength
    Umsortieren per Drag-and-dropNeinentfälltJa (withPillsReorder)Ja, standardmäßig an (allowDragDrop)
    StylingTailwind v4, Quellcode in deinem RepoTailwind, Quellcode in deinem RepoMantine-StylesDein eigenes CSS

    Quellen: Komponentenliste von shadcn/ui (opens in a new tab) und Combobox-Doku (opens in a new tab), Mantine TagsInput (opens in a new tab), README von react-tag-input (opens in a new tab).

    Brauchst du einen shadcn Tag Input, kommt die Combobox im Mehrfachmodus offiziell am nächsten heran, und sie ist die richtige Wahl, wenn die Werte aus einer Liste kommen. Mantines TagsInput ist die bessere Wahl, wenn deine App schon Mantine nutzt. Müssen Leute Tags per Drag in eine Reihenfolge bringen, nimm Mantine oder react-tag-input: Unser Tag Input sortiert nicht um. Willst du einen Tailwind Tag Input, bei dem Aufteilen beim Einfügen, Validierung mit Begründung, Tastaturnavigation zwischen Chips und das Verhalten auf dem Smartphone schon eingebaut sind, dann deckt der Tag Input von Wingo UI genau das ab.

    Wo fängst du am besten an?

    Fang mit der Tag-Input-Doku an: Playground und Beispiele für E-Mails, Backspace-Modi, eine strikte Liste, Limits, Chip-Stile und Hashtags. Tag Input, Multi Select und Email Input gehören zu Wingo UI Pro: $8 im Monat, $80 im Jahr oder $150 einmalig, Stand Oktober 2026 (Preise). Für den Rest eines Formulars lies den Guide zu React-Formular-Komponenten, und weitere Guides findest du in der Kategorie Komponenten-Guides.

    Komponenten in diesem Artikel

    • Tag Input

      A React tag input that turns typed, pasted or suggested text into removable chips, for tags, keywords and email recipients.

      Pro
    • Multi Select

      A React multi select: pick several options shown as chips with a +N overflow, with search, select all, a maximum and async options.

      Pro
    • Email Input

      A React email input for one address or a list of recipients, with domain completion, typo hints, contact suggestions and validation.

      Pro

    Häufige Fragen

    Wie baue ich einen Tag Input in React?

    Halte ein Array aus Strings im State, rendere jeden Eintrag als Chip mit einem Entfernen-Button und füg den getrimmten Text bei Enter oder einem Komma hinzu; leere und doppelte Werte überspringst du. Eine fertige React Tag Input Komponente wie der Tag Input von Wingo UI ergänzt das Aufteilen beim Einfügen, Vorschläge, Limits, Validierung und Tastaturnavigation zwischen den Chips.

    Hat shadcn/ui einen Tag Input?

    Nein. Stand Oktober 2026 hat die offizielle Komponentenliste von shadcn/ui keinen Tag Input. Die Combobox unterstützt Mehrfachauswahl mit Chips und deckt damit das Auswählen aus einer Liste ab, ihre Doku zeigt aber keinen Weg, getippte Werte zu behalten, die nicht in der Liste stehen; dafür brauchst du eigenen Code oder eine Community-Komponente.

    Wie gehe ich mit einer eingefügten Liste in einem Tag Input um?

    Teil den eingefügten Text an Kommas, Semikolons, Tabs und Zeilenumbrüchen, trimme jeden Teil, wirf leere und doppelte Einträge raus und validiere jeden einzeln, bevor du ihn hinzufügst. Der Tag Input von Wingo UI macht genau das, wenn addOnPaste aktiv ist, und das ist der Standard.

    Was ist der Unterschied zwischen einem Tag Input und einem Multi-Select?

    Ein Tag Input nimmt Werte an, die die Person tippt, die Menge möglicher Werte ist also offen. Bei einem Multi-Select wählst du per Checkbox aus einer festen Liste von Optionen; die lässt sich leichter überfliegen, und Tippfehler sind ausgeschlossen.

    Wie sende ich Tags mit einem Formular in React ab?

    Rendere pro Tag einen Hidden Input mit demselben name und lies sie mit formData.getAll(name), oder pack den Tag Input in den Controller von react-hook-form und validiere das Array mit zod. Der Tag Input von Wingo UI rendert die Hidden Inputs, sobald du name übergibst.

    • Formulare
    • Tag Input
    • Chips
    • Barrierefreiheit
    • Mobile UI

    Teilen

    SR

    Über den Autor

    Serban Rusu

    Gründer von Wingo UI

    Serban Rusu hat Wingo UI gegründet. Er baut die Komponenten, die CLI und den MCP-Server und schreibt über React-UIs für Smartphones und KI-Agents.

    Mehr von Serban
    Weiterlesen

    Ähnliche Artikel

    Alle Artikel
    Komponenten-Guides

    React Multi Select mit Suche, Chips und Bottom Sheet

    So baust du einen React Multi Select, der echte Daten aushält: Chips mit +N-Überlauf, Suche, Alle auswählen nur für Treffer, ein Limit und ein Bottom Sheet.

    SRSerban Rusu·16. Okt. 2026·10 Min. Lesezeit
    Komponenten-Guides

    React Combobox: Async-Suche ohne Race Conditions

    So baust du eine React Combobox, die ohne Race Conditions am Server sucht, Akzente ignoriert, die ARIA-Tasten kennt und auf dem Handy ein Such-Sheet öffnet.

    SRSerban Rusu·16. Okt. 2026·10 Min. Lesezeit
    Komponenten-Guides

    Embla Carousel React: barrierefreie Slides ohne Layout Shift

    Bau mit Embla Carousel React ein Karussell für Fotos, Inserate, Testimonials und Onboarding, mit Tastatursteuerung, pausierbarem Autoplay und ohne Layout Shift.

    SRSerban Rusu·19. Okt. 2026·9 Min. Lesezeit
    Newsletter

    Neue Artikel per E-Mail

    Neue Guides, Tutorials und Vergleiche aus dem Wingo UI Blog, sobald sie erscheinen. Die meisten Artikel sind auf Englisch.

    Kein Spam. Du kannst dich jederzeit abmelden.

    WingoUI

    Animierte, konfigurierbare, mobile-first React-Komponenten und Blöcke. Kopier den Quellcode, pass ihn an und lass deinen Coding-Agenten damit bauen.

    Produkt

    • Komponenten
    • Vorlagen
    • Preise
    • KI-Agenten
    • Theme-Generator

    Ressourcen

    • Doku
    • Blog
    • Changelog
    • Changelog-RSS
    • llms.txt

    Rechtliches

    • AGB
    • Datenschutz
    • Rückerstattung
    • Lizenz
    • Impressum

    Komponenten-Kategorien

    • Buttons & Actions
    • Inputs
    • Forms
    • Navigation
    • Overlays
    • Feedback
    • Data Display
    • Tables & Lists
    • Charts & Stats
    • Layout
    • Media
    • AI Kit
    • Text & Effects
    • Mobile
    • Commerce
    • Marketing Sections
    • Blocks
    • Hooks & Utilities

    © 2026 Wingo UI

    Wingo UI