Don't like 😂 and 😢 -emojis in reactions? Here's a simple solution that replaces the two emojis to 😏 and 🫨 across Civitai.
Setup
You need an extension installed to your browser that can run custom code. In this case, ScriptCat, Tampermonkey or Greasemonkey. In short, they offer the same functionality, just that ScriptCat has better privacy policy and Tampermonkey/Greasemonkey are the most popular.
Chrome: ScriptCat or Tampermonkey
Firefox: ScriptCat or Tampermonkey or Greasemonkey
Once you have either installed, copy the following code:
// ==UserScript==
// @name Replace emojis
// @namespace local
// @version 2.0
// @description Replaces selected emojis
// @match https://civitai.com/*
// @match https://www.civitai.com/*
// @match https://civitai.red/*
// @match https://www.civitai.red/*
// @run-at document-idle
// @grant none
// ==/UserScript==
(() => {
"use strict";
const replacements = [
["😂", "😏"],
["😢", "🫨"]
];
const excludedSelector =
"script, style, textarea, input, select, option, [contenteditable]";
function replaceText(text) {
let result = text;
for (const [from, to] of replacements) {
result = result.split(from).join(to);
}
return result;
}
function containsTarget(text) {
return replacements.some(([from]) => text.includes(from));
}
function isExcluded(node) {
const parent = node.parentElement;
return (
!parent ||
Boolean(parent.closest(excludedSelector))
);
}
function updateTextNode(node) {
if (
node.nodeType !== Node.TEXT_NODE ||
!node.nodeValue ||
isExcluded(node) ||
!containsTarget(node.nodeValue)
) {
return;
}
const current = node.nodeValue;
const updated = replaceText(current);
if (updated !== current) {
node.nodeValue = updated;
}
}
function processSubtree(root) {
if (!root) {
return;
}
if (root.nodeType === Node.TEXT_NODE) {
updateTextNode(root);
return;
}
if (
root.nodeType !== Node.ELEMENT_NODE ||
root.matches(excludedSelector)
) {
return;
}
const walker = document.createTreeWalker(
root,
NodeFilter.SHOW_TEXT,
{
acceptNode(node) {
if (
!node.nodeValue ||
isExcluded(node) ||
!containsTarget(node.nodeValue)
) {
return NodeFilter.FILTER_REJECT;
}
return NodeFilter.FILTER_ACCEPT;
}
}
);
const nodes = [];
let node;
while ((node = walker.nextNode())) {
nodes.push(node);
}
for (const textNode of nodes) {
updateTextNode(textNode);
}
}
function observe() {
if (!document.body) {
return;
}
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
}
const observer = new MutationObserver(mutations => {
observer.disconnect();
try {
for (const mutation of mutations) {
if (mutation.type === "characterData") {
updateTextNode(mutation.target);
}
for (const addedNode of mutation.addedNodes) {
processSubtree(addedNode);
}
}
} finally {
observe();
}
});
if (!document.body) {
return;
}
processSubtree(document.body);
observe();
})();What it does
Operates only when in Civitai URL.
Scans the page text elements locally in browser to find set emojis.
Replaces set emojis if present.
Keeps updated in dynamic content changes.
I made this iteration with GPT 5.6 Sol and have used it for a few weeks. No hit in browser performance.
TIP: If you ever want to load custom code from the internet, feed it to your choice of LLM first, asking what it does and if it's secure.
After you have copied the code, create a new userscript in ScriptCat, Tampermonkey or Greasemonkey and paste it to the textfield.
Save, and make sure the extension is enabled.
Done!
Now your browser should automatically change the affected emojis across Civitai.
Before

After

Notes
This is a visual override, not a function replacement.
Works on desktop and mobile.
You can easily revert the change by disabling the extension or userscript itself.
You can change the replacements to be whatever you want. See https://emojipedia.org/
If an emoji shows ? - it means your OS or browser doesn't support it.
