Skip to main content

Overview

The GuildQueueHistory class manages the playback history for a guild queue, allowing you to track previously played tracks and navigate backwards through them. It is accessible via queue.history.

Constructor

new GuildQueueHistory<Meta = any>(queue: GuildQueue<Meta>)
queue
GuildQueue<Meta>
required
The guild queue instance that owns this history manager

Properties

queue
GuildQueue<Meta>
The guild queue instance associated with this history manager
tracks
Queue<Track>
The LIFO (Last In First Out) queue storing track history
currentTrack
Track | null
The currently playing track
nextTrack
Track | null
The next track in the queue
previousTrack
Track | null
The previous track in the history
disabled
boolean
Whether history tracking is disabled for this queue
size
number
The number of tracks stored in history

Methods

isEmpty()

Checks if the history is empty.
history.isEmpty(): boolean
returns
boolean
true if there are no tracks in history, false otherwise
Example:
if (queue.history.isEmpty()) {
  await interaction.reply('No tracks in history!');
}

getSize()

Gets the size of the history.
history.getSize(): number
returns
number
The number of tracks in history
Example:
const historySize = queue.history.getSize();
await interaction.reply(`There are ${historySize} tracks in history`);

push()

Adds one or more tracks to the history.
history.push(track: Track | Track[]): boolean
track
Track | Track[]
required
The track or array of tracks to add to history
returns
boolean
true if tracks were added successfully, false if history is disabled
Example:
// Add single track
queue.history.push(track);

// Add multiple tracks
queue.history.push([track1, track2, track3]);

clear()

Clears all tracks from history.
history.clear(): void
Example:
queue.history.clear();
await interaction.reply('History cleared!');

previous()

Plays the previous track from history.
async previous(preserveCurrent?: boolean): Promise<void>
preserveCurrent
boolean
default:"true"
If true, adds the current track to the front of the queue. If false, the current track is discarded
Example:
try {
  // Play previous track and keep current track in queue
  await queue.history.previous();
  await interaction.reply('Playing previous track!');
} catch (error) {
  await interaction.reply('No previous track available!');
}

// Play previous track without preserving current
await queue.history.previous(false);
Throws:
  • NoResultError if there is no previous track in history

back()

Alias for previous(). Plays the previous track from history.
async back(preserveCurrent?: boolean): Promise<void>
preserveCurrent
boolean
default:"true"
If true, adds the current track to the front of the queue
Example:
// Same as queue.history.previous()
await queue.history.back();

next()

Skips to the next track in the queue.
async next(): Promise<void>
Example:
try {
  await queue.history.next();
  await interaction.reply('Playing next track!');
} catch (error) {
  await interaction.reply('No next track available!');
}
Throws:
  • NoResultError if there is no next track in the queue

resize()

Resizes the history store to respect the maximum history size.
history.resize(): void
This method is automatically called when tracks are added to history. It removes old tracks if the history size exceeds queue.maxHistorySize.

Usage Examples

Basic History Navigation

import { useQueue } from 'discord-player';

export async function handlePrevious(interaction) {
  const queue = useQueue(interaction.guildId);
  
  if (!queue) {
    return interaction.reply('No active queue!');
  }
  
  if (queue.history.isEmpty()) {
    return interaction.reply('No previous tracks!');
  }
  
  try {
    await queue.history.previous();
    await interaction.reply('Playing previous track!');
  } catch (error) {
    await interaction.reply('Failed to play previous track!');
  }
}

Display History

export async function showHistory(interaction) {
  const queue = useQueue(interaction.guildId);
  
  if (!queue) {
    return interaction.reply('No active queue!');
  }
  
  const history = queue.history.tracks.toArray();
  
  if (history.length === 0) {
    return interaction.reply('No tracks in history!');
  }
  
  const historyList = history
    .slice(0, 10)
    .map((track, i) => `${i + 1}. ${track.title} - ${track.author}`)
    .join('\n');
  
  await interaction.reply({
    embeds: [{
      title: 'Track History',
      description: historyList,
      footer: { text: `Total: ${queue.history.size} tracks` }
    }]
  });
}

Clear History

export async function clearHistory(interaction) {
  const queue = useQueue(interaction.guildId);
  
  if (!queue) {
    return interaction.reply('No active queue!');
  }
  
  const size = queue.history.size;
  queue.history.clear();
  
  await interaction.reply(`Cleared ${size} tracks from history!`);
}
export async function handlePreviousNoPreserve(interaction) {
  const queue = useQueue(interaction.guildId);
  
  if (!queue || queue.history.isEmpty()) {
    return interaction.reply('Cannot go back!');
  }
  
  // Go back without preserving current track
  await queue.history.previous(false);
  await interaction.reply('Went back (current track discarded)');
}

Configuration

History behavior can be configured when creating the queue:
const queue = player.nodes.create(interaction.guild, {
  // Disable history tracking
  disableHistory: false,
  
  // Maximum number of tracks to keep in history
  maxHistorySize: 100
});

Notes

  • History uses a LIFO (Last In First Out) queue structure
  • The most recently played track is at position 0
  • History is automatically managed as tracks play
  • When history is disabled (disableHistory: true), the push() method returns false and no tracks are stored
  • The maxHistorySize option controls how many tracks are kept in history. When exceeded, oldest tracks are removed
  • Using previous() removes the track from history and plays it
  • The preserveCurrent parameter in previous() allows you to control whether the current track stays in the queue

Build docs developers (and LLMs) love