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 AndreuzzaSometimes 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-dataobject trackstext+spellCheck. - Tailwind CSS provides the same clean textarea styling as other components, so it stays visually consistent.
- A checkbox flips the
spellCheckboolean 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
spellChecktotrueif you want spellcheck on by default. space-y-1keeps 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
spellCheckflips to understand user preferences. - Add a helper tooltip or description to explain when spellcheck might catch product names or jargon incorrectly.
/Michael Andreuzza