diff --git a/webui/static/docs.js b/webui/static/docs.js
index 176ab088..aaaa1d43 100644
--- a/webui/static/docs.js
+++ b/webui/static/docs.js
@@ -3,14 +3,37 @@
// ===============================
function docsImg(src, alt) {
- return ``;
+ return `
SoulSync is a self-hosted music download, sync, and library management platform. It connects to Spotify, Apple Music/iTunes, Tidal, Qobuz, YouTube, and Beatport for metadata, and uses Soulseek (via slskd) as the primary download source. Your library is served through Plex, Jellyfin, or Navidrome.
- ${docsImg('gs-overview.png', 'SoulSync dashboard overview')} + ${docsImg('gs-overview.jpg', 'SoulSync dashboard overview')}Search and download tracks in FLAC, MP3, and more from Soulseek, YouTube, Tidal, or Qobuz, with automatic metadata tagging and file organization.
Mirror playlists from Spotify, YouTube, Tidal, and Beatport. Discover official metadata and sync to your media server.
Version & Updates: Click the version number in the sidebar footer to open the What's New modal, which shows detailed release notes for every feature and fix. SoulSync automatically checks for updates by comparing your running version against the latest GitHub commit. If an update is available, a banner appears in the modal. Docker users are notified when a new image has been pushed to the repo.
/app/StagingIn Docker, every app runs in its own isolated container with its own filesystem. Volume mounts in docker-compose create "bridges" between your host folders and the container. But SoulSync doesn't automatically know where those bridges go — you have to tell it via the Settings page.
Here's what happens with a properly configured setup:
@@ -215,7 +239,7 @@ const DOCS_SECTIONS = [# Download Path: /app/downloads# Transfer Path: /app/Transfer
Go through every item. If you miss any single one, the pipeline will break:
@@ -296,7 +320,7 @@ const DOCS_SECTIONS = [ { id: 'workflows', title: 'Quick Start Workflows', - icon: '/static/help.png', + icon: '/static/help.jpg', children: [ { id: 'wf-first', title: 'What Should I Do First?' }, { id: 'wf-download', title: 'How to: Download an Album' }, @@ -430,7 +454,7 @@ const DOCS_SECTIONS = [ { id: 'dashboard', title: 'Dashboard', - icon: '/static/dashboard.png', + icon: '/static/dashboard.jpg', children: [ { id: 'dash-overview', title: 'Overview & Stats' }, { id: 'dash-workers', title: 'Enrichment Workers' }, @@ -445,7 +469,7 @@ const DOCS_SECTIONS = [The dashboard is your command center. At the top you'll see service status indicators for Spotify, your media server, and Soulseek — showing connected/disconnected state at a glance. Below that, stat cards display your library totals: artists, albums, tracks, and total library size.
Stats update in real-time via WebSocket — no page refresh needed.
- ${docsImg('dash-overview.png', 'Dashboard overview')} + ${docsImg('dash-overview.jpg', 'Dashboard overview')}Tidal IDs, artist images, album labels, explicit flags, ISRCs
Qobuz IDs, artist images, album labels, genres, explicit flags
Rate Limit Protection: Workers include smart rate limiting for all APIs. If Spotify returns a rate limit with a Retry-After greater than 60 seconds, the app seamlessly switches to iTunes/Apple Music — an amber indicator appears in the sidebar, searches automatically use Apple Music, and the enrichment worker pauses. When the ban expires, everything recovers automatically. No action needed from the user.
@@ -481,7 +505,7 @@ const DOCS_SECTIONS = [The retag operation writes title, artist, album artist, album, track number, disc number, year, and genre. Cover art can optionally be re-embedded.
The system automation Auto-Backup Database creates a backup every 3 days automatically. You can adjust the interval in Automations.
The Sync page lets you import playlists from Spotify, YouTube, Tidal, and Beatport. Once imported, playlists are mirrored — they persist in your SoulSync instance and can be refreshed, discovered, and synced to your wishlist for downloading.
- ${docsImg('sync-overview.png', 'Playlist sync page')} + ${docsImg('sync-overview.jpg', 'Playlist sync page')}Paste a YouTube playlist URL into the input field and click Parse Playlist. SoulSync extracts the track list and attempts to match each track to official Spotify/iTunes metadata.
- ${docsImg('sync-youtube.png', 'YouTube playlist import')} + ${docsImg('sync-youtube.jpg', 'YouTube playlist import')}Genre Browser — Browse 12+ electronic music genres (House, Techno, Drum & Bass, Trance, etc.) with per-genre views: Top 10 tracks, staff picks, hype rankings, latest releases, and new charts.
Charts — Top 100 and Hype charts with full track listings. Each track can be manually matched against Spotify for metadata, then synced and downloaded.
- ${docsImg('sync-beatport.png', 'Beatport genre browser')} + ${docsImg('sync-beatport.jpg', 'Beatport genre browser')}Toggle to Basic Search mode for direct Soulseek queries. This shows raw search results with detailed info: format, bitrate, quality score, file size, uploader name, upload speed, and availability.
Filters let you narrow results by type (Albums/Singles), format (FLAC/MP3/OGG/AAC/WMA), and sort by relevance, quality, size, bitrate, duration, or uploader speed.
- ${docsImg('dl-basic-search.png', 'Basic Soulseek search')} + ${docsImg('dl-basic-search.jpg', 'Basic Soulseek search')}Downloads can be started from multiple places: Enhanced Search results, artist discography, Download Missing modal, wishlist auto-processing, and playlist sync.
Download Candidate Selection: If a download fails or no suitable source is found, you can view the cached search candidates and manually pick an alternative file from a different user. This lets you recover failed downloads without restarting the entire search.
- ${docsImg('dl-candidates.png', 'Download candidate selection')} + ${docsImg('dl-candidates.jpg', 'Download candidate selection')}Each format has configurable bitrate ranges and a priority order. Enable Fallback to accept any quality when preferred formats aren't available.
- ${docsImg('dl-quality-profiles.png', 'Quality profile settings')} + ${docsImg('dl-quality-profiles.jpg', 'Quality profile settings')}Each playlist can be played in the media player, downloaded, or synced to your media server.
Genre Browser — Filter discovery pool content by specific genres. Browse available genres and view top tracks within each genre category.
+ ${docsImg('disc-genre-browser.jpg', 'Genre browser')}ListenBrainz Playlists — If ListenBrainz is configured, the Discover page also shows personalized playlists generated from your listening history: Created For You, Your Playlists, and Collaborative playlists.
Search for 1–5 artists, select them, and click Generate to create a custom playlist from their catalogs. You can then download or sync the generated playlist.
- ${docsImg('disc-build-playlist.png', 'Build custom playlist')} + ${docsImg('disc-build-playlist.jpg', 'Build custom playlist')}Browse discovery pool content by decade — tabs from the 1950s through the 2020s. Each decade pulls top tracks from pool artists active in that era.
- ${docsImg('disc-time-machine.png', 'Time Machine decade browser')} + ${docsImg('disc-time-machine.jpg', 'Time Machine decade browser')}Search for any artist by name. Results show artist cards with images and genres. Results come from Spotify (or iTunes as fallback). Click any card to open the artist detail view.
- ${docsImg('art-search.png', 'Artist search results')} + ${docsImg('art-search.jpg', 'Artist search results')}At the top, View on buttons link to the artist on each matched external service (Spotify, Apple Music, MusicBrainz, Deezer, AudioDB, Last.fm, Genius, Tidal, Qobuz). Service badges on artist cards also indicate which services have matched this artist.
Similar Artists appear as clickable bubbles below the discography for further exploration and discovery.
- ${docsImg('art-detail.png', 'Artist detail page')} + ${docsImg('art-detail.jpg', 'Artist detail page')}Manual Processing: Use the Process Wishlist automation action to trigger processing on demand. Options include processing all items, albums only, or singles only.
Cleanup: The Cleanup Wishlist action removes duplicates (same track added multiple times) and items you already own in your library.
Automations let you schedule tasks and react to events with a visual WHEN → DO → THEN builder. Create custom workflows like "When a download completes, update the database, then notify me on Discord."
Each automation card shows its trigger/action flow, last run time, next scheduled run (with countdown), and a Run Now button for instant execution.
- ${docsImg('auto-overview.png', 'Automations page')} + ${docsImg('auto-overview.jpg', 'Automations page')}Add Conditions to filter when the automation runs. Match modes: All (AND) or Any (OR). Operators: contains, equals, starts_with, not_contains.
- ${docsImg('auto-builder.png', 'Automation builder')} + ${docsImg('auto-builder.jpg', 'Automation builder')}Use the Run Now button on any automation card to execute it immediately, regardless of its schedule. The result (success/failure) updates in real-time on the card. Running automations display a glow effect on their card.
Stall detection: If an automation action runs for more than 2 hours without completing, it is automatically flagged as stalled and terminated to prevent resource leaks.
The Dashboard activity feed also logs every automation execution with timestamps, so you can review the full history of what ran and when.
- ${docsImg('auto-history.png', 'Automation execution history')} + ${docsImg('auto-history.jpg', 'Automation execution history')}The Library page shows all artists in your collection as cards with images, album/track counts, and service badges (Spotify, MusicBrainz, Deezer, AudioDB, iTunes, Last.fm, Genius, Tidal, Qobuz) indicating which services have matched this artist.
Use the search bar, alphabet navigation (A–Z, #), and watchlist filter (All/Watched/Unwatched) to browse. Click any artist card to view their discography.
The artist detail page shows albums, EPs, and singles as cards with completion percentages. Filter by category, content type (live/compilations/featured), or status (owned/missing). At the top, View on buttons link to the artist on each matched external service.
- ${docsImg('lib-standard.png', 'Library artist grid')} + ${docsImg('lib-standard.jpg', 'Library artist grid')}Supports MP3, FLAC, OGG, and M4A via Mutagen. After writing, optional server sync pushes metadata to Plex (per-track update), Jellyfin (library scan), or Navidrome (auto-detects).
Set your staging folder path in Settings → Download Settings. Place audio files you want to import into this folder. SoulSync scans the folder and detects albums from the file structure.
Place albums in subfolders (e.g., Artist - Album/) and loose singles at the root level.
The import page header shows the total files in staging and their combined size.
- ${docsImg('imp-staging.png', 'Import staging page')} + ${docsImg('imp-staging.jpg', 'Import staging page')}The sidebar media player is always visible when a track is loaded. It shows album art, track info, a seekable progress bar, and playback controls (play/pause, previous, next, volume, repeat, shuffle).
+ ${docsImg('player-sidebar.jpg', 'Sidebar media player')}Click the sidebar player to open the Now Playing modal — a full-screen experience with large album art, ambient glow (dominant color from cover art), a frequency-driven audio visualizer, and expanded controls.
- ${docsImg('player-nowplaying.png', 'Now Playing modal')} + ${docsImg('player-nowplaying.jpg', 'Now Playing modal')}Add tracks to the queue from the Enhanced Library Manager or download results. Manage the queue in the Now Playing modal: reorder, remove individual tracks, or clear all.
Smart Radio mode (toggle in queue header) automatically adds similar tracks when the queue runs out, based on genre, mood, style, and artist similarity. Playback continues seamlessly.
Repeat modes: Off → Repeat All (loop queue) → Repeat One. Shuffle randomizes the next track from the remaining queue.
- ${docsImg('player-queue.png', 'Queue panel')} + ${docsImg('player-queue.jpg', 'Queue panel')}The media player streams audio directly from your connected server — tracks play through your Plex, Jellyfin, or Navidrome instance without needing local file access.
/app/downloads, /app/Transfer). Never use host paths like /mnt/music — the container can't access those. Your docker-compose volumes section is where host paths are mapped to container paths. See Getting Started → Folder Setup for a complete walkthrough.PINs are 4-6 digits. If you forget your PIN, the admin can reset it from Manage Profiles. The admin PIN protects settings and destructive operations when multiple profiles exist.
- ${docsImg('profiles-picker.png', 'Profile picker')} + ${docsImg('profiles-picker.jpg', 'Profile picker')} + ${docsImg('profiles-create.jpg', 'Profile creation')}If the admin removes a page that was set as a user's home page, the home page automatically resets. Navigation guards prevent users from accessing restricted pages even via direct URL or browser history.