Skip to content

About

A Vencord plugin that gives you a custom profile badge image, description, and styling with hover tooltips, a click popup, badge rotation ("My Badges"), presets, and packs. Bundled with UserBoard, a sidebar button that opens a full in-app dashboard for managing everything without leaving Discord.

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Latest commit

 

History

49 Commits

Folders and files

Repository files navigation

Vencord logo

Custom Badges — Vencord

Vencord Plugin License: GPL v3 Cloudflare Workers Discord Server

TypeScript Third-Party Status

One badge. Every client. Zero exceptions.

A Vencord and Equicord plugin that gives you a custom profile badge image, description, and styling with hover tooltips, a click popup, badge rotation ("My Badges"), presets, and packs. Bundled with UserBoard, a sidebar button that opens a full in-app dashboard for managing everything without leaving Discord.

▸ Two versions exist. This branch (main) is the Dashboard version. If you want zero DOM injection and pure Vencord BadgeAPI, use the React branch. The installer below can set up either one.

Features

  • Custom profile badge: image, description, and color/shape/animation styling
  • Multiple badges per user with one active at a time ("My Badges" rotation)
  • Presets and importable/exportable badge packs
  • Dedicated sidebar dashboard (black-themed) for managing badges without opening Discord's settings
  • Account verification: badge writes require a session token proving you own the account
  • Badge data synced through a small Cloudflare Worker + KV backend, with server-side rate limiting
  • One-line installer for Vencord and Equicord (Windows)

$\color{#FFB6C1}\textsf{Quick Install (Windows)}$

Open PowerShell and run:

irm https://raw.githubusercontent.com/ItzMeShadow999/CustomBadges/main/install.ps1 | iex

The installer walks you through everything:

  • ◆ Pick your client: Vencord or Equicord
  • ◆ Pick your version: Dashboard (main) or React (CustomBadges-React)
  • ◆ Installs Git, Node.js LTS and pnpm if they are missing (via winget)
  • ◆ Asks whether you already have the client built from source
    • Yes: you enter the path to your folder. The repo root, its src folder, or src\userplugins all work. Your existing repo is left alone, only src\userplugins\customBadges is added.
    • No: you choose where to clone it (blank uses the default folder in your user profile)
  • ◆ Downloads the plugin files with a live progress line
  • ◆ Closes Discord, runs pnpm install and pnpm build quietly (one live log line and a spinner, full log only if something fails)
  • ◆ Runs pnpm inject (you pick your Discord install in the prompt), or skips it if you already injected
  • ◆ Enables CustomBadges in your client settings and relaunches Discord

After it finishes, open the plugin settings and click Verify Discord Account to get your session token (see Account Verification).

▪ Skip the prompts

Set any of these environment variables in the same PowerShell window before running the installer:

Variable Values What it does
CB_CLIENT vencord or equicord Skips the client menu
CB_VARIANT main or react Skips the version menu (main is the dashboard version)
CB_DIR a folder path Clone location, or your existing source build
CB_YES 1 No prompts, closes Discord automatically

Example:

$env:CB_CLIENT='equicord'; $env:CB_VARIANT='react'; irm https://raw.githubusercontent.com/ItzMeShadow999/CustomBadges/main/install.ps1 | iex

▪ Requirements and notes

  • Windows 10 or 11 with PowerShell 5.1 or newer. macOS and Linux users should use the manual steps below.
  • winget is needed only if Git or Node.js are missing.
  • pnpm inject is the client's own interactive installer, so you still choose your Discord install there.
  • The banner uses true color. If your console is too narrow or does not support it, a plain title or basic colors are used instead.
  • Read the script before running it: install.ps1

$\Huge{\color{#FFB6C1}\textsf{Manual Installation (click to expand)}}$

Follow the steps below to install the plugin manually.

1. Clone the Vencord repo & pnpm install

git clone https://github.com/Vendicated/Vencord
cd "YOURPATHHERE"
pnpm install

2. Locate your Vencord userplugins folder in \Vencord\src

  • If the folder doesn't exist, create it.

3. Create a new folder inside userplugins called customBadges

Copy every file from this project into it, keeping the same structure:

userplugins/customBadges/
├── index.tsx
├── native.ts
└── dashboard/
    ├── types.ts
    ├── bridge.ts
    ├── button.ts
    ├── buttonRegistry.ts
    ├── dashboardView.ts
    ├── html.ts
    └── wireSettings.ts

▸ For the React branch, copy only index.tsx and native.ts. There is no dashboard/ folder.

4. Rebuild Vencord

  • Source build: run pnpm build (or npm run build), then pnpm inject if you haven't already injected Vencord into your Discord client.
  • Installer-based build with plugin auto-detection: just restart Discord after copying the files in.

5. Enable the plugin

Open Discord → Vencord Settings → Plugins, find CustomBadges, and enable it.

6. Restart Discord

Ctrl/Cmd+R

$\Huge{\color{#FFB6C1}\textsf{Manual Installation: Equicord (click to expand)}}$

Equicord is Vencord-based, so CustomBadges installs the exact same way. Just point the clone at Equicord's repo instead of Vencord's.

1. Clone the Equicord repo & pnpm install

git clone https://github.com/Equicord/Equicord
cd "YOURPATHHERE"
pnpm install

2. Locate your Equicord userplugins folder in \Equicord\src

  • If the folder doesn't exist, create it.

3. Create a new folder inside userplugins called customBadges

Copy every file from this project into it, keeping the same structure:

userplugins/customBadges/
├── index.tsx
├── native.ts
└── dashboard/
    ├── types.ts
    ├── bridge.ts
    ├── button.ts
    ├── buttonRegistry.ts
    ├── dashboardView.ts
    ├── html.ts
    └── wireSettings.ts

▸ For the React branch, copy only index.tsx and native.ts.

4. Rebuild Equicord

  • Source build: run pnpm build (or npm run build), then pnpm inject if you haven't already injected Equicord into your Discord client.
  • Installer-based build with plugin auto-detection: just restart Discord after copying the files in.

5. Enable the plugin

Open Discord → Equicord Settings → Plugins, find CustomBadges, and enable it.

6. Restart Discord

Ctrl/Cmd+R


§ Which version should I use?

Feature Dashboard (main) React (CustomBadges-React)
Badge rendering DOM injection via MutationObserver Vencord BadgeAPI (React)
Tooltip Custom fixed-position tooltip Vencord native tooltip
Click popup card Yes Removed
Dashboard UI Full-page panel in the DM sidebar Removed
Files index.tsx + native.ts + dashboard/* index.tsx + native.ts only
Settings UI Settings tab and dashboard Single Vencord settings tab

Usage

  • Open the plugin's settings tab in Vencord Settings to set your badge image, description, and style, or
  • Use the new dashboard button added to your DM sidebar. It opens a full-page dashboard where you can set your badge, switch between saved badges, import/apply presets, import a badge pack from a URL, or generate your own pack to share.
  • Your badge is stored server-side (keyed to your Discord user ID) so it follows you across devices as long as the plugin is installed and enabled.

Account Verification

Publishing, switching, or deleting a badge requires proving you own the Discord account you're doing it as:

  1. Click Verify Discord Account in settings. This opens your browser to the worker's /auth/start page.
  2. Confirm you're signed in as the right account and follow the prompt there.
  3. Copy the code it gives you back and paste it into the Session Token field in settings.

That token is what authorizes every write from then on (sent as a Bearer header). Reading badges (yours or anyone else's) never required it and still doesn't. The token doesn't expire on its own; if a publish/switch/delete ever fails with an auth error, just re-verify and paste a fresh code. The token field itself is masked once you click away, so it's not left sitting in plain text in your settings.

If you ever lose track of your token, or think someone else got hold of it, hit Revoke Your Token. This immediately kills that token server-side (on every device using it), and you'll need to verify again to get a new one.


Badge Preview

1. Hover: shows the badge tooltip

2. Click: opens the full badge popup card


Backend (Self Hosting / Contributors)

The worker.js + wrangler.toml in this project deploy to Cloudflare Workers with a KV namespace for badge storage. If you want to run your own instance instead of using the default endpoint:

  1. wrangler kv namespace create BADGES_KS and put the resulting id into wrangler.toml.
  2. wrangler deploy.
  3. Point the plugin at your worker by passing your own apiBase where native.ts's functions are called.

Update Catalog (click to expand)

CustomBadges: Patch Notes // V2

Highlights

  • Account verification (session tokens): badge writes (set / switch / delete) now require a verified session token instead of being trusted on userId alone.
  • Dashboard gets its own opening/closing animation and no longer hides Discord's real UI to render itself.
  • Standalone dashboard is now feature-complete with the Vencord settings tab: tooltip/popup/owner-tag/mutual-guild toggles that previously only existed in Discord's native Settings are now wired into the dashboard too.
  • Badge Pack Sharing Guidelines panel, in both the Vencord settings tab and the standalone dashboard, with a CRT power-off close animation.
  • Session token input with an animated letter → dot masking effect.
  • Layout fix: dashboard content no longer has a large dead gap on the left/right.

native.ts

  • Added authHeaders() / requireSessionToken() helpers.
  • setBadge, setActiveBadge, deleteBadge now take a sessionToken argument and send it as a Bearer auth header; each throws NOT_VERIFIED if no token is present.
  • Added revokeOwnToken(): calls POST {apiBase}/self/revoke to invalidate the current session token.

dashboard/bridge.ts

  • DashboardBridge interface extended with verifyAccount, revokeSessionToken, switchToBadge, deleteBadgeSlot so the standalone dashboard can call them (previously these lived only in index.tsx and weren't exposed to the dashboard).

dashboard/dashboardView.ts

  • Mounting strategy changed: the wrapper now mounts on <body> and is pinned over the main content area with position: fixed + getBoundingClientRect(), instead of being appended inside mainArea with its siblings hidden via display: none. Discord's message list and everything else underneath now keeps rendering normally the whole time. This is what fixed the blank-pane bug on close.
  • Added a resize listener + light setInterval poll to reposition the wrapper if Discord's own layout shifts (sidebar/member-list toggle) without a resize event.
  • Open/close animation: wrapper fades and scales in on open (opacity 0→1, scale(0.97)→scale(1), slight translateY), and now animates back out on close instead of being removed instantly. restoreDefaultView() waits ~200ms before actually detaching it. Reopening mid-close cancels the pending removal.

dashboard/html.ts

  • New shield icon (used for the Account Verification section).
  • New Account Verification section: Verify / Revoke buttons + session token field.
  • New session token input styling: text is painted transparent over a real <input>, with a per-character overlay that morphs each letter into a masking dot on blur (and back on focus), including scroll-sync so it stays aligned once the token overflows the field width.
  • New preference toggle switches in the dashboard itself (tooltip, popup, owner tag, append Vencord tag, hide own badge, restrict to mutual servers). Previously these only existed in Discord's native Settings tab.
  • New ub-btn-danger-solid / ub-btn-link button styles.
  • New Badge Pack Sharing Guidelines panel (#ub-guidelines-panel + backdrop): format spec, pack-size note, content rules, submission steps, and a "Got it" close button. Closes with a CRT-style power-off collapse + flash instead of a plain fade.
  • Layout fix: .contentSection_b6bcee / .content_b6bcee (Discord's own settings classes) were inheriting centering meant for a page that sits next to a nav sidebar; since the dashboard doesn't render that sidebar, this left a large empty gap on the left (and right) of the cards. Now forced flush-left and full-width.

dashboard/wireSettings.ts

  • Added wireSwitch() / setSwitchValue() generic toggle wiring, used for all the new dashboard preference switches.
  • Added the session-token masking logic: buildTokenChars(), setTokenMasked(), syncOverlayScroll(), escapeHtml().
  • Added openGuidelines() / closeGuidelines() for the new guidelines panel (open resets and restarts the transition so it can be reopened right after closing; close waits out the 340ms CRT animation before clearing state).
  • Added updatePopupLockState(): disables the popup/owner-tag controls when badge mode is "vencord" (Vencord Classic mode can't support the click-to-view popup).
  • Added renderMyBadgesList().

index.tsx

  • describeBadgeApiError() now handles the NOT_VERIFIED error kind.
  • New settings entries: verifyAccount (opens {apiBase}/auth/start via Discord OAuth, identify scope only), sessionToken, revokeToken.
  • New verifyDiscordAccount() and revokeSessionToken() functions.
  • New SessionTokenInput and RevokeTokenButton React components (Vencord settings tab equivalent of the dashboard's token field/masking behavior).
  • switchToBadge() and deleteBadgeSlot() are now exported and pass settings.store.sessionToken through to setActiveBadge / deleteBadge.
  • setBadge call site updated to pass the session token.
  • Added renderJsonHighlighted(): simple JSON syntax highlighter (keys/strings/numbers/literals/punctuation) used when previewing a pack's JSON.
  • Added PackGuidelinesModal component: the Vencord-settings-tab version of the guidelines panel, same CRT power-off close animation.
  • "Make Pack" button extracted into its own MakePackButton component; badge pack action buttons grouped into BadgePacksButtonsRow.

Unchanged

dashboard/button.ts, dashboard/buttonRegistry.ts, dashboard/types.ts: no differences.


License

This plugin is built for and depends on Vencord, which is licensed under the GNU General Public License v3.0 (or later). In keeping with that, this plugin is also distributed under GPL-3.0-or-later.

That means: you're free to use, study, modify, and share this plugin, but if you distribute a modified version, you must also make its source available under the same license. See the full license text at https://www.gnu.org/licenses/gpl-3.0.html, or the LICENSE file in this project for the standard notice.

This is a third-party plugin and isn't affiliated with, endorsed by, or supported by Discord Inc. Use of client modifications is against Discord's Terms of Service. Use at your own risk.

Community & Support

  • Found someone using this plugin to display NSFW, hateful, or otherwise abusive badge content? Please report it. Don't just block and move on.
  • Something broken or not working as expected?
    1. Check the FAQs first. Your issue may already be answered there.
    2. If it's not covered, ask in the issues help chat.
    3. To report a bug, abuse, or a badge that violates the rules, use the Reports chat.
  • Join the server here: https://discord.gg/PUYaka9Hy8
  • You can optionally tag Shadow in the relevant channel for visibility. Please don't send DMs, they're most likely filtered out and won't be seen.

About

A Vencord plugin that gives you a custom profile badge image, description, and styling with hover tooltips, a click popup, badge rotation ("My Badges"), presets, and packs. Bundled with UserBoard, a sidebar button that opens a full in-app dashboard for managing everything without leaving Discord.

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Contributors

Languages