JSPM

better-discord-transcripts

1.0.7
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 2362
  • Score
    100M100P100Q10509F
  • License Apache-2.0

Discord HTML transcript generator with Components V2, threads, polls, voice playback, and search. Drop-in replacement for discord-html-transcripts.

Package Exports

  • better-discord-transcripts

Readme

better-discord-transcripts

npm version license node

A nicely formatted HTML transcript generator for discord.js v14/v15. Drop-in replacement for discord-html-transcripts, with Components V2, thread modals, voice playback, and a built-in search UI. Inspired by community forks such as discord.js-html-transcript.

Images and voice messages are inlined by default so transcripts stay readable offline. Images are compressed to WebP via sharp - smaller HTML files without extra setup.

Requirements

  • Node.js 18+
  • discord.js ^14.26.4 or ^15 (peer dependency - install it yourself)
  • sharp - bundled as a regular dependency; installed automatically with this package

You do not need to run npm install sharp separately. It ships with better-discord-transcripts and is used whenever saveImages is enabled (default).

Install

npm install better-discord-transcripts discord.js

Migration from discord-html-transcripts

One line change. Same options, same return types:

- const { createTranscript } = require('discord-html-transcripts');
+ const { createTranscript } = require('better-discord-transcripts');

Your existing ticket code still works.

Quick start

const { createTranscript } = require('better-discord-transcripts');

const attachment = await createTranscript(channel, { limit: -1 });
await logChannel.send({ files: [attachment] });

If you omit limit (or set -1), the full channel history is fetched, including thread messages on posts with hasThread.

Image compression (sharp)

With default options, attachments and embed images are downloaded and embedded as WebP base64 instead of raw PNG/JPEG. That keeps transcript file size down while everything still opens from a single .html file with no external CDN links.

Setting Value
Library sharp (required dependency)
Format WebP
Max dimension 720px (longest side)
Quality ~70%
Toggle saveImages: false skips download and inlining entirely

If sharp fails to load on an unsupported platform, the library falls back to the original image format and logs a one-time warning - the transcript still generates, but files may be larger.

// Default - images compressed with sharp
await createTranscript(channel);

// Skip images - smallest output, but Discord CDN links may expire later
await createTranscript(channel, { saveImages: false });

Options

Same options as discord-html-transcripts, plus saveVoiceMessages:

Option Type Default Description
limit number all messages Max messages to fetch. -1 or omit = everything
filter (m) => boolean none Filter messages before render
returnType 'attachment', 'buffer', 'string' 'attachment' Or use the ExportReturnType enum
filename string transcript-{channelName}.html Attachment filename
saveImages boolean true Download images and inline as WebP base64 via sharp (max 720px, ~70% quality)
saveVoiceMessages boolean true Download voice messages and inline as base64 so they stay playable after Discord URLs expire
footerText string Exported {number} message{s}. Footer line before the powered-by credit
poweredBy boolean true Show "Powered by better-discord-transcripts"
favicon 'guild' or string 'guild' Guild icon or a custom URL
hydrate boolean false Server-side hydration of web components (slower, works offline)
callbacks object auto resolveUser, resolveRole, resolveChannel, resolveImageSrc, resolveVoiceSrc

Disable image or voice inlining

// No images (voice messages still inlined by default)
await createTranscript(channel, { saveImages: false });

// Voice only (images stay as Discord CDN links, but links may break later - remember that!)
await createTranscript(channel, { saveImages: false, saveVoiceMessages: true });

// Neither - smallest file, but CDN links may break later - remember that!
await createTranscript(channel, { saveImages: false, saveVoiceMessages: false });

TypeScript

import { createTranscript, ExportReturnType } from 'better-discord-transcripts';

const transcript = await createTranscript(channel, {
  returnType: ExportReturnType.String,
});

generateFromMessages - when you already have messages

createTranscript fetches messages from Discord for you.

generateFromMessages skips that step. You pass a Message[] or Collection you already loaded (custom fetch, cached ticket log, filtered list, etc.) and get the same HTML output.

Use it when:

  • you fetched messages yourself (custom pagination, database, bot cache)
  • you want to render only a subset without calling the API again
  • you deleted the channel but still have message objects in memory
const { generateFromMessages } = require('better-discord-transcripts');

// messages = Message[] or Collection from channel.messages.fetch(), your DB, etc.
const attachment = await generateFromMessages(messages, channel, {
  poweredBy: false,
  filename: 'ticket-log.html',
});

Same options as createTranscript, except there is no limit or filter (you control the array yourself). saveImages and saveVoiceMessages default to true here as well.

Interactive HTML viewer

Built into every transcript:

  • Search - find messages by text or ID, keyboard navigation
  • Pinned messages - header panel with jump-to-message
  • Member list - participants and message counts
  • Thread modal - click a thread bar to read the full thread inline
  • Image lightbox - click images to zoom
  • Voice playback - play button and waveform (works offline when saveVoiceMessages is on)
  • Spoiler reveal - click to reveal spoilers

Content rendered

  • Plain text, markdown, mentions, emojis, timestamps
  • Embeds, attachments, stickers, reactions
  • Replies, forwards, slash command headers
  • Components V2 - Container, Section, TextDisplay, Media Gallery, Thumbnail, File, Separator, buttons
  • Polls with vote bars
  • Voice messages - waveform from attachment.waveform, duration, inline <audio>
  • System messages - pins, thread created, joins, and more
  • Server tags, role icons, verified bot badges
  • Cross-server reply indicators

Included by default

  • Full channel fetch when limit is omitted
  • Full thread fetch on messages with hasThread
  • sharp installed and used for image inlining (saveImages: true)
  • Images inlined as WebP base64 (720px max, ~70% quality)
  • Voice messages inlined as base64 (saveVoiceMessages: true) for offline playback

API

Export Description
createTranscript(channel, options?) Fetch messages from a channel and render HTML
generateFromMessages(messages, channel, options?) Render HTML from messages you already have
ExportReturnType Attachment, Buffer, or String
default { createTranscript, generateFromMessages }

License

Apache-2.0

Fork and successor of discord-html-transcripts by ItzDerock.