You can implement a custom audio player in Bubble using the HTML Audio element or a plugin like Audio Player by Zerocode. This tutorial covers adding play/pause/seek controls, building a progress bar, displaying track metadata, creating a playlist queue, and handling background playback — all through Bubble's visual editor with minimal custom code.
Overview: Implementing an Audio Player in Bubble
This tutorial shows how to build a functional audio player in your Bubble app. Whether you are building a podcast app, music platform, or e-learning tool with audio lessons, you will learn to play audio files, build custom controls, display track information, and manage playlists. We use a combination of Bubble plugins and HTML elements to create a polished audio experience.
Prerequisites
- A Bubble account with an app
- Audio files uploaded to Bubble's file manager or hosted externally
- Basic familiarity with Bubble plugins and Custom States
- Optional: an audio player plugin from the Bubble marketplace
Step-by-step guide
Install an audio player plugin or set up HTML audio
Install an audio player plugin or set up HTML audio
Go to the Plugins tab and search for audio player. Install a plugin like Audio Player by Zeroqode or BDK Native Audio. If you prefer a code-free approach, you can use Bubble's HTML element with a standard HTML5 audio tag. For the plugin approach, install it and add the Audio Player element to your page from the Element Palette. For the HTML approach, add an HTML element and enter: <audio id='myPlayer' src='dynamic_url'></audio>. The plugin approach is recommended as it provides more control without writing code.
Expected result: An audio player element or HTML audio element is on your page ready for configuration.
Create the Track data type and configure the data source
Create the Track data type and configure the data source
Go to the Data tab and create a Track data type with fields: title (text), artist (text), album (text), duration (number in seconds), audio_file (file), cover_image (image), track_number (number), playlist (Playlist type if applicable). Upload your audio files via the File Manager or through the app's upload interface. On your player page, set the audio player's source to the current track's audio_file URL. Add a Custom State called current_track (type Track) on the page to track which song is playing.
Expected result: A Track data type stores audio metadata, and the player is connected to a track's audio file.
Build custom playback controls
Build custom playback controls
Add visual elements for your player controls: a Play/Pause toggle button (use an Icon element that switches between play and pause icons based on a Custom State is_playing), Previous and Next buttons, and a volume slider (use a SliderInput element). Create workflows: When Play button is clicked → set is_playing state to yes and trigger the plugin's Play action. When Pause is clicked → set is_playing to no and trigger Pause. For volume, when the SliderInput value changes → set the player's volume. Style the controls in a horizontal row resembling a standard media player.
Pro tip: Use Conditional formatting on the play/pause button: When is_playing is yes → show the pause icon. When is_playing is no → show the play icon.
Expected result: Play, pause, skip, and volume controls work and update their visual state in real time.
Add a progress bar with seek functionality
Add a progress bar with seek functionality
Add a Group element as the progress bar container (full width, 4-8px height, grey background). Inside it, add another Group as the progress fill (same height, colored background). Set the fill width dynamically using the plugin's current time / track duration * 100 percent. If using the HTML approach, use JavaScript to update a Custom State with the current playback time every second. For seek functionality, add a click event on the container Group: calculate the click position as a percentage of the bar width and set the player's current time to that percentage of the duration.
Expected result: A progress bar shows the current playback position and users can click to seek to any point in the track.
Display track metadata and album art
Display track metadata and album art
Above or below the controls, add display elements: an Image element bound to current_track's cover_image, a Text element for current_track's title (large, bold), a Text for current_track's artist, and time displays showing current time / total duration in MM:SS format. For the time format, use a text expression that converts seconds to minutes:seconds (e.g., floor(seconds/60):formatted as 0 + ':' + seconds mod 60:formatted as 00). Update these displays dynamically as the track changes.
Expected result: The player displays album art, track title, artist name, and current/total time for the playing track.
Create a playlist queue with navigation
Create a playlist queue with navigation
Add a Repeating Group below or beside the player showing a list of Tracks. Highlight the currently playing track using a Conditional: When Current cell's Track is page's current_track → background color change. When a user clicks a track in the list, set current_track to the clicked track and start playback. For Next and Previous buttons, find the current track's position in the playlist and navigate to the next or previous item. Create a workflow: Get current_track's track_number, search for Track where track_number = current + 1 and playlist = current playlist. For more advanced audio features like streaming and DRM, RapidDev can assist with custom integrations.
Expected result: A playlist shows all tracks, highlights the current one, and next/previous buttons navigate through the queue.
Complete working example
1AUDIO PLAYER WORKFLOW SUMMARY2==============================34DATA TYPES:5 Track: title, artist, album, duration (seconds),6 audio_file, cover_image, track_number7 Playlist: name, tracks (list of Tracks), creator (User)89CUSTOM STATES (on page):10 current_track (Track)11 is_playing (yes/no)12 current_time (number)13 volume (number, default 80)1415PAGE ELEMENTS:16 - Album art Image17 - Title and artist Text elements18 - Play/Pause button (icon toggles)19 - Previous / Next buttons20 - Progress bar (Group container + fill Group)21 - Time display (current / total)22 - Volume SliderInput23 - Playlist Repeating Group2425WORKFLOW 1: Play/Pause Toggle26 Event: Button Play/Pause clicked27 If is_playing = no → Play audio, set is_playing = yes28 If is_playing = yes → Pause audio, set is_playing = no2930WORKFLOW 2: Next Track31 Event: Button Next clicked32 1. Find Track where track_number = current + 133 2. Set current_track = result34 3. Set audio source = new track's audio_file35 4. Play audio3637WORKFLOW 3: Previous Track38 Same as Next but track_number = current - 13940WORKFLOW 4: Select from Playlist41 Event: Track in Repeating Group clicked42 1. Set current_track = clicked track43 2. Play audio4445WORKFLOW 5: Seek46 Event: Progress bar Group clicked47 1. Calculate position = click X / bar width * duration48 2. Set audio current time = position4950WORKFLOW 6: Volume Change51 Event: SliderInput value changed52 Action: Set audio volume = slider value / 100Common mistakes when implementing an audio player in Bubble.io: Step-by-Step Guide
Why it's a problem: Not handling autoplay browser restrictions
How to avoid: Always require a user click (play button) to initiate audio. Never assume audio will autoplay.
Why it's a problem: Using large uncompressed audio files
How to avoid: Compress audio files to MP3 at 128-192kbps before uploading. This balances quality with file size.
Why it's a problem: Not resetting the progress bar when changing tracks
How to avoid: In the track change workflow, reset the current_time Custom State to 0 and update the progress bar before starting playback.
Best practices
- Use MP3 format for broad browser compatibility
- Compress audio to 128-192kbps for web delivery
- Always require user interaction before playing audio (browser autoplay policy)
- Reset progress bar and time display when changing tracks
- Highlight the currently playing track in the playlist
- Add keyboard shortcuts (space for play/pause) for better accessibility
- Show a loading state while audio buffers
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a custom audio player in Bubble.io with play/pause, seek bar, volume control, playlist, and album art display. What plugin should I use, and how do I structure the data types, custom states, and workflows?
Add an audio player to my app. I need a Track data type, a player with play/pause/next/previous controls, a progress bar, volume slider, album art display, and a playlist Repeating Group that highlights the current track.
Frequently asked questions
Which audio formats does Bubble support?
Bubble can store any file type. For playback, use MP3 for broadest browser compatibility. WAV and OGG also work in most modern browsers. Avoid FLAC for web playback.
Can I stream audio instead of downloading the full file?
HTML5 audio elements stream by default — they begin playback before the full file is downloaded. For very large files, ensure your audio is served with proper HTTP range headers.
Does the player keep playing when navigating to another page?
No. Navigating to a new page stops playback. To maintain playback across pages, place the player in a Reusable Element (Floating Group) that persists across page changes, or use a single-page app architecture.
Can I add playback speed control?
Yes. HTML5 audio supports playback rate changes. Use a JavaScript action or plugin setting to adjust the playbackRate property (0.5x, 1x, 1.5x, 2x).
How do I handle audio file storage limits?
Bubble's free plan includes 0.5GB storage. Audio files can be large — a 5-minute MP3 at 192kbps is about 7MB. For apps with many tracks, consider hosting audio on an external CDN like Cloudflare R2 or AWS S3.
Can RapidDev help build advanced audio features?
Yes. RapidDev can help implement features like waveform visualization, audio recording, real-time streaming, transcription, and integration with music distribution APIs.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation