diff --git a/db/migrations/20260104203627_playlist_case_insensitive_name.sql b/db/migrations/20260104203627_playlist_case_insensitive_name.sql
new file mode 100644
index 00000000..64b079cc
--- /dev/null
+++ b/db/migrations/20260104203627_playlist_case_insensitive_name.sql
@@ -0,0 +1,99 @@
+-- +goose Up
+-- Fix case-insensitive sorting for playlist names
+create table playlist_dg_tmp
+(
+ id varchar(255) not null
+ primary key,
+ name varchar(255) collate NOCASE default '' not null,
+ comment varchar(255) default '' not null,
+ duration real default 0 not null,
+ song_count integer default 0 not null,
+ public bool default FALSE not null,
+ created_at datetime,
+ updated_at datetime,
+ path string default '' not null,
+ sync bool default false not null,
+ size integer default 0 not null,
+ rules varchar,
+ evaluated_at datetime,
+ owner_id varchar(255) not null
+ constraint playlist_user_user_id_fk
+ references user
+ on update cascade on delete cascade
+);
+
+insert into playlist_dg_tmp(id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size,
+ rules, evaluated_at, owner_id)
+select id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, rules, evaluated_at,
+ owner_id
+from playlist;
+
+drop table playlist;
+
+alter table playlist_dg_tmp
+ rename to playlist;
+
+create index playlist_name
+ on playlist (name);
+
+create index playlist_created_at
+ on playlist (created_at);
+
+create index playlist_updated_at
+ on playlist (updated_at);
+
+create index playlist_evaluated_at
+ on playlist (evaluated_at);
+
+create index playlist_size
+ on playlist (size);
+
+-- +goose Down
+-- Note: Downgrade loses the collation but preserves data
+create table playlist_dg_tmp
+(
+ id varchar(255) not null
+ primary key,
+ name varchar(255) default '' not null,
+ comment varchar(255) default '' not null,
+ duration real default 0 not null,
+ song_count integer default 0 not null,
+ public bool default FALSE not null,
+ created_at datetime,
+ updated_at datetime,
+ path string default '' not null,
+ sync bool default false not null,
+ size integer default 0 not null,
+ rules varchar,
+ evaluated_at datetime,
+ owner_id varchar(255) not null
+ constraint playlist_user_user_id_fk
+ references user
+ on update cascade on delete cascade
+);
+
+insert into playlist_dg_tmp(id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size,
+ rules, evaluated_at, owner_id)
+select id, name, comment, duration, song_count, public, created_at, updated_at, path, sync, size, rules, evaluated_at,
+ owner_id
+from playlist;
+
+drop table playlist;
+
+alter table playlist_dg_tmp
+ rename to playlist;
+
+create index playlist_name
+ on playlist (name);
+
+create index playlist_created_at
+ on playlist (created_at);
+
+create index playlist_updated_at
+ on playlist (updated_at);
+
+create index playlist_evaluated_at
+ on playlist (evaluated_at);
+
+create index playlist_size
+ on playlist (size);
diff --git a/persistence/collation_test.go b/persistence/collation_test.go
index 7e114475..bb127657 100644
--- a/persistence/collation_test.go
+++ b/persistence/collation_test.go
@@ -32,6 +32,7 @@ var _ = Describe("Collation", func() {
Entry("media_file.sort_title", "media_file", "sort_title"),
Entry("media_file.sort_album_name", "media_file", "sort_album_name"),
Entry("media_file.sort_artist_name", "media_file", "sort_artist_name"),
+ Entry("playlist.name", "playlist", "name"),
Entry("radio.name", "radio", "name"),
Entry("user.name", "user", "name"),
)
@@ -53,6 +54,7 @@ var _ = Describe("Collation", func() {
Entry("media_file.sort_album_name", "media_file", "coalesce(nullif(sort_album_name,''),order_album_name) collate nocase"),
Entry("media_file.sort_artist_name", "media_file", "coalesce(nullif(sort_artist_name,''),order_artist_name) collate nocase"),
Entry("media_file.path", "media_file", "path collate nocase"),
+ Entry("playlist.name", "playlist", "name collate nocase"),
Entry("radio.name", "radio", "name collate nocase"),
Entry("user.user_name", "user", "user_name collate nocase"),
)
diff --git a/ui/src/playlist/PlaylistList.jsx b/ui/src/playlist/PlaylistList.jsx
index c1856675..eae9d863 100644
--- a/ui/src/playlist/PlaylistList.jsx
+++ b/ui/src/playlist/PlaylistList.jsx
@@ -170,6 +170,7 @@ const PlaylistList = (props) => {
}
actions={}
bulkActionButtons={!isXsmall && }