useSound() — Add small sounds effects to your page
No sound? Browsers require you to interact with the page first (e.g. click somewhere), before you can play sounds.
1import { useEffect, useRef } from "react";2
3type Settings = {4 volume?: number;5 playbackRate?: number;6};7
8export const useSound = (url: string, settings: Settings | undefined = {}) => {9 const audioRef = useRef<HTMLAudioElement | null>(null);10
11 useEffect(() => {12 // If the url changes, we clear the old instance,13 // this way a new Audio instance will be created on the next play14 audioRef.current = null;15 }, [url]);16
17 useEffect(() => {18 if (!audioRef.current) return;19 audioRef.current.volume = settings.volume || 1;20 audioRef.current.playbackRate = settings.playbackRate || 1;21 }, [settings]);22
23 const play = () => {24 if (typeof window === "undefined") return;25
26 if (!audioRef.current) {27 // We only created the Audio instance when play is fired,28 // this way we can avoid loading the sound if it's not used29 audioRef.current = new Audio(url);30 }31
32 try {33 audioRef.current.currentTime = 0;34 audioRef.current.play();35 } catch {}36 };37
38 return [play];39};
1import { useEffect, useRef } from "react";2
3export const useSound = (url, settings = {}) => {4 const audioRef = useRef(null);5
6 useEffect(() => {7 // If the url changes, we clear the old instance,8 // this way a new Audio instance will be created on the next play9 audioRef.current = null;10 }, [url]);11
12 useEffect(() => {13 if (!audioRef.current) return;14 audioRef.current.volume = settings.volume || 1;15 audioRef.current.playbackRate = settings.playbackRate || 1;16 }, [settings]);17
18 const play = () => {19 if (typeof window === "undefined") return;20
21 if (!audioRef.current) {22 // We only created the Audio instance when play is fired,23 // this way we can avoid loading the sound if it's not used24 audioRef.current = new Audio(url);25 }26
27 try {28 audioRef.current.currentTime = 0;29 audioRef.current.play();30 } catch {}31 };32
33 return [play];34};
Subtle sounds can add some life to your page ✨. They make it feel more interactive and engaging.
After using Josh Comeau’s hook useSound for quite a while, I kept stumbling on a few issues with the package that didn’t get fixed. Probably because Josh also moved on from this library.
That is why I decided to write my own basic implementation of the useSound hook. The implementation is based around the standardized Web Audio API. That means we need pretty little code to make a small hook that plays a sound.
Using the hook
To use the hook, you need to pass the URL of the sound you want to play. Optionally you can pass an object with the volume and playback rate settings.
The hook then returns an array with a single function (for now 😉), which you can call to play the sound.
1import { useSound } from "./useSound";2
3const MyComponent = () => {4 const [play] = useSound("/path/to/sound.mp3", {5 volume: 0.5,6 playbackRate: 1.5,7 });8
9 return <button onClick={play}>Play sound</button>;10};