Package Exports
- discord2html
Readme
discord2html
Generate styled HTML transcripts from Discord channel message history. Processes Discord-flavored markdown, embeds, attachments, reactions, threads, and Discord Components V2.
discord2html is a maintained fork of discord-html-transcripts. This fork fixes the critical v3.3.0 bug, adds full Discord Components V2 support, and modernizes the package for current Discord.js and Node.js versions.
What's different from the original
- Bug fix: v3.3.0 introduced a stray
;after the<style>JSX tag that prevented all custom CSS from loading, breaking the visual rendering of every Components V2 message. Fixed. - Components V2: Select menu option emojis now render as images (not raw URL strings). Premium button style handled. All unknown component types degrade gracefully to
nullinstead of throwing. - Modern markdown: Headings (
#,##,###) and subtext (-#) are now rendered as styled HTML instead of falling through to plain text — important for Components V2 messages that rely on them. - Footer branding: New
brandingoption ({ text, url?, color? }) renders your brand in the transcript footer, optionally as a clickable link. - CJS interop fix:
discord-markdown-parser'sparseis now imported as a named export. The previous default import resolved to the wholemodule.exportsobject under ESM, causing a runtimeparse is not a functionerror. - Dual CJS/ESM output: Package now ships both
dist/index.js(CJS) anddist/index.mjs(ESM) with matching.d.ts/.d.mtstype declarations. Theexportsfield is set correctly. - Dependency fix:
debugwas indevDependenciesbut is used in production code — moved todependencies. - Bundled React (self-contained): React, ReactDOM and
@derockdev/discord-components-*are bundled into the dist at build time. The package renders with React 19 (react-dom/static), but@derockdev/discord-components-reactpeer-requires React ≤18 — so a naïve install left two React copies in the tree, and elements created under React 18 failed to render under React 19 with "Objects are not valid as a React child". Bundling resolves everyimport Reactto a single React 19 instance baked into the package, so consumers never need to install React or addoverrides— onlydiscord.js. The ESM build injects acreateRequireshim so the bundled CJSreact-domserver can load Node built-ins (util,stream, …) without the "Dynamic require of X is not supported" error. - Modernized: TypeScript target updated to ES2020. React updated to 19.2.4. Build pipeline switched from raw
tsctotsup.
Installation
npm install discord2htmlPeer dependency: discord.js v14 or v15
Quick start
import * as discord2html from 'discord2html';
// or: const discord2html = require('discord2html');
// Using the built-in message fetcher
const transcript = await discord2html.createTranscript(channel);
channel.send({ files: [transcript] });
// Using your own message array/collection
const transcript = await discord2html.generateFromMessages(messages, channel);
channel.send({ files: [transcript] });API reference
createTranscript(channel, options?)
Fetches all messages from a TextBasedChannel and generates an HTML transcript.
| Parameter | Type | Description |
|---|---|---|
channel |
TextBasedChannel |
The channel to fetch messages from |
options |
CreateTranscriptOptions |
Optional configuration (see below) |
Returns Promise<AttachmentBuilder> by default, or Promise<Buffer> / Promise<string> based on returnType.
generateFromMessages(messages, channel, options?)
Generates an HTML transcript from a provided message collection or array.
| Parameter | Type | Description |
|---|---|---|
messages |
Message[] | Collection<string, Message> |
Messages to render |
channel |
Channel |
Used for the header (guild name, channel name, icon) |
options |
GenerateFromMessagesOptions |
Optional configuration (see below) |
Options
All options are optional.
{
// createTranscript only:
limit: number; // Max messages to fetch. -1 fetches all. Default: all
filter: (msg) => bool; // Filter function applied before rendering
// both functions:
returnType: ExportReturnType; // 'attachment' | 'buffer' | 'string'. Default: 'attachment'
filename: string; // Attachment filename. Default: 'transcript-{channel-id}.html'
saveImages: boolean; // Download images and inline as base64. Default: false
poweredBy: boolean; // Show "Powered by discord2html" footer. Default: true
footerText: string; // Footer text. Use {number} and {s}. Default: 'Exported {number} message{s}.'
favicon: 'guild' | string; // 'guild' uses the server icon, or pass a URL. Default: 'guild'
hydrate: boolean; // Server-side hydrate the HTML. Default: false
callbacks: {
resolveChannel: (id: string) => Awaitable<Channel | null>;
resolveUser: (id: string) => Awaitable<User | null>;
resolveRole: (id: string) => Awaitable<Role | null>;
resolveImageSrc: (attachment: APIAttachment, message: APIMessage) => Awaitable<string | null | undefined>;
};
}ExportReturnType (enum)
import { ExportReturnType } from 'discord2html';
ExportReturnType.Attachment // returns AttachmentBuilder (default)
ExportReturnType.Buffer // returns Buffer
ExportReturnType.String // returns stringTranscriptImageDownloader
Builder for the resolveImageSrc callback. Downloads and optionally compresses images inline.
import { TranscriptImageDownloader } from 'discord2html';
callbacks: {
resolveImageSrc: new TranscriptImageDownloader()
.withMaxSize(5120) // Skip images over 5 MB
.withCompression(40, true) // 40% quality, convert to WebP (requires `sharp`)
.build(),
}TypeScript
The package ships .d.ts and .d.mts type declarations. No @types/discord2html package is needed.
import type { CreateTranscriptOptions, GenerateFromMessagesOptions, ExportReturnType } from 'discord2html';License
Apache-2.0. Original work by Derock. Fork maintained by José Hernanes.