I’m using Emojis in the Categories section in the sidebar, but I also have a custom section that is public. I wanted to have the same colorful icons in that section so it doesn’t get so “bland” compared to the Categories section.
Is this possible?
I’m using Emojis in the Categories section in the sidebar, but I also have a custom section that is public. I wanted to have the same colorful icons in that section so it doesn’t get so “bland” compared to the Categories section.
Is this possible?
With the help of both ChatGPT and Claude, I was able to make it work and very customizable:
If you want to do it, create a new component and add this to the CSS tab:
.sidebar-section-link-prefix .emoji.prefix-emoji {
width: 1rem !important;
height: 1rem !important;
}
For my particular case
1rem
works great. Adjust to your forum/community
Then in the JS tab:
import { apiInitializer } from "discourse/lib/api";
import { emojiUrlFor } from "discourse/lib/text";
export default apiInitializer("0.11.1", (api) => {
// Map section names to IDs
const sectionIds = {
"community": 1,
"tiago": 2,
"personal-section": 3,
// Add more sections here
};
// Map of [sectionId, itemName] to emoji names
const iconReplacements = {
// Community section (ID: 1)
"1,admin": "wrench",
"1,review": "triangular_flag_on_post",
"1,everything": "books",
"1,my-posts": "writing_hand",
"1,my-messages": "envelope_with_arrow",
// Tiago section (ID: 2)
"2,Journal": "notebook_with_decorative_cover",
"2,Music": "musical_note",
"2,About": "bust_in_silhouette",
// Personal section (ID: 3)
"3,Backups": "floppy_disk",
"3,Scheduled": "clock3",
"3,Staff": "lock",
"3,Components": "electric_plug",
};
function replaceIcons() {
Object.entries(sectionIds).forEach(([sectionName, sectionId]) => {
Object.entries(iconReplacements).forEach(([key, emojiName]) => {
const [keyId, itemName] = key.split(',');
// Only process if this replacement is for the current section
if (parseInt(keyId) === sectionId) {
const url = emojiUrlFor(emojiName);
// Try multiple selectors to catch both hamburger menu and fixed sidebar
const selectors = [
// Fixed sidebar selector
`div[data-section-name="${sectionName}"] li[data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`,
// Hamburger menu selector (more specific)
`.menu-panel div[data-section-name="${sectionName}"] li[data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`,
// Generic fallback
`[data-section-name="${sectionName}"] [data-list-item-name="${itemName}"] .sidebar-section-link-prefix.icon`
];
for (const selector of selectors) {
const prefix = document.querySelector(selector);
if (prefix && url) {
prefix.innerHTML = `
<img src="${url}"
title="${emojiName}"
alt="${emojiName}"
class="emoji prefix-emoji">
`;
break; // Exit loop once we find and replace the icon
}
}
}
});
});
}
// Run on page change
api.onPageChange(replaceIcons);
// Also run with delay to catch dynamically loaded content
api.onPageChange(() => {
setTimeout(replaceIcons, 100);
setTimeout(replaceIcons, 500);
});
// Use MutationObserver to catch when hamburger menu is added to DOM
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
mutation.addedNodes.forEach((node) => {
if (node.nodeType === Node.ELEMENT_NODE) {
// Check if the added node contains sidebar sections
if (node.classList?.contains('menu-panel') ||
node.querySelector?.('.sidebar-sections') ||
node.classList?.contains('sidebar-sections')) {
setTimeout(replaceIcons, 50);
}
}
});
});
});
// Start observing
observer.observe(document.body, {
childList: true,
subtree: true
});
});
I made it so I can easily add new custom sections by name, attributing it an id
and then creating each section’s mapping.
The reason for that is because I may have 2 sections with the title Journal
, for example, but maybe I want 2 different emojis for each.
I’m pretty sure there will be someone saying that there’s a component or plugin for this but it was still fun to go back and forth with ChatGPT and Claude until everything worked the way I wanted.
Hope this helps other users.
If you see anything that can be tweaked/improved, please share
I just updated the JS code, because I noticed that on mobile it was still showing the default icons. Everything is working as expected on both mobile and desktop.