In this article, learn how to incorporate sound effects in your React apps using a small library called uifx.
Sound effects aren’t used often for apps. You usually just see them on Big Tech’s apps like:
I think we’ve grown so accustomed to these “noises” that they’re not even considered interesting features anymore. But they are! Imagine if Apple suddenly decided to remove the “tick-tack” sound from their keyboard. For those of us who’ve gotten used to that familiar noise, we’d probably feel some kind of strange aural deprivation. Yet for web apps, we almost never see sound effects (sfx) built into the user interface and frankly… we almost don’t expect them to be there.
iOS/Android apps aren’t the only digital mediums that can express themselves with sounds. The web can… and should embrace sound effects more!
I realized there were a lot of full-fledged audio libraries like SoundManager or Howler, but none of them were designed for UI sound effects which require a fire-and-forget strategy for playing mini-sound bites… so I built a simple library for this called uifx
:
import UIfx from 'uifx';
import mp3File from './my-sounds/beep.mp3';
const beep = new UIFx({asset: mp3File});
<button onClick={beep.play}>Signup</button>
React is used here but you can use it in any JavaScript environment that has the Audio
API –– which is most modern browsers!
Here’s a practical example where sound fx is used to provide audio feedback on an <input type="range"/>
element.
import React, { Component } from 'react';
import UIfx from 'uifx';
import tickAudio from './my-sounds/tick.mp3';
const tick = new UIfx({asset: tickAudio});
export default class InputRange extends Component {
state = {
value: 0,
}
onChange = (event) => {
this.setState({ value: event.target.value });
tick.play();
}
render() {
return (
<div>
<div>{this.state.value}</div>
<input
type="range"
value={this.state.value}
onChange={this.onChange}
/>
</div>
)
}
}
Don’t you get a mental picture of a watchmaker’s tool or something? How interesting is that?! Audio adds a completely new sensory experience!
UIfx
is designed specifically for playing tiny audio files in rapid succession. Sometimes, however, you’ll want to throttle playback a bit so it doesn’t sound too crazy or overload the user’s speakers:
const tick = new UIfx({
asset: tickAudio,
throttleMs: 40
})
Finding the right balance of realtime feedback is more an art rather than a science. I usually try to put myself in user’s shoes and ask myself how much instant audio feedback I would want, and throttle accordingly.
By default, sounds will play at full volume. To change the volume of a UIfx
sound, call UIfx.setVolume()
method:
beep.setVolume(0.8).play();
// or...
beep.setVolume(0.8);
beep.play();
Valid arguments are 0.0
→ 1.0
to emulate the Audio
api. In the demo below the volume is changed using the previous <input type="range">
slider:
class ToastNotifications extends Component {
state = {
isToastVisible: false,
volume: 0.5,
}
sfx = {
beep: new UIfx({asset: beepAudio}),
tick: new UIfx({asset: tickAudio, throttleMs: 100}),
appear: new UIfx({asset: appearAudio}),
disappear: new UIfx({asset: disappearAudio})
}
onVolumeChange = (event) => {
this.setState(
{ volume: event.target.value },
// "setState" cb to get updated volume 👇
() => this.sfx.tick.setVolume(this.state.volume).play()
)
}
toggleToast = () => {
this.setState(
{ isToastVisible: !this.state.isToastVisible },
() => {
this.state.isToastVisible // 👈 decide which sfx to play
? this.sfx.appear.setVolume(this.state.volume).play()
: this.sfx.disappear.setVolume(this.state.volume).play()
}
)
}
render() {
return (
<div>
<button onClick={this.toggleToast}>
Toggle notification
</button>
<div>
Volume: {this.state.volume}
</div>
<input
value={this.state.volume}
onChange={this.onVolumeChange}
min="0.0"
max="1.0"
step="0.01"
type="range"
/>
<Toast isVisible={this.state.isToastVisible}/>
</div>
)
}
}
If you don’t want to persist volume changes, you can easily play at a different volume by passing an argument to UIfx.play()
:
const tick = new UIfx({
asset: tickMp3,
volume: 1.0
});
tick.play(0.25); // plays at 0.25 volume
tick.play(); // plays at 1.0 volume
Sound effects in web apps is a relatively unexplored domain. My hope is that uifx
will help you build apps that engage people more fully –– both visual and aural. Small touches like this can touch people’s hearts and provide more richer exeriences to your users.
📦 Check out [uifx](https://github.com/wle8300/uifx)
! I’d love to know what you think!
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi William, I found your article very useful, and I’m about to go use your teachings in my project. Thank you. -Duncan Haywood