Skip to main content
audx works in Next.js without any config. Sounds are generated as TypeScript in your project, the React bindings ship with "use client", and every sound is safe to import during server rendering: it does nothing until it runs in a browser.

Set up

Run init from the root of your Next.js app:
init suggests a sounds directory based on your project layout, and the @/* alias that create-next-app adds to tsconfig.json covers it:

Play a sound from a client component

Sounds play in response to user interaction, so call them from a client component:
app/components/save-button.tsx
Render it from any server component as usual:
app/page.tsx
You can import a sound in a server component, but you can’t pass it to a client component as a prop: functions aren’t serializable. Import sounds inside the client components that play them.

Add a mute setting

Put <SoundProvider> in a client providers file and wrap your root layout with it. Every useSound below it follows its enabled and volume props, and also stays silent when the user has prefers-reduced-motion: reduce set.
app/providers.tsx
app/layout.tsx
Read the setting from localStorage in an effect, as above, rather than during render. Reading it during render gives a different result on the server and the client and causes a hydration mismatch. See Use with React for a toggle component that drives this setting.

Sounds outside components

Server actions, route handlers and middleware run on the server, where there is no audio. Play the sound on the client when the result comes back:
app/components/subscribe-form.tsx

Pages Router

The same code works in the Pages Router. Wrap your app in pages/_app.tsx instead of a root layout. You don’t need "use client" there.
pages/_app.tsx

Next steps

Pick sounds for each interaction

The 43 semantic sounds and when to use each one.

UI sound best practices

When to play sounds, and how to keep them accessible.