diff --git a/main.go b/main.go
index e824dbb..40e57b2 100644
--- a/main.go
+++ b/main.go
@@ -58,7 +58,12 @@ func main() {
 				continue
 			}
 
+			server.Documents.Lock()
+
 			var entries []QueueEntry
+			if len(server.Documents.Documents) > 0 {
+				entries = append(entries, QueueEntry{ID: NewQueueEntryID(), QueueEntryData: QueueEntryDataSeparator{}})
+			}
 			for _, page := range docPages {
 				entries = append(entries, QueueEntry{
 					ID:             NewQueueEntryID(),
@@ -66,9 +71,7 @@ func main() {
 					QueueEntryData: QueueEntryDataPage{Page: &page},
 				})
 			}
-			entries = append(entries, QueueEntry{ID: NewQueueEntryID(), QueueEntryData: QueueEntryDataSeparator{}})
 
-			server.Documents.Lock()
 			server.Documents.Append(entries...)
 			server.Documents.Unlock()
 		}
diff --git a/queue.go b/queue.go
index 0569f68..87fbe9c 100644
--- a/queue.go
+++ b/queue.go
@@ -171,15 +171,38 @@ func (d *Queue) Shift(offset int, ids ...QueueEntryID) {
 	}
 }
 
+// Split will add a separator behind every queue entry with the given IDs.
+//
+// The Queue must be locked when calling this.
+func (d *Queue) Split(ids ...QueueEntryID) {
+	for _, id := range ids {
+		if i := slices.IndexFunc(d.Documents, func(e QueueEntry) bool { return e.ID == id }); i >= 0 && i < len(d.Documents)-1 {
+			doc := &d.Documents[i]
+
+			switch d.Documents[i+1].QueueEntryData.(type) {
+			case QueueEntryDataPage:
+			default:
+				// If the next entry is not a page, we will not put a separator here.
+				continue
+			}
+
+			switch doc.QueueEntryData.(type) {
+			case QueueEntryDataPage:
+				d.InsertAt(i+1, QueueEntry{
+					ID:             NewQueueEntryID(),
+					QueueEntryData: QueueEntryDataSeparator{},
+				})
+			}
+		}
+	}
+}
+
 // QueueEntryByID returns the QueueEntry with the given ID.
 //
 // The Queue must be locked when calling this.
 func (d *Queue) QueueEntryByID(id QueueEntryID) *QueueEntry {
-	for i := range d.Documents {
-		document := &d.Documents[i]
-		if document.ID == id {
-			return document
-		}
+	if i := slices.IndexFunc(d.Documents, func(e QueueEntry) bool { return e.ID == id }); i >= 0 {
+		return &d.Documents[i]
 	}
 
 	return nil
diff --git a/server-websocket-packets.go b/server-websocket-packets.go
index 7363436..88e4c5e 100644
--- a/server-websocket-packets.go
+++ b/server-websocket-packets.go
@@ -51,7 +51,7 @@ func init() { ServerWebsocketPacketRegister(&ServerWebsocketPacketQueueShiftAt{}
 
 // ServerWebsocketPacketQueueShift represents a shift operation on a document queue list.
 type ServerWebsocketPacketQueueShift struct {
-	IDs    []QueueEntryID `json:"ids"`    // IDs of the documents.
+	IDs    []QueueEntryID `json:"ids"`    // IDs of the entries.
 	Offset int            `json:"offset"` // Shift offset.
 }
 
@@ -59,8 +59,8 @@ func (s *ServerWebsocketPacketQueueShift) Type() string { return "QueueShift" }
 
 func init() { ServerWebsocketPacketRegister(&ServerWebsocketPacketQueueShift{}) }
 
-// ServerWebsocketPacketQueueUpdate represents an update operation of documents in a queue list.
-// The receiver should update any of the received documents in their local queue list.
+// ServerWebsocketPacketQueueUpdate represents an update operation of entries in a queue list.
+// The receiver should update any of the received entries in their local queue list.
 type ServerWebsocketPacketQueueUpdate struct {
 	Documents []QueueEntry `json:"documents"`
 }
@@ -68,3 +68,13 @@ type ServerWebsocketPacketQueueUpdate struct {
 func (s *ServerWebsocketPacketQueueUpdate) Type() string { return "QueueUpdate" }
 
 func init() { ServerWebsocketPacketRegister(&ServerWebsocketPacketQueueUpdate{}) }
+
+// ServerWebsocketPacketQueueSplit represents a "add separator" operation in a queue list.
+// The split is added behind the given entry IDs.
+type ServerWebsocketPacketQueueSplit struct {
+	IDs []QueueEntryID `json:"ids"` // IDs of the entries.
+}
+
+func (s *ServerWebsocketPacketQueueSplit) Type() string { return "QueueSplit" }
+
+func init() { ServerWebsocketPacketRegister(&ServerWebsocketPacketQueueSplit{}) }
diff --git a/server-websocket.go b/server-websocket.go
index 594858c..d1e1fd9 100644
--- a/server-websocket.go
+++ b/server-websocket.go
@@ -92,6 +92,10 @@ func (s *Server) handleWebSocket(w http.ResponseWriter, r *http.Request) {
 				s.Documents.Lock()
 				s.Documents.Shift(packet.Offset, packet.IDs...)
 				s.Documents.Unlock()
+			case *ServerWebsocketPacketQueueSplit:
+				s.Documents.Lock()
+				s.Documents.Split(packet.IDs...)
+				s.Documents.Unlock()
 			default:
 				log.Printf("Websocket client %q sent unsupported packet type %T.", conn.LocalAddr(), prototype)
 				return
diff --git a/static/js/api.js b/static/js/api.js
index e3d8a24..6b45bb8 100644
--- a/static/js/api.js
+++ b/static/js/api.js
@@ -96,6 +96,20 @@ export class API extends EventTarget {
 		this.#socket.send(JSON.stringify(message));
 	}
 
+	/**
+	 * Sends a document queue split request to the server.
+	 * @param {...number} ids Document ids.
+	 */
+	queueSplit(...ids) {
+		if (this.#socket.readyState !== WebSocket.OPEN) {
+			return
+		}
+
+		/** @type {{type: string, payload: import("./model").APIPacketQueueSplit}} */
+		const message = { type: "QueueSplit", payload: { ids: ids } };
+		this.#socket.send(JSON.stringify(message));
+	}
+
 	/**
 	 * 
 	 * @param {"GET"|"POST"|"DELETE"|"UPDATE"} method 
diff --git a/static/js/components/document-queue-entry-page.js b/static/js/components/document-queue-entry-page.js
index a588d93..8b09642 100644
--- a/static/js/components/document-queue-entry-page.js
+++ b/static/js/components/document-queue-entry-page.js
@@ -14,20 +14,46 @@ export class DocumentQueueEntryPage extends LitElement {
 		/** @type {API} */
 		this.api;
 		/** @type {import('model').APIQueueEntry} */
-		this.document;
+		this.queueEntry;
 	}
 
 	static styles = css`
+		:host {
+			width: 100%;
+			display: flex;
+			justify-content: space-between;
+			gap: 8px;
+		}
+
 		img {
 			width: 128px;
 		}
+
+		#buttons {
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+			gap: 8px;
+		}
+
+		button {
+			padding: 8px;
+		}
 	`;
 
 	// @ts-ignore
 	render() {
 		return html`
-			<img id="image" src=${`/api/queue-entry-page/${this.document.id}/preview`}></img>
-			<span>This is a document</span>
+			<img id="image" src=${`/api/queue-entry-page/${this.queueEntry.id}/preview`}></img>
+			<div style="flex-grow: 1;">
+				<span>This is a document</span>
+			</div>
+			<div id="buttons">
+				<button @click=${e => this.api.queueShift(-1, this.queueEntry.id)}>▲</button>
+				<button @click=${e => this.api.queueDelete(this.queueEntry.id)}>Delete</button>
+				<button @click=${e => this.api.queueSplit(this.queueEntry.id)}>Split</button>
+				<button @click=${e => this.api.queueShift(1, this.queueEntry.id)}>▼</button>
+			</div>
 		`;
 	}
 }
diff --git a/static/js/components/document-queue-entry-separator.js b/static/js/components/document-queue-entry-separator.js
index ae7f44b..df42ae2 100644
--- a/static/js/components/document-queue-entry-separator.js
+++ b/static/js/components/document-queue-entry-separator.js
@@ -14,20 +14,38 @@ export class DocumentQueueEntrySeparator extends LitElement {
 		/** @type {API} */
 		this.api;
 		/** @type {import('model').APIQueueEntry} */
-		this.document;
+		this.queueEntry;
 	}
 
 	static styles = css`
 		:host {
 			width: 100%;
-			background: black;
+			display: flex;
+			justify-content: space-between;
+			gap: 8px;
+		}
+
+		#buttons {
+			display: flex;
+			flex-direction: column;
+			justify-content: space-between;
+			gap: 8px;
+		}
+
+		button {
+			padding: 8px;
 		}
 	`;
 
 	// @ts-ignore
 	render() {
 		return html`
-			
+			<div style="flex-grow: 1; align-self: center;">
+				<hr>
+			</div>
+			<div id="buttons">
+				<button @click=${e => this.api.queueDelete(this.queueEntry.id)}>Delete</button>
+			</div>
 		`;
 	}
 }
diff --git a/static/js/components/document-queue-entry.js b/static/js/components/document-queue-entry.js
index 10f4522..0806898 100644
--- a/static/js/components/document-queue-entry.js
+++ b/static/js/components/document-queue-entry.js
@@ -61,9 +61,9 @@ export class DocumentQueueEntry extends LitElement {
 		let embeddedElement;
 		switch (this.queueEntry.type) {
 			case "Page":
-				embeddedElement = html`<document-queue-entry-page .document=${this.queueEntry} .api=${this.api}></document-queue-entry-page>`; break;
+				embeddedElement = html`<document-queue-entry-page .queueEntry=${this.queueEntry} .api=${this.api}></document-queue-entry-page>`; break;
 			case "Separator":
-				embeddedElement = html`<document-queue-entry-separator .document=${this.queueEntry} .api=${this.api}></document-queue-entry-separator>`; break;
+				embeddedElement = html`<document-queue-entry-separator .queueEntry=${this.queueEntry} .api=${this.api}></document-queue-entry-separator>`; break;
 			default:
 				embeddedElement = html`<span>Unsupported entry type!</span>`
 		}
@@ -71,7 +71,6 @@ export class DocumentQueueEntry extends LitElement {
 		return html`
 			<div id="left-bar">
 				<input id="checkbox-selected" type="checkbox" .checked=${this.selected} @change=${this.onCheckboxChange}></input>
-				<button id="button-swap" @click=${e => this.api.queueShift(1, this.queueEntry.id)}>⇵</button>
 			</div>
 
 			${embeddedElement}
diff --git a/static/js/model.d.ts b/static/js/model.d.ts
index 55e581c..1288da2 100644
--- a/static/js/model.d.ts
+++ b/static/js/model.d.ts
@@ -33,6 +33,10 @@ export type APIPacketQueueShift = {
 	offset: number;
 }
 
+export type APIPacketQueueSplit = {
+	ids: number[];
+}
+
 export type APIEvents = {
 	queuedeleteat: CustomEvent<APIPacketQueueDeleteAt>;
 	queueinsertat: CustomEvent<APIPacketQueueInsertAt>;