A Spotify browser overlay for Home Assistant dashboards, with responsive desktop, mobile, and 10-inch tablet layouts.
Important
Spotify Browser requires the custom SpotifyPlus
integration and a configured SpotifyPlus media_player entity.
- Home Assistant with a Lovelace dashboard using YAML-accessible root configuration.
- SpotifyPlus installed, authenticated, and exposing the configured
media_player. - One—and only one—Spotify Browser JavaScript resource registered in Home Assistant.
- A modern browser, Home Assistant Companion WebView, or Fully Kiosk Browser.
- For automatic opening, a dedicated Lovelace view whose URL matches
spotify_browser.auto_open.pathexactly.
After replacing the JavaScript resource, fully reload the frontend. Android WebViews may retain registered custom elements until the app process is restarted.
Galaxy Tab A9/A10-class touch tablets use the desktop information architecture above 768px, with tablet-specific sizing between 769px and 1180px. The browser uses more of the viewport, album art and the queue sidebar are capped, device rows retain comfortable touch targets, and nested lists use momentum scrolling. These rules only apply to coarse pointers, so laptop layouts at the same width are unchanged.
- Open HACS in Home Assistant.
- Click the three dots in the top-right corner and select Custom repositories.
- Add
https://github.com/biggiebytes/HA-Spotify-Browserunder Repository and select Lovelace as the Category. - Click Add, then find and install the Spotify Browser card.
- HACS will automatically register the dashboard resource.
- Copy
spotify-browser.jsto your Home Assistantwww/directory. - Register the resource in your Lovelace dashboard configuration:
resources:
- url: /local/spotify-browser.js
type: moduleConfiguration must live at the Lovelace root under spotify_browser:. The
legacy custom:spotify-browser-card is only an invisible compatibility shim
and is not a configuration source or launcher.
spotify_browser:
entity: media_player.spotify_user
auto_open:
enabled: true
path: /dashboard-music/spotify-browser
homeonexit:
timeout: 300
cache_size: 15| Key | Type | Default | Description |
|---|---|---|---|
entity |
string | none | The primary Spotify media_player entity. |
spotify_accounts |
list | none | List of accounts for multi-user switching. |
homeonexit |
boolean / object | true |
Reset view to home screen on close. Supports timeout (seconds). |
device_playback |
object | none | Device helper (input_select), default volumes, and volume rules. |
queue |
object | none | Mini-player buttons and desktop sidebar visibility. |
cache_size |
number | 10 |
Maximum pages retained in history. |
performance |
string | auto |
Rendering profile: auto, high (full animations), or low (optimized). |
animations |
object | none | Configures transition types (page_transition, browser_open, blur). |
storage |
object | none | Entities and scripts used for persistent pinned items/device settings. |
homescreen |
object | none | Section visibility, ordering, and refresh timers. |
advanced |
object | none | Last.fm-based radio track generation and similar artist configurations. |
external_providers |
object | none | Integration credentials for external metadata services. |
auto_close_seconds |
number | 0 |
Closes browser automatically after inactive seconds. 0 disables. |
auto_open |
boolean / object | false |
Opens after initialization. For a dedicated dashboard view, use { enabled: true, path: /dashboard-name/spotify }. |
auto_open_path |
string | none | Path alias for auto_open.path; a final view slug such as spotify is also accepted. |
closeondisconnect |
boolean | true |
Closes the browser interface if connection to Home Assistant is lost. |
custom_hash |
string | #spotify-browser |
URL hash that triggers the browser layout. |
desktop_style |
object | none | Dimensions, margins, and sizing modes for desktop viewports. |
Controls browser state reset on close/reopen. Can be true (always reset to Home), false (remember last page forever), or an object:
timeout(number): Remembers last page for N seconds, then resets to Home.
helper/device_manager(string): Entity ID of aninput_selecthelper to store and persist selected devices.hide(list): Device names to filter out of the device picker.show(list): Device names to explicitly include in the picker.default/default_device(string): Device ID to use as a fallback.volume(object): Time-based volume levels and slider parameters:default(number / object): Fallback volume (e.g.25), or an object containing:fallback(number): Default volume used when no rules match.rules(list): Time-based rules containingstart(HH:MM),end(HH:MM), andlevel(0-100 percentage).
slider(object): Volume slider behavior:rate_control(boolean): Throttle volume service calls (default:true).optimistic(boolean): Update UI volume slider state immediately (default:true).
Saved default devices are validated against a fresh SpotifyPlus device scan before idle playback starts. If an Echo or other Spotify Connect target is not currently online, the card asks for another device instead of silently sending playback to a stale device ID. Device transfers remain open until SpotifyPlus confirms success, so an unavailable target can be refreshed and retried.
Echo devices can disappear from Spotify Connect after standby, a network change, or a Spotify account/session restart. When that happens:
- Wake the Echo and ask it to play Spotify once if it is absent from Spotify's own device list.
- Open Connect, choose Manage & refresh devices, then refresh the scan.
- Confirm the Echo is signed into the same Spotify account used by the configured SpotifyPlus entity.
- If Home Assistant or SpotifyPlus was restarted, wait for the media-player entity to become available before retrying. The card resynchronizes after the Home Assistant connection is ready and does not scan during reconnect.
An Echo shown as saved but offline is retained for later use; it is not treated as an active playback target until SpotifyPlus reports it online again.
desktop(object): Desktop viewport settings:open_init(boolean): Open the queue sidebar panel automatically when the browser opens (default:false).miniplayer(boolean / object): Iftrue, enables the mini-player. Or configure buttons individually:shuffle,previous,next,like,volume,device(boolean).
cache(boolean): Cache homescreen data for faster loads (default:true).expiry(number): Expiry window in minutes before refreshing cached data (default:60).sort(list): Section sorting order. Allowed items:pinned,recently played,followed_artists,favourite_playlists,favourite_albums,made_for_you.sticky(object): Configures pinned elements:helper/pinned_items_entity(string): Entity ID of aninput_selecthelper to persist pins.limit(number): Maximum number of pinned items to display (default:10).
madeforyou(list / object): If object, supports:content/items(list): Custom playlists/albums.pills/desktop_pills(boolean): Enable genre pills styling on desktop.
similar_artists(object):provider(string): External metadata provider (e.g.,'lastfm').limit(number): Max recommendations to fetch (default:10).
radio_track(object):enabled(boolean): Generates a custom track radio when playing.provider(string): Metadata provider (e.g.,'lastfm').limit(number): Maximum radio track queue size (default:30).dontstopthemusic(boolean): Continues track radio play indefinitely.
mode(string): Dialog sizing method ('default','fixed','fullscreen').width(string): Width in CSS units (e.g.'1000px').height(string): Height in CSS units (e.g.'700px').margin(string): Margin around the window on desktop viewports.margin_top,margin_bottom,margin_left,margin_right(string): Individual overrides.
To enable pinning items and saving device settings, configure a template sensor in your configuration.yaml and a helper script in your scripts.yaml.
template:
- trigger:
- platform: event
event_type: spotify_browser_store_data
sensor:
- name: Spotify Browser Data
unique_id: spotify_browser_data
state: "{{ now().timestamp() | int }}"
attributes:
data: "{{ trigger.event.data.data | to_json }}"spotify_browser_store:
alias: Spotify Browser Store Data
mode: queued
fields:
data:
description: Full data object to persist
sequence:
- condition: template
value_template: "{{ data is mapping }}"
- event: spotify_browser_store_data
event_data:
data: "{{ data }}"spotify_browser:
entity: media_player.spotify_user
storage:
sensor_entity: sensor.spotify_browser_data
event_type: spotify_browser_store_data
write_script: script.spotify_browser_storeYou can configure multiple Spotify accounts and switch between them within the interface:
spotify_browser:
spotify_accounts:
- name: "User A"
entity: media_player.spotify_user_a
default: true
hash: "#user-a"
- name: "User B"
entity: media_player.spotify_user_b
hash: "#user-b"Keep configuration at the Lovelace root; the dedicated view does not need a
custom:spotify-browser-card. Route-scoped auto-open is recommended so other
dashboard views remain unaffected:
spotify_browser:
entity: media_player.spotify_user
auto_open:
enabled: true
path: /dashboard-music/spotify-browserNavigating to that path opens the inset modal. Closing it with X or the backdrop restores the previously visited dashboard route. The route is dismissed until the user navigates away, preventing a Lovelace re-render from reopening it. Cold startup is reconciled while Home Assistant and Lovelace initialize, so the view does not depend on a launcher card or pull-to-refresh.
auto_open: true is also supported, but opens on every route where this resource
and root configuration are loaded; route-scoped configuration is safer.
Browser Mod is not required. Spotify Browser can coexist with Browser Mod when both are loaded once as normal Lovelace resources. Do not wrap Spotify Browser inside a Browser Mod popup: Spotify Browser already owns its backdrop, focus, close handling, and responsive modal geometry. Avoid registering duplicate Spotify Browser resources or manually loading Browser Mod's internal chunks.
Open the browser using URL hashes or JavaScript window events.
Navigate or link directly to these hashes:
#spotify-browser- Opens the main browser#spotify-browser-now-playing- Opens the now playing view on mobile#user-a- Opens the browser and switches to the specified account
Trigger the browser programmatically:
// Open the browser
window.dispatchEvent(new CustomEvent('spotify-browser-open'));
// Open directly to mobile now-playing screen
window.dispatchEvent(new CustomEvent('spotify-browser-open-now-playing'));Below is the contents of the root spotify_browser: mapping demonstrating the
available options. Add spotify_browser: above it and indent the block by two
spaces when pasting it into dashboard YAML.
entity: media_player.spotify_user
homeonexit:
timeout: 300 # 5 minutes
device_playback:
helper: input_select.spotify_browser_device_manager
hide:
- "Living Room Speaker"
show:
- "Kitchen Speaker"
default: "speaker_kitchen"
volume:
default:
fallback: 25
rules:
- start: '09:00'
end: '17:00'
level: '35'
- start: '22:00'
end: '07:00'
level: '15'
slider:
rate_control: true
optimistic: true
queue:
- desktop:
open_init: true
miniplayer:
shuffle: true
previous: true
next: true
like: true
volume: true
device: true
cache_size: 15
performance: auto
animations:
page_transition: fade # 'fade', 'slide', 'none'
browser_open: fade
blur: true
spotify_accounts:
- name: "Bryce"
entity: media_player.spotify_bryce
default: true
hash: "#bryce"
image: "/local/spotify/bryce.jpg"
- name: "Alice"
entity: media_player.spotify_alice
hash: "#alice"
storage:
sensor_entity: sensor.spotify_browser_data
event_type: spotify_browser_store_data
write_script: script.spotify_browser_store
homescreen:
cache: true
expiry: 60 # minutes
sticky:
helper: input_select.spotify_pinned_items
limit: 10
madeforyou:
content:
- id: "37i9dQZF1DXcBWIGoYBM5M"
title: "Top Hits"
type: "playlist"
desktop_pills: true
sort:
- pinned
- recently played
- made_for_you
- favourite_playlists
- followed_artists
- favourite_albums
advanced:
radio_track:
enabled: true
provider: "lastfm"
limit: 30
dontstopthemusic: true
similar_artists:
provider: "lastfm"
limit: 10
external_providers:
lastfm:
api_key: "YOUR_LASTFM_API_KEY"
auto_close_seconds: 0
closeondisconnect: true
custom_hash: "#spotify-browser"
desktop_style:
mode: fixed
width: 1000px
height: 700px
fullscreen: false
margin: 32pxTest both portrait and landscape on the target tablet (the Home Assistant app and the kiosk browser, if both are used):
- Open Home, Library, Search, a long playlist, and Now Playing. Confirm only the intended content pane scrolls and horizontal carousels do not drag the page.
- Open and close the on-screen keyboard from Search. Confirm the app keeps its pre-keyboard height and the search field remains visible.
- With Spotify idle, play a track and select an online Echo. Confirm the picker stays visible on failure and closes only after a successful transfer.
- Put the tablet to sleep for at least 30 seconds, wake it, and confirm player state refreshes without a connection-lost toast.
- Unplug or disable the selected Echo, refresh devices, and confirm it is shown offline (when saved) and is not auto-selected as the default.
- Check that album art, device rows, footer actions, and queue controls fit without clipping at 800px, 1200px, and 1340px viewport dimensions.



