How to build a spellcheck-enabled textarea with Tailwind CSS and Alpine.js

Add an Alpine-powered spellcheck toggle to a Tailwind CSS textarea so writers can choose whether the browser should flag typos.

Published on November 26, 2025 by Michael Andreuzza · 3 min read

Sometimes you want to let users decide whether spellcheck runs—maybe they’re entering code, brand names, or multiple languages. This pattern wraps a standard textarea with an Alpine.js checkbox that toggles the browser’s built-in spellcheck behavior. No third-party libraries required.

What’s inside

  • A single x-data object tracks text + spellCheck.
  • Tailwind CSS provides the same clean textarea styling as other components, so it stays visually consistent.
  • A checkbox flips the spellCheck boolean and updates the textarea instantly.

1. Alpine state container

Store the textarea value and the spellcheck preference inside one Alpine component.

<div class="w-full space-y-1" x-data="{ text: '', spellCheck: true }">
  <!-- textarea + checkbox -->
</div>
  • Initialize spellCheck to true if you want spellcheck on by default.
  • space-y-1 keeps the label, textarea, and toggle comfortably spaced.

2. Textarea wiring and styling

Bind the textarea’s content with x-model and pass the boolean through :spellcheck.

<textarea
  id="spellcheck-textarea"
  x-model="text"
  rows="4"
  placeholder="Type your message"
  :spellcheck="spellCheck"
  class="block w-full px-4 py-2 text-sm text-blue-700 bg-white border border-transparent rounded-lg appearance-none duration-300 ring-1 ring-zinc-200 placeholder-zinc-400 focus:border-zinc-300 focus:bg-transparent focus:outline-none focus:ring-blue-500 focus:ring-offset-2 focus:ring-2"
></textarea>
  • :spellcheck="spellCheck" rewrites the DOM attribute whenever the checkbox changes.
  • Tailwind’s ring/focus utilities keep parity with other inputs on the site.

3. Checkbox toggle

A simple checkbox bound with x-model updates the boolean without extra handlers.

<label class="flex items-center gap-3 text-sm text-zinc-500">
  <input
    type="checkbox"
    class="text-blue-600 rounded shadow size-4 border-zinc-300 focus:ring-blue-600"
    x-model="spellCheck"
  />
  Enable spellcheck
</label>
  • Wrapping the input and text in a label makes the entire row clickable.
  • Adjust the copy if you want to surface the current state (e.g., x-text="spellCheck ? 'Disable' : 'Enable'").

4. Copy-and-paste snippet

Drop this into any Alpine-enabled page.

<div class="w-full space-y-1" x-data="{ text: '', spellCheck: true }">
  <label class="text-sm font-medium text-zinc-500"> Spellcheck textarea </label>
  <textarea
    id="spellcheck-textarea"
    x-model="text"
    rows="4"
    placeholder="Type your message"
    class="block w-full px-4 py-2 text-sm text-blue-700 bg-white border border-transparent rounded-lg appearance-none duration-300 ring-1 ring-zinc-200 placeholder-zinc-400 focus:border-zinc-300 focus:bg-transparent focus:outline-none focus:ring-blue-500 focus:ring-offset-2 focus:ring-2 sm:text-sm"
    :spellcheck="spellCheck"
  ></textarea>
  <label class="flex items-center mt-2 text-sm gap-3 text-zinc-500">
    <input
      type="checkbox"
      class="text-blue-600 rounded shadow size-4 border-zinc-300 focus:ring-blue-600"
      x-model="spellCheck"
    />
    Enable spellcheck
  </label>
</div>

Finishing touches

  • Invert the label text (Disable spellcheck) dynamically based on the boolean to make the toggle clearer.
  • If you track analytics, dispatch a custom event when spellCheck flips to understand user preferences.
  • Add a helper tooltip or description to explain when spellcheck might catch product names or jargon incorrectly.

/Michael Andreuzza