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 readSometimes 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