Join our Discord Community

Switch

A control that allows users to toggle between checked and not checked states. Perfect for settings, preferences, and feature toggles in React applications with Next.js, TypeScript, and Tailwind CSS.

You know those toggle switches that just feel right when you flip them? Like the ones on your phone for airplane mode or dark theme? That's what Switch gives you - a satisfying binary control that users actually want to interact with.

Basic toggle

Simple on/off control with proper labeling:

Loading component...

Just a clean toggle with clear labeling. This free open source React component handles all the accessibility requirements so screen readers know what's being toggled and users can navigate with keyboards.

npx shadcn@latest add switch

Why switches beat checkboxes for settings

Sometimes you need something that feels more immediate than a checkbox:

  • Visual feedback - Users see the state change instantly
  • Mobile friendly - Large touch targets that feel natural to tap
  • Settings context - Clearly indicates system preferences vs form data
  • Immediate effect - Perfect when changes apply right away
  • Status indication - Shows current state at a glance
  • Satisfying interaction - That little slide animation feels good

Real-world switch patterns

Form integration

Email preferences with proper validation:

Loading component...

Settings panel

App preferences grouped logically:

Loading component...

These examples show switches in their natural habitat - settings screens, preference panels, and feature toggles. Each switch clearly communicates what it controls and responds immediately.

Perfect for user preferences

Switches work best when the change takes effect immediately. Dark mode, notifications, privacy settings, feature flags, accessibility options. Much better than checkboxes when you're dealing with system-level toggles rather than form data.

Built on Radix UI Switch primitive with full keyboard navigation support. Full TypeScript support. Styled with Tailwind CSS to match the shadcn design system.

Radix UI Foundation

The Switch component is built on top of Radix UI's Switch primitive, providing:

  • Full keyboard navigation - Space and Enter keys toggle the switch
  • Accessibility compliance - Adheres to the switch ARIA role requirements
  • Form integration - Renders a hidden input for proper form submission
  • Controlled/uncontrolled - Works in both controlled and uncontrolled modes
  • Data attributes - Provides data-state and data-disabled attributes for styling

Component Structure

The Radix UI Switch consists of two main parts:

import * as Switch from "@radix-ui/react-switch"

<Switch.Root>
  <Switch.Thumb />
</Switch.Root>

API Reference

Switch (Root)

Contains all parts of the switch and renders a hidden input for forms.

PropTypeDefaultDescription
checkedboolean-The controlled checked state of the switch
defaultCheckedboolean-The default checked state (uncontrolled)
onCheckedChange(checked: boolean) => void-Event handler called when the checked state changes
disabledbooleanfalseWhether the switch is disabled
requiredbooleanfalseWhether the switch is required in forms
namestring-The name of the switch for form submission
valuestring"on"The value given as data when submitted with a name
idstring-The id attribute for the switch
classNamestring-Additional CSS classes

Data Attributes

The switch automatically applies data attributes for styling:

AttributeValuesDescription
[data-state]"checked" | "unchecked"Indicates the current state
[data-disabled]Present when disabledApplied when switch is disabled

State management

The Switch can be controlled or uncontrolled:

// Controlled
const [enabled, setEnabled] = useState(false)
<Switch checked={enabled} onCheckedChange={setEnabled} />

// Uncontrolled  
<Switch defaultChecked={true} />

Form integration

Works seamlessly with React Hook Form and other form libraries:

<FormField
  control={form.control}
  name="notifications"
  render={({ field }) => (
    <FormItem className="flex items-center justify-between">
      <FormLabel>Push Notifications</FormLabel>
      <FormControl>
        <Switch
          checked={field.value}
          onCheckedChange={field.onChange}
        />
      </FormControl>
    </FormItem>
  )}
/>

Accessibility features

Built-in accessibility support includes:

  • ARIA labels - Proper role and state attributes
  • Keyboard support - Space and Enter keys toggle the switch
  • Focus management - Clear visual focus indicators
  • Screen reader support - State changes are announced
  • Label association - Connects with Label components via id/htmlFor
  • Form integration - Works with form validation and submission

Keyboard navigation

KeyAction
SpaceToggle the switch
EnterToggle the switch

Switch vs Checkbox guidelines

Use Switch when:

  • Settings and preferences - System-level configuration
  • Immediate effect - Change applies right away without form submission
  • Binary states - Clear on/off, enabled/disabled states
  • Feature toggles - Turning functionality on or off

Use Checkbox when:

  • Form data - Part of form that gets submitted
  • Multiple selection - Selecting items from a list
  • Agreement - Terms acceptance, consent flows
  • Data collection - Gathering user information

Design patterns for switches

Settings organization

Group related switches with clear section headers:

<div className="space-y-6">
  <div>
    <h3 className="mb-4 text-lg font-medium">Notifications</h3>
    <div className="space-y-4">
      <SwitchItem label="Email updates" />
      <SwitchItem label="Push notifications" />
    </div>
  </div>
  
  <div>
    <h3 className="mb-4 text-lg font-medium">Privacy</h3>
    <div className="space-y-4">
      <SwitchItem label="Analytics" />
      <SwitchItem label="Location sharing" />
    </div>
  </div>
</div>

Descriptive labels

Always include helpful descriptions for complex settings:

<div className="flex items-center justify-between">
  <div className="space-y-0.5">
    <Label className="font-medium">Auto Save</Label>
    <p className="text-sm text-muted-foreground">
      Automatically save your work as you type
    </p>
  </div>
  <Switch />
</div>

Immediate feedback

Show the effect of toggle changes right away:

const [darkMode, setDarkMode] = useState(false)

useEffect(() => {
  document.documentElement.classList.toggle('dark', darkMode)
}, [darkMode])

<Switch 
  checked={darkMode} 
  onCheckedChange={setDarkMode}
/>

Common switch scenarios

Keep these patterns in mind when adding switches to your interface:

  • Label clearly - Describe exactly what the switch controls
  • Group logically - Related settings should be visually connected
  • Show current state - Make the on/off position obvious
  • Provide descriptions - Explain what happens when toggled
  • Test on mobile - Ensure touch targets are large enough
  • Consider consequences - Some settings might need confirmation dialogs
  • Persist state - Remember user preferences across sessions
  • Handle errors gracefully - What if the setting change fails?