Implement a feature in NextJS where an MP3 file is played upon clicking

Just getting started with JS frameworks and having some trouble with the function syntax. Here's what I have so far: when the button is clicked, it should play a quick audio file specified below the button in the Audio tags. Any suggestions on how to make this work?

import Head from 'next/head'

export default function Home() {
  function play() {
    var audio = document.getElementById('a1');
    audio.play();
  }

  return (
    <div className='home'>
      <Head>
        <title>Create Next App</title>
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <div className='container'>
        <div className='col'>
          <button onClick={play()}>Click</button>
          <audio id='a1' src='/static/src.mp3'></audio>
      </div>

Answer №1

Instead of using parentheses when calling the function, pass the reference instead. Here is an example:

<button onClick={play}>Click</button>

Answer №2

<button onClick={play}>Click</button>
<audio id='a1'>
  <source src='/static/src.mp3' type='audio/mpeg' />
  Your browser does not support the audio element.
</audio>

perhaps there is an issue with the src attribute, feel free to try testing it with this src

alternatively, you might consider using useRef to target the element instead of relying on document.getElementById

Answer №3

If you're looking to improve your handling of the <audio /> element, consider utilizing a reference with the help of useRef:

import { useRef } from 'react';

export default function CustomPlayer() {
  const audioReference = useRef();

  const playAudio = () => {
    if (audioReference.current) {
      audioReference.current.play()
    } else {
      // Handle error
    }
  }

  return (
    <div>
      <button onClick={playAudio}>Play</button>
      <audio ref={audioReference} src='/static/audio.mp3' />
    </div>
  )
}

Answer №4

Encountering errors with sound libraries in NextJS led me to create my own Audio Player component that can be controlled externally. This player utilizes the "audio" tag accessed through react refs.

Let's delve into the code snippets for a better understanding.

The parent component manages a "play" state to determine if the audio should play or not. Within the AudioPlayer component, this state is monitored using useEffect, triggering the sound only when the "play" state is true after a user interaction like a button click. Once the sound finishes playing, the "play" property is reset to false, enabling it to play again when triggered.

Benefits of this approach include lesser code due to a separate component and the ability to control the AudioPlayer's state externally.

However, limitations include the need for user initiation to activate the sound and being unable to play the sound unless it has ended previously.

import React, { useRef, useEffect } from "react";

export default function AudioPlayer(props) {
  const audioRef = useRef(null);

  useEffect(() => {
    if (props.play) {
      playAudio();
    }
  }, [props.play]);

  const playAudio = () => {
    if (audioRef.current) {
      audioRef.current.play();
    }
  };

  const handleAudioEnded = () => {
    // Call the callback function when the audio ends
    if (props.onFinish) {
      props.onFinish();
    }
  };

  return (
    <div>
      <audio ref={audioRef} controls className="hidden" onEnded={handleAudioEnded}>
        <source src={props.src} type="audio/mp3" />
        Your browser does not support the audio element.
      </audio>
    </div>
  );
}

To incorporate this within the parent component:

// State to toggle sound playback
const [playSubmitSound, setPlaySubmitSound] = useState(false);

return (
        <AudioPlayer
          src="/sounds/submit.mp3"
          play={playSubmitSound}
          onFinish={() => setPlaySubmitSound(false)}
        />
        <button onClick={() => setPlaySubmitSound(true)}>sound</button>);

Note: TailwindCSS is used to hide the Audio tag, but CSS can achieve the same by setting the display: none; property on the wrapping div of the audio tag.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assign a class to an element depending on the date

I need to customize a span element in my HTML code like this. html <span class="tribe-event-date-start">September 5 @ 7:00 pm</span> My objective is to identify that specific element based on its date and then apply a class to its parent co ...

Is there a way to retrieve the selected value from a dropdown menu using vue.js?

I have a parent Vue component structured like this: <template> <form> <div class="row"> <div class="col-md-4"> <form-select id="color" name="color" :data="color">Color</form-select&g ...

What is the best way to invoke a function using a string as its name?

In my grid configuration function, I am assigning column definitions. One key, valueGetter, requires a function to be called to fetch the column value. The issue I am encountering is that the API returns this value as a string. When I try to set it using ...

What is the best way to connect a JavaScript file to an HTML file in an Express app?

I have my NodeJS server set up with Express, utilizing Handlebars as the rendering engine. app.use(express.static(publicDirPath)) (...) app.engine("hbs",hbs({ extname: "hbs", defaultView: "main", layoutsDir: path.join(srcDirP ...

"Please ensure that the field values in MessageEmbed are not left empty" stated discord.js

I've been working on a Discord bot using node.js, and I've encountered an issue with my kick and ban commands. I've tried to incorporate Discord embeds, but I keep running into this problem. Can anyone assist me with this? Here is the code ...

Angular checkbox filtering for tables

I have a table populated with data that I want to filter using checkboxes. Below is the HTML code for this component: <div><mat-checkbox [(ngModel)]="pending">Pending</mat-checkbox></div> <div><mat-checkbox [(ngModel ...

Looking for a way to store data in a sub-document in MongoDB? I am having an issue where my farm sub-documents

After many attempts, I am still facing issues while saving farm data for a User. I created an API to sign up a user and save their data, including the farm object. However, every time I try to update the code, the farm object turns into null. The goal is t ...

Execute npm build in sbt for play framework

Exploring sbt/play configuration is a new challenge for me. Working with play 2.3.8 to host my javascript application, my project utilizes: .enablePlugins(SbtWeb) .enablePlugins(play.PlayScala) .settings( ... libraryDependencies ++= WebDependancies :+ ...

If an interface property is set as (), what significance does it hold?

While exploring the Vue.js source code located at packages/reactivity/src/effects.ts, I came across this snippet: export interface ReactiveEffectRunner<T = any> { (): T effect: ReactiveEffect } I'm curious, what does () signify in the code ...

Encountered an error in NextJs where multiple children were passed to <Link> component with the same `href` while mapping

Is there an easy way to map through an array of menu items using the NextJs < Link > component? Here's the code I'm currently using: {navigation.map((item) => ( <Link key={item.name} href={item.href} className={classNam ...

"Enhance your online shopping experience with a React.js popup modal for

In the midst of developing a shopping cart, I find myself facing a challenge in making the modal pop up when clicking on the shopping cart icon. The semantic-ui documentation for modals has not provided clear instructions on achieving this functionality, s ...

Is it possible to link an HTML select element to a changing array in JavaScript?

Let's say I have an empty HTML select element. <select id="options"> </select> Can I link a JavaScript array to this select so that when the array is modified, the select options update accordingly? Alternatively, do I need to resort to ...

Tips for properly formatting functional Vue components?

Below is a functional component that functions as intended. <template functional> <div> <input /> </div> </template> <script> export default { name: "FunctionalComponent" } </script> <styl ...

Challenges encountered when creating routes in Reactjs

I'm currently working on a project and facing some challenges with managing routes. My frontend is split into two sections: one for the client side and the other for the admin panel, which is responsible for managing the client side. For example, if I ...

Having trouble setting the `variant='dense'` for material-ui Toolbar – it remains at a height of 64px no matter what

Implemented a hello world AppBar/Toolbar with the variant='dense' style. import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; import registerServiceWorker from './registerServiceWo ...

Update the state within a forEach iteration

Is there a way to update state when clicking on buttons? I keep getting an error. Error: Uncaught TypeError: this.setState is not a function I understand that this.setState cannot be used here, but I'm unsure of where to bind it. class Popup extend ...

The true essence of Angular values only comes to light once the view has been updated

Here is the HTML code I am working with : <div class="container-fluid"> <div class="jumbotron" id="welcomehead"> <br><br><br><br><br><br><br><br><br><br> ...

The functionality to apply a color class to a navbar item when clicked is malfunctioning

I'm attempting to create a navigation bar using text that toggles the visibility of different divs. I want the selected option to appear in red, indicating it has been chosen, while deselecting any other options. I am new to JavaScript and thought add ...

Show detailed information in a table cell containing various arrays using AngularJS

After integrating d3.js into my code, I now have an array with key-value pairs. Each team is assigned a key and its corresponding cost is the value. When I check the console log, it looks like this: Console.log for key and value Rate for current month [{ ...

Fetch additional data from a table by utilizing Ajax and PHP

I have 7 data entries in my database When attempting to load the data from a table using ajax and php, I encountered an issue. After clicking the "load more" button, the data displays successfully but the "load more" button disappears. Here is my index. ...