Skip to main content
Learn how to add click sounds to buttons with customizable volume, playback rates, and variants.

Basic Button Click

The simplest way to add a click sound to a button:
import { useSound } from "@/hooks/use-sound"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function BasicClickButton() {
  const [playClick] = useSound(clickSoft)

  return (
    <Button onClick={playClick}>
      Click Me
    </Button>
  )
}

Volume Control

Adjust the volume for different button styles:
import { useSound } from "@/hooks/use-sound"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function SubtleButton() {
  const [playClick] = useSound(clickSoft, { volume: 0.3 })

  return (
    <Button variant="ghost" onClick={playClick}>
      Subtle Click
    </Button>
  )
}

Dynamic Playback Rates

Create playful effects by varying the playback rate:
import { useSound } from "@/hooks/use-sound"
import { click8bit } from "@/sounds/click-8bit"
import { Button } from "@/components/ui/button"

export function PlaybackRateButtons() {
  const [playClick] = useSound(click8bit)

  return (
    <div className="flex gap-2">
      <Button onClick={() => playClick({ playbackRate: 0.5 })}>
        Slow (0.5x)
      </Button>
      <Button onClick={() => playClick({ playbackRate: 1.0 })}>
        Normal (1x)
      </Button>
      <Button onClick={() => playClick({ playbackRate: 1.5 })}>
        Fast (1.5x)
      </Button>
      <Button onClick={() => playClick({ playbackRate: 2.0 })}>
        Very Fast (2x)
      </Button>
    </div>
  )
}

Different Click Styles

Perfect for secondary actions and ghost buttons:
import { useSound } from "@/hooks/use-sound"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function SoftClickButton() {
  const [playClick] = useSound(clickSoft, { volume: 0.5 })

  return (
    <Button variant="ghost" onClick={playClick}>
      Cancel
    </Button>
  )
}

Advanced: Hover + Click

Combine hover and click sounds for rich feedback:
import { useSound } from "@/hooks/use-sound"
import { hoverTick } from "@/sounds/hover-tick"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function InteractiveButton() {
  const [playHover] = useSound(hoverTick, { volume: 0.3 })
  const [playClick] = useSound(clickSoft, { volume: 0.6 })

  return (
    <Button 
      onMouseEnter={playHover}
      onClick={playClick}
    >
      Interactive Button
    </Button>
  )
}
Keep hover sounds subtle (volume 0.2-0.4) to avoid overwhelming users when navigating the interface.

Preventing Sound Overlap

Use the interrupt option to stop the previous sound when clicking rapidly:
import { useSound } from "@/hooks/use-sound"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function RapidClickButton() {
  const [playClick] = useSound(clickSoft, { 
    interrupt: true,
    volume: 0.7 
  })

  return (
    <Button onClick={playClick}>
      Click Me Rapidly
    </Button>
  )
}

User Preference Toggle

Respect user preferences by making sounds optional:
import { useState } from "react"
import { useSound } from "@/hooks/use-sound"
import { clickSoft } from "@/sounds/click-soft"
import { Button } from "@/components/ui/button"

export function ButtonWithPreference() {
  const [soundEnabled, setSoundEnabled] = useState(true)
  const [playClick] = useSound(clickSoft, { soundEnabled })

  return (
    <div className="flex gap-2 items-center">
      <Button onClick={playClick}>
        Click Me
      </Button>
      <label className="flex items-center gap-2">
        <input 
          type="checkbox" 
          checked={soundEnabled}
          onChange={(e) => setSoundEnabled(e.target.checked)}
        />
        Enable sounds
      </label>
    </div>
  )
}

Troubleshooting

Mobile Safari requires a user interaction before playing audio. Make sure the sound is triggered by a click event, not on page load.
// ❌ Won't work on mobile Safari
useEffect(() => {
  playSound() // Called automatically
}, [])

// ✅ Works on all platforms
<Button onClick={playSound}>
  Click Me
</Button>
Use the interrupt option to stop the previous sound:
const [playClick] = useSound(clickSoft, { interrupt: true })
Adjust the volume option (0.0 to 1.0):
const [playClick] = useSound(clickSoft, { volume: 0.5 })
Or override it per click:
const [playClick] = useSound(clickSoft)

<Button onClick={() => playClick({ volume: 0.3 })}>
  Quiet Click
</Button>

Available Click Sounds

  • click-soft - Very subtle and gentle (7ms)
  • click-8bit - Retro-style digital click (91ms)
  • switch-on - Upward-moving activation sound (364ms)
  • switch-off - Downward-moving deactivation sound (213ms)
  • hover-tick - Subtle hover feedback (224ms)
Install sounds individually:
npx soundcn@latest add click-soft
npx soundcn@latest add click-8bit
npx soundcn@latest add switch-on switch-off

Build docs developers (and LLMs) love