@disckit/placeholders
v1.3.0
Published
Placeholder substitution engine for Discord bots. Zero Discord.js dependency — works in bot and dashboard.
Downloads
76
Maintainers
Readme
Features
- Replace
{member:name},{guild:memberCount},{level}and more in any string - No discord.js dependency — works in dashboards and REST APIs with plain objects
buildPreviewContext()— build a context from flat data for live message previewsdetectPlaceholders()— find all tokens in a string (for validation or UI hints)applyPresencePlaceholders()— bot status strings with{servers}and{members}VARIABLESregistry — list and describe all available tokens programmatically- Full TypeScript types included · Zero dependencies · Node.js 18+
Installation
npm install @disckit/placeholders
yarn add @disckit/placeholders
pnpm add @disckit/placeholdersTypeScript / ESM
Types are bundled — no extra install needed.
Supports both CommonJS and ESM:
// ESM
import { applyPlaceholders, VARIABLES } from '@disckit/placeholders';
// CommonJS
const { applyPlaceholders, VARIABLES } = require('@disckit/placeholders');Usage
Apply placeholders
const { applyPlaceholders } = require('@disckit/placeholders');
const ctx = {
guild: { name: 'My Server', id: '123', memberCount: 1500, icon: '' },
member: { id: '456', name: 'john', nick: 'John', dis: '0', tag: 'john#0', mention: '<@456>', avatar: '' },
};
applyPlaceholders('Welcome {member:mention} to {server}! We now have {count} members.', ctx);
// → "Welcome <@456> to My Server! We now have 1500 members."Dashboard message preview
The buildPreviewContext() helper creates a realistic preview context from flat data — useful for live preview in a web dashboard without needing Discord.js objects:
const { applyPlaceholders, buildPreviewContext } = require('@disckit/placeholders');
// In your dashboard API route:
app.post('/preview', (req, res) => {
const { template, guildName, memberCount } = req.body;
const ctx = buildPreviewContext({ guildName, memberCount, memberName: 'example' });
res.json({ result: applyPlaceholders(template, ctx) });
});Role placeholders
const ctx = {
guild: { name: 'Server', id: '1', memberCount: 100 },
member: { id: '2', name: 'john', nick: 'john', dis: '0', tag: 'john#0', mention: '<@2>', avatar: '' },
roles: {
resolve: (roleId) => {
const role = guild.roles.cache.get(roleId);
return role ? role.toString() : null; // null = silently removed
},
},
};
applyPlaceholders('You just got {role:987654321}!', ctx);
// → "You just got @Staff!" (or "You just got !" if role not found)Presence variables
const { applyPresencePlaceholders, buildPresenceContext } = require('@disckit/placeholders');
const ctx = buildPresenceContext(250, 45000);
await applyPresencePlaceholders('In {servers} servers with {members} members', ctx);
// → "In 250 servers with 45000 members"
// Sharded bot — pass a resolver:
await applyPresencePlaceholders(statusText, {
resolver: async () => {
const servers = (await client.shard.fetchClientValues('guilds.cache.size')).reduce((a, b) => a + b, 0);
return buildPresenceContext(servers, membersCount);
},
});Detect and validate placeholders
const { detectPlaceholders, hasPlaceholders } = require('@disckit/placeholders');
detectPlaceholders('Welcome {member:mention} to {server}!');
// → ['{member:mention}', '{server}']
hasPlaceholders('Hello, World!'); // → false
hasPlaceholders('{member:name}'); // → trueVariable registry
const { VARIABLES, getByGroup, findByKey } = require('@disckit/placeholders');
// All available tokens
VARIABLES.forEach(v => console.log(`${v.key} — ${v.description}`));
// By group
getByGroup('member'); // → all {member:*} variable definitions
getByGroup('guild'); // → all {guild:*} variable definitions
// Find a specific one
findByKey('{member:mention}');
// → { key: '{member:mention}', group: 'member', description: '...', example: '<@123>' }Available Placeholders
| Token | Group | Description |
|-------|-------|-------------|
| {server} / {guild:name} | guild | Server name |
| {guild:id} | guild | Server ID |
| {count} / {guild:memberCount} | guild | Total member count |
| {guild:icon} | guild | Server icon URL |
| {member:id} | member | Member's Discord ID |
| {member:name} | member | Username |
| {member:nick} | member | Display name |
| {member:tag} | member | Full tag (username#0) |
| {member:mention} | member | Clickable mention |
| {member:avatar} | member | Avatar URL |
| {inviter:name} / {inviter:tag} | inviter | Who sent the invite |
| {invites} | inviter | Inviter's effective invite count |
| {level} / {xp} / {rank} / {coins} | extras | Bot-specific values |
| {role:ID} | role | Role mention by ID (removed if not found) |
| {servers} / {members} | presence | Bot status only |
