Sound effects make apps feel more responsive and polished. A subtle click on a button press, a chime on a notification, an error buzz on validation failure — these small details add up.
Here's how to add sound effects to a React app using the Lotsofsounds API.
Architecture
Fetch sounds during your build and bundle them as static assets. Simpler and avoids runtime API calls.
Fetch signed URLs from your backend and play them on demand. Better when sounds change without redeploying.
Build-time approach
Fetch sounds in a build script
const fs = require("fs");
const path = require("path");
const API_KEY = process.env.LOS_API_KEY;
const BASE = "https://api.lotsofsounds.com/api/v1";
const OUT_DIR = path.join(__dirname, "../public/sounds");
const SOUNDS = {
click: "ui click soft",
success: "success chime short",
error: "error buzz notification",
notification: "gentle notification bell",
};
async function main() {
fs.mkdirSync(OUT_DIR, { recursive: true });
for (const [name, query] of Object.entries(SOUNDS)) {
const searchRes = await fetch(
`${BASE}/sounds?q=${encodeURIComponent(query)}&limit=1&sort=avg_rating`,
{ headers: { "x-api-key": API_KEY } }
);
const { data } = await searchRes.json();
if (!data.length) continue;
const dlRes = await fetch(`${BASE}/sounds/${data[0].id}/download`, {
headers: { "x-api-key": API_KEY },
});
const { data: dl } = await dlRes.json();
const audio = await fetch(dl.download_url);
const buffer = Buffer.from(await audio.arrayBuffer());
fs.writeFileSync(path.join(OUT_DIR, `${name}.mp3`), buffer);
console.log(`Downloaded: ${name}.mp3`);
}
}
main();Create a React hook
import { useCallback, useRef } from "react";
export function useSound(src: string) {
const audioRef = useRef<HTMLAudioElement | null>(null);
const play = useCallback(() => {
if (!audioRef.current) {
audioRef.current = new Audio(src);
}
audioRef.current.currentTime = 0;
audioRef.current.play().catch(() => {});
}, [src]);
return { play };
}Use it in a component
import { useSound } from "@/hooks/useSound";
function SubmitButton() {
const { play: playClick } = useSound("/sounds/click.mp3");
const { play: playSuccess } = useSound("/sounds/success.mp3");
async function handleSubmit() {
playClick();
const result = await submitForm();
if (result.ok) playSuccess();
}
return <button onClick={handleSubmit}>Submit</button>;
}Runtime approach
If you need sounds to change without redeploying, proxy the API through your backend:
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const query = searchParams.get("q");
const searchRes = await fetch(
`https://api.lotsofsounds.com/api/v1/sounds?q=${query}&limit=1`,
{ headers: { "x-api-key": process.env.LOS_API_KEY! } }
);
const { data } = await searchRes.json();
if (!data.length)
return Response.json({ error: "Not found" }, { status: 404 });
const dlRes = await fetch(
`https://api.lotsofsounds.com/api/v1/sounds/${data[0].id}/download`,
{ headers: { "x-api-key": process.env.LOS_API_KEY! } }
);
return Response.json(await dlRes.json());
}app.get("/api/sounds/play", async (req, res) => {
const { q } = req.query;
const searchRes = await fetch(
`https://api.lotsofsounds.com/api/v1/sounds?q=${q}&limit=1`,
{ headers: { "x-api-key": process.env.LOS_API_KEY } }
);
const { data } = await searchRes.json();
if (!data.length) return res.status(404).json({ error: "Not found" });
const dlRes = await fetch(
`https://api.lotsofsounds.com/api/v1/sounds/${data[0].id}/download`,
{ headers: { "x-api-key": process.env.LOS_API_KEY } }
);
res.json(await dlRes.json());
});Tips
Best practices
- Preload sounds on page load for instant playback — don't fetch on click
- Respect user preferences: Check
prefers-reduced-motionand provide a mute toggle - Keep sounds short: UI sounds should be under 1 second. Use
max_duration=1in your search - Cache aggressively: Downloaded sounds don't change, so cache at the CDN and browser level
Get started
Related
Blog PostBuilding an Audio Pipeline with LotsofsoundsHow to automate sound effect management in your CI/CD workflow using the Lotsofsounds APIBlog PostGetting Started with the Lotsofsounds APIA step-by-step guide to integrating sound effects into your app using our REST API, with examples in cURL, JavaScript, and Python
