Skip to content

Instantly share code, notes, and snippets.

@arafathusayn
Last active May 31, 2026 15:35
Show Gist options
  • Select an option

  • Save arafathusayn/101a211b3d8122876d70cf1af04ae81d to your computer and use it in GitHub Desktop.

Select an option

Save arafathusayn/101a211b3d8122876d70cf1af04ae81d to your computer and use it in GitHub Desktop.
Remove Tawk.to Branding (2026)
/**
* Remove Tawk.to Branding
*
* What it hides:
* - Footer branding links (tawk.to, utm_source=tawk-messenger)
* - "Add Chat to your website" link
* - Popout button/icon
* - Branding container classes
*
* Key design decisions:
* - CSS injection over DOM removal (less disruptive, survives re-renders)
* - MutationObserver over setInterval (reacts to changes, no wasted cycles)
* - Debounced re-scans (Tawk rebuilds its widget DOM sometimes)
* - iframe `load` listener stays active (catches SPA navigations)
* - JS fallback for popout buttons (`:has()` unsupported in older browsers)
*/
;(function removeTawkBranding() {
"use strict";
// ── Config ────────────────────────────────────────────────────────────
var STYLE_ID = "hide-tawk-branding";
// NOTE: No `:contains()` (jQuery-only, invalid in browsers).
// No `:has()` in CSS (Firefox < 121, older Safari/Chrome).
// Popout buttons handled via JS fallback below.
var BRANDING_CSS = [
"a[href*='tawk.to'] { display: none !important; }",
"a[href*='utm_source=tawk-messenger'] { display: none !important; }",
"a[title*='Add Chat to your website'] { display: none !important; }",
".tawk-branding { display: none !important; }",
"[class*='tawk-branding'] { display: none !important; }",
".tawk-padding-small { display: none !important; }",
".tawk-icon-popout { display: none !important; }",
].join("\n");
var RETRY_DELAY_MS = 1500;
// ── State ─────────────────────────────────────────────────────────────
var processedIframes = new WeakSet();
var pendingRetries = new Map();
var debounceTimer = null;
// ── Core ──────────────────────────────────────────────────────────────
/**
* Inject a <style> into a document. Returns true on success.
*/
function injectStyle(doc) {
try {
if (!doc || !doc.createElement) return false;
if (doc.getElementById(STYLE_ID)) return true;
var style = doc.createElement("style");
style.id = STYLE_ID;
style.textContent = BRANDING_CSS;
var target = doc.head || doc.documentElement;
if (target) {
target.appendChild(style);
return true;
}
} catch (_) {
// Cross-origin β€” expected.
}
return false;
}
/**
* JS fallback: hide popout buttons for browsers without CSS `:has()`.
*/
function hidePopoutButtons(doc) {
try {
if (!doc || !doc.querySelectorAll) return;
var icons = doc.querySelectorAll(".tawk-icon-popout");
for (var i = 0; i < icons.length; i++) {
var btn = icons[i].closest("button");
if (btn) btn.style.setProperty("display", "none", "important");
}
} catch (_) {}
}
/**
* Inject styles into an iframe. Retries once if contentDocument isn't ready.
*/
function injectIntoIframe(iframe) {
try {
var doc = iframe.contentDocument;
if (!doc) {
// Schedule a single retry if iframe not ready yet
if (!pendingRetries.has(iframe)) {
var timeout = setTimeout(function () {
pendingRetries.delete(iframe);
injectIntoIframe(iframe);
}, RETRY_DELAY_MS);
pendingRetries.set(iframe, timeout);
}
return;
}
injectStyle(doc);
hidePopoutButtons(doc);
} catch (_) {
// Cross-origin β€” expected.
}
}
/**
* Process a chat iframe: mark as processed, inject now, re-inject on reload.
*/
function handleIframe(iframe) {
if (processedIframes.has(iframe)) return;
var title = (iframe.title || "").toLowerCase();
if (title.indexOf("chat") === -1) return;
processedIframes.add(iframe);
// Inject immediately (may already be loaded)
injectIntoIframe(iframe);
// Re-inject on subsequent loads (SPA navigation, widget rebuild).
// Intentionally NOT `{ once: true }` β€” Tawk can reload iframe content.
iframe.addEventListener("load", function () {
injectIntoIframe(iframe);
});
}
/**
* Scan a root document for all chat iframes.
*/
function scanIframes(root) {
try {
var iframes = (root || document).querySelectorAll("iframe");
for (var i = 0; i < iframes.length; i++) {
handleIframe(iframes[i]);
}
} catch (_) {}
}
// ── Observer ──────────────────────────────────────────────────────────
function onMutations(mutations) {
var foundNewIframe = false;
for (var i = 0; i < mutations.length; i++) {
var added = mutations[i].addedNodes;
for (var j = 0; j < added.length; j++) {
var node = added[j];
if (node.nodeName === "IFRAME") {
handleIframe(node);
foundNewIframe = true;
} else if (node.nodeType === 1 && node.querySelectorAll) {
var nested = node.querySelectorAll("iframe");
if (nested.length) {
for (var k = 0; k < nested.length; k++) {
handleIframe(nested[k]);
}
foundNewIframe = true;
}
}
}
}
// Debounced re-scan: Tawk sometimes rebuilds its widget DOM entirely,
// so existing iframes may get new content without a new IFRAME node.
if (foundNewIframe && !debounceTimer) {
debounceTimer = setTimeout(function () {
debounceTimer = null;
scanIframes();
hidePopoutButtons(document);
}, 500);
}
}
// ── Bootstrap ─────────────────────────────────────────────────────────
function start() {
// Main document branding (outside iframes)
injectStyle(document);
hidePopoutButtons(document);
// Initial iframe scan
scanIframes();
// Watch for dynamically added iframes
if (typeof MutationObserver !== "undefined" && document.body) {
var observer = new MutationObserver(onMutations);
observer.observe(document.body, { childList: true, subtree: true });
// Cleanup
window.addEventListener("beforeunload", function () {
observer.disconnect();
pendingRetries.forEach(clearTimeout);
pendingRetries.clear();
if (debounceTimer) {
clearTimeout(debounceTimer);
debounceTimer = null;
}
});
}
}
// Guard: script may be in <head> before document.body exists
if (document.body) {
start();
} else {
document.addEventListener("DOMContentLoaded", start);
}
})();
@nextvisionmx

Copy link
Copy Markdown

Awesome!

Thanks!

@dev-amdadul

Copy link
Copy Markdown

You have done a awesome job. Thank You
But now they are using another branding can you remove that for us please. @arafathusayn
Untitled

@juan5620

Copy link
Copy Markdown

Same here Works briefly and then the whole chat freezes.

@juan5620

juan5620 commented Sep 1, 2022

Copy link
Copy Markdown

definitely not working it makes the chat freeze after a couple of clicks

@garyfisher

Copy link
Copy Markdown

You have done a awesome job. Thank You But now they are using another branding can you remove that for us please. @arafathusayn Untitled

var removeBranding = function() {
    try {
        var element = document.querySelector("iframe[title*=chat]:nth-child(2)").contentDocument.querySelector(`a[class*=tawk-branding]`)
        var elementt = document.querySelector("iframe[title*=chat]:nth-child(2)").contentDocument.querySelector(`a[class*=tawk-button-small]`)
        if (element) {
            element.remove()
        }
        if (elementt) {
            elementt.remove()
        }
    } catch (e) {}
}

var tick = 100

setInterval(removeBranding, tick)

@zubairbd007

Copy link
Copy Markdown

how to add this code to plugin?please help

@HideCM

HideCM commented Nov 24, 2022

Copy link
Copy Markdown

How to remove POP OUT WIDGET, please?

@AndresReyesDev

Copy link
Copy Markdown

@HideCM No way to do that. The popup is located on the tawk domain.

@KarisKevoo

Copy link
Copy Markdown

worked fine for me, thenks

@chiangky

Copy link
Copy Markdown

sometime works perfectly, some time throw error... any ideas? thanks.
Untitled

@trinib

trinib commented Oct 19, 2023

Copy link
Copy Markdown

working in 2023 latest version

@jarrod0011

Copy link
Copy Markdown

Worked For Me!

Create a JavaScript file:
Create a new JavaScript file, for example, custom-script.js, and paste the above code into this file.

Upload the JavaScript file:
Upload the JavaScript file to your theme directory or another appropriate location in your WordPress installation.

Enqueue the script in your theme's functions.php:
Open your theme's functions.php file and add the following code to enqueue your script:

functions.php - code

function enqueue_custom_script() {
    wp_enqueue_script('custom-script', get_template_directory_uri() . '/path/to/custom-script.js', array(), '1.0', true);
}
add_action('wp_enqueue_scripts', 'enqueue_custom_script');

Make sure to replace /path/to/custom-script.js with the actual path to your JavaScript file.

Save and update:
Save the changes to your functions.php file and update your WordPress theme.

Now, your JavaScript code will be included and executed on the client side when the website is loaded.

@lswang6

lswang6 commented May 8, 2024

Copy link
Copy Markdown

not working properly in 0.8.2 plugin (2024 verison), sometimes the layout of the chat interface is offset, and can not show chat window properly.

@dqd

dqd commented Oct 3, 2024

Copy link
Copy Markdown

Instead of removing a node, you can inject some CSS to change the widget appearance, such as:

const style = document.createElement('style');
style.textContent = 'a.tawk-branding {display:none;}';
document.querySelector('iframe[title*="chat"]:nth-child(2)').contentDocument.head.appendChild(style);

@s2vdeveloper

s2vdeveloper commented Mar 3, 2025

Copy link
Copy Markdown

Please provide new tawk brand removing code because previous code not working..

Below mentioned script not working currently.

var removeBranding = function() {
try {
var element = document.querySelector("iframe[title*=chat]:nth-child(2)").contentDocument.querySelector(a[class*=tawk-branding])

    if (element) {
        element.remove()
    }
} catch (e) {}

}

var tick = 100

setInterval(removeBranding, tick)

@enkiark

enkiark commented Mar 9, 2025

Copy link
Copy Markdown

var removeBranding = function() {
try {
const style = document.createElement('style');
style.textContent = '.tawk-padding-small {display:none !important;}';
document.querySelector('iframe[title*="chat"]:nth-child(2)').contentDocument.head.appendChild(style)
} catch (e) {}
}

var tick = 100

setInterval(removeBranding, tick)

2025 new tawk remove logo

@yasirquyoom

Copy link
Copy Markdown

How we can achieve this is next js website bro please help me.

@ironmanavenger

Copy link
Copy Markdown

Perfect @enkiark
Worked for me.

@murtazabaanihali

Copy link
Copy Markdown

hello all of you guys, here is how you remove all the brandings whether outside chat or inside chat widget for tawk.io

For React/Next.js

"use client";

import { useEffect } from "react";

export default function HideTawkBranding() {
    useEffect(() => {
        const hideBranding = (iframe: HTMLIFrameElement) => {
            try {
                const doc = iframe.contentDocument;
                const link = doc?.querySelector(
                    "a[href*='tawk.to']"
                ) as HTMLElement | null;

                if (link) {
                    link.style.setProperty("display", "none", "important");
                }
            } catch {
                // cross-origin iframe β†’ expected
            }
        };

        const scanIframes = () => {
            document
                .querySelectorAll("iframe[title*='chat']")
                .forEach((iframe) => {
                    console.log("I am here ",)
                    hideBranding(iframe as HTMLIFrameElement)
                });
        };

        // initial scan
        scanIframes();

        // watch for new iframes
        const observer = new MutationObserver(scanIframes);
        observer.observe(document.body, {
            childList: true,
            subtree: true,
        });

        return () => observer.disconnect();
    }, []);

    return null;
}

Import this above component in root of your react/Next js.

And for plain JS:

// hide-tawk-branding.js
(function() {
  const processedIframes = new WeakSet();
  const retryTimeouts = new Map();

  const injectHideStyles = (iframe) => {
    try {
      const doc = iframe.contentDocument;
      if (!doc) {
        // Retry once after 2s if iframe not ready
        if (!retryTimeouts.has(iframe)) {
          const timeout = setTimeout(() => {
            retryTimeouts.delete(iframe);
            injectHideStyles(iframe);
          }, 2000);
          retryTimeouts.set(iframe, timeout);
        }
        return;
      }

      // Skip if already injected
      if (doc.getElementById("hide-tawk-branding")) return;

      const style = doc.createElement("style");
      style.id = "hide-tawk-branding";
      style.textContent = "a[href*='tawk.to']{display:none!important}";
      doc.head.appendChild(style);
    } catch {
      // Silently fail on cross-origin errors
    }
  };

  const handleIframe = (iframe) => {
    // Skip if already processed
    if (processedIframes.has(iframe)) return;

    const title = iframe.title;
    if (title && title.toLowerCase().includes("chat")) {
      processedIframes.add(iframe);
      injectHideStyles(iframe);
    }
  };

  // Process existing iframes
  document.querySelectorAll("iframe[title*='chat' i]").forEach(handleIframe);

  // Watch for new iframes
  const observer = new MutationObserver((mutations) => {
    for (const mutation of mutations) {
      for (const node of mutation.addedNodes) {
        if (node.nodeName === "IFRAME") {
          handleIframe(node);
          continue;
        }
        
        if (node.nodeType === 1) {
          const iframes = node.querySelectorAll("iframe[title*='chat' i]");
          if (iframes.length) {
            iframes.forEach(handleIframe);
          }
        }
      }
    }
  });

  observer.observe(document.body, {
    childList: true,
    subtree: true,
  });

  // Cleanup on page unload
  window.addEventListener("beforeunload", () => {
    observer.disconnect();
    retryTimeouts.forEach(clearTimeout);
    retryTimeouts.clear();
  });
})();

@husnainshah943

husnainshah943 commented Feb 12, 2026

Copy link
Copy Markdown

Updated Code 2026:

  • Remove Footer Branding
  • Remove "Add Chat to your Website"
  • Remove Popout

All type of Branding is removed!

<script> (function() { const processedIframes = new WeakSet(); const retryTimeouts = new Map(); const hideTawkElements = (doc) => { try { if (!doc) return; // Don't add duplicate styles if (doc.getElementById("hide-tawk-global")) return; const style = doc.createElement("style"); style.id = "hide-tawk-global"; style.textContent = ` a[href*='tawk.to'] { display: none !important; } a[href*='utm_source=tawk-messenger'] { display: none !important; } a[href*='Add Chat to your website'] { display: none !important; } .tawk-dropdown-menu a:last-child { display: none !important; } button[role="button"] + div a[href*='tawk.to'] { display: none !important; } div[data-v-2fc2d95d] a:last-child { display: none !important; } button:has(.tawk-icon-popout) { display: none !important; } button:has(.tawk-icon-popout) + div { display: none !important; } .tawk-icon-popout { display: none !important; } button:contains("Pop out widget") { display: none !important; } [class*="tawk-dropdown"] button:has(.tawk-icon-popout) { display: none !important; } `; if (doc.head) { doc.head.appendChild(style); } else if (doc.documentElement) { doc.documentElement.appendChild(style); } // Also directly hide any existing tawk.to links and popout buttons const links = doc.querySelectorAll('a[href*="tawk.to"], a[href*="utm_source=tawk-messenger"]'); links.forEach(link => { link.style.display = 'none'; if (link.parentElement) { link.parentElement.style.display = 'none'; } }); // Directly hide popout buttons const popoutButtons = doc.querySelectorAll('button:has(.tawk-icon-popout), button:contains("Pop out widget"), .tawk-icon-popout'); popoutButtons.forEach(button => { button.style.display = 'none'; if (button.parentElement) { button.parentElement.style.display = 'none'; } }); } catch (e) { // Cross-origin error - can't access } }; const processDocument = (doc) => { hideTawkElements(doc); // Find all iframes inside this document try { const iframes = doc.querySelectorAll('iframe'); iframes.forEach(iframe => { if (!processedIframes.has(iframe)) { processedIframes.add(iframe); // Try to access iframe content when loaded try { if (iframe.contentDocument) { processDocument(iframe.contentDocument); } iframe.addEventListener('load', () => { try { if (iframe.contentDocument) { processDocument(iframe.contentDocument); } } catch (e) {} }, { once: true }); } catch (e) {} } }); } catch (e) {} }; // Start with main document processDocument(document); // Watch for new iframes and DOM changes const observer = new MutationObserver((mutations) => { // Process main document again hideTawkElements(document); for (const mutation of mutations) { for (const node of mutation.addedNodes) { if (node.nodeName === "IFRAME") { if (!processedIframes.has(node)) { processedIframes.add(node); try { if (node.contentDocument) { processDocument(node.contentDocument); } node.addEventListener('load', () => { try { if (node.contentDocument) { processDocument(node.contentDocument); } } catch (e) {} }, { once: true }); } catch (e) {} } } // Also hide popout buttons when they're added if (node.nodeType === 1) { if (node.matches && node.matches('button:has(.tawk-icon-popout), button:contains("Pop out widget")')) { node.style.display = 'none'; } const popoutButtons = node.querySelectorAll('button:has(.tawk-icon-popout), button:contains("Pop out widget"), .tawk-icon-popout'); popoutButtons.forEach(button => { button.style.display = 'none'; }); } } } }); observer.observe(document.body, { childList: true, subtree: true }); // Cleanup window.addEventListener("beforeunload", () => { observer.disconnect(); retryTimeouts.forEach(clearTimeout); retryTimeouts.clear(); }); })(); </script>

@arafathusayn

Copy link
Copy Markdown
Author

Code updated for 2026. Please test and let me know if it works.

@bloodykheeng

bloodykheeng commented Mar 16, 2026

Copy link
Copy Markdown

2026 march update

i had to tweak @murtazabaanihali code
here ive comented one useEffect but they all work one can remove the branding entirely
then the other can help u add ur custom branding
am using nextjs 16

"use client";

import { useEffect } from "react";

export default function TawkTo() {
    // ================== embed tawk.to script ==================
    useEffect(() => {
        if (typeof window === "undefined") return;
        const s1 = document.createElement("script");
        const s0 = document.getElementsByTagName("script")[0];
        s1.async = true;
        s1.src = "Add link to the widget";
        s1.charset = "UTF-8";
        s1.setAttribute("crossorigin", "*");
        s0?.parentNode?.insertBefore(s1, s0);
    }, []);

    // // ============= remove tawk.to branding by injecting CSS into its iframe ======================
    // useEffect(() => {
    //     const hideBranding = (iframe: HTMLIFrameElement) => {
    //         try {
    //             const doc = iframe.contentDocument || iframe.contentWindow?.document;
    //             if (!doc) return;

    //             // Skip if already injected
    //             if (doc.getElementById("hide-tawk-branding")) return;

    //             const style = doc.createElement("style");
    //             style.id = "hide-tawk-branding";
    //             style.innerHTML = `
    //             a[href*="tawk.to"] {
    //                 display: none !important;
    //                 visibility: hidden !important;
    //                 opacity: 0 !important;
    //             }
    //         `;
    //             doc.head?.appendChild(style);
    //         } catch {
    //             // cross-origin iframe β†’ expected
    //         }
    //     };

    //     const scanIframes = () => {
    //         document
    //             .querySelectorAll("iframe[title*='chat']")
    //             .forEach((iframe) => hideBranding(iframe as HTMLIFrameElement));
    //     };

    //     // Initial scan
    //     scanIframes();

    //     // Debounce to prevent rapid-fire calls
    //     let debounceTimer: ReturnType<typeof setTimeout>;
    //     const debouncedScan = () => {
    //         clearTimeout(debounceTimer);
    //         debounceTimer = setTimeout(scanIframes, 500);
    //     };

    //     // Only watch childList (new nodes), NOT subtree mutations inside iframes
    //     const observer = new MutationObserver(debouncedScan);
    //     observer.observe(document.body, {
    //         childList: true,
    //         subtree: false, // ← key change: don't watch inside existing nodes
    //     });

    //     return () => {
    //         observer.disconnect();
    //         clearTimeout(debounceTimer);
    //     };
    // }, []);


    // // ================== add ur own branding to tawk.to widget by injecting CSS into its iframe ====================
    useEffect(() => {
        const BRAND_NAME = "bloodykheeng";
        const STYLE_ID = "hide-tawk-branding";
        const IFRAME_SELECTOR = "iframe[title*='chat']";

        const hideBranding = (iframe: HTMLIFrameElement) => {
            try {
                const doc = iframe.contentDocument || iframe.contentWindow?.document;
                if (!doc) return;

                // Inject styles only once
                if (doc.getElementById(STYLE_ID)) return;

                const style = doc.createElement("style");
                style.id = STYLE_ID;
                style.innerHTML = `
                a[href*="tawk.to"] {
                    font-size: 0 !important;
                    pointer-events: none !important;
                    cursor: default !important;
                }
                a[href*="tawk.to"] img,
                a[href*="tawk.to"] svg {
                    display: none !important;
                }
                a[href*="tawk.to"]::after {
                    content: "Powered by ${BRAND_NAME}";
                    font-size: 11px;
                    color: #9ca3af;
                }
            `;
                doc.head?.appendChild(style);
            } catch {
                // cross-origin iframe β†’ expected
            }
        };

        const scanIframes = () => {
            document
                .querySelectorAll(IFRAME_SELECTOR)
                .forEach((iframe) => hideBranding(iframe as HTMLIFrameElement));
        };

        // Initial scan
        scanIframes();

        // Debounce to prevent rapid-fire calls
        let debounceTimer: ReturnType<typeof setTimeout>;
        const debouncedScan = () => {
            clearTimeout(debounceTimer);
            debounceTimer = setTimeout(scanIframes, 500);
        };

        // Only watch childList (new nodes), NOT subtree mutations inside iframes
        const observer = new MutationObserver(debouncedScan);
        observer.observe(document.body, {
            childList: true,
            subtree: false,
        });

        return () => {
            observer.disconnect();
            clearTimeout(debounceTimer);
        };
    }, []);

    return null;
}

@hoangbits

Copy link
Copy Markdown

any of you guys interested in a product that dont force using their logo?

@bloodykheeng

Copy link
Copy Markdown

Have u made ur own app @hoangbits

@hazelcorp2011-cmd

Copy link
Copy Markdown

Please provide new tawk-chat brand removing code because previous code not working..

Below mentioned script not working currently.

<script> var removeBranding = function() { try { const style = document.createElement('style'); style.textContent = '.tawk-padding-small {display:none !important;}'; document.querySelector('iframe[title*="chat"]:nth-child(2)').contentDocument.head.appendChild(style) } catch (e) {} } var tick = 100 setInterval(removeBranding, tick) </script>

@muchisx

muchisx commented May 15, 2026

Copy link
Copy Markdown

@arafathusayn any updates on a new version β˜€οΈ? Seems like the current one no longer works

@bloodykheeng

bloodykheeng commented May 18, 2026

Copy link
Copy Markdown

@hazelcorp2011-cmd πŸ”§ try this β€” it seems the Tawk guys were smart πŸ˜„ they removed the href, so you can’t easily target it anymore with:

a[href*="tawk.to"]

But haha πŸ˜„πŸ˜„πŸ˜„πŸ˜„πŸ˜„ you can still catch that anchor using other CSS attribute selectors. See below πŸ‘‡

method one just hiding the brand

  // ================== embed tawk.to script ==================
  useEffect(() => {
        const BRANDING_SELECTORS = `
        /* expanded widget branding */
        a[style*="font-size: 12px"][style*="font-weight: 400"][style*="padding: 0.5em"],

        /* minimized widget branding */
        a[style*="font-size: 12px"][style*="border-radius: 100px"]
    `;



        const injectStyle = (doc: Document) => {
            if (doc.getElementById("hide-tawk-branding")) return;

            const style = doc.createElement("style");
            style.id = "hide-tawk-branding";

            style.textContent = `
            ${BRANDING_SELECTORS} {
                display: none !important;
                visibility: hidden !important;
                opacity: 0 !important;
                pointer-events: none !important;
                width: 0 !important;
                height: 0 !important;
                overflow: hidden !important;
                max-width: 0 !important;
                max-height: 0 !important;
            }
        `;

            (doc.head || doc.documentElement).prepend(style);
        };

        const handleIframe = (iframe: HTMLIFrameElement) => {
            const apply = () => {
                try {
                    const doc =
                        iframe.contentDocument ||
                        iframe.contentWindow?.document;

                    if (!doc) return;

                    injectStyle(doc);
                } catch {
                    // cross-origin iframe β€” expected for non-tawk iframes
                }
            };

            apply();
            iframe.addEventListener("load", apply);
        };

        // existing iframes
        document.querySelectorAll("iframe").forEach((iframe) => {
            handleIframe(iframe as HTMLIFrameElement);
        });

        // future iframes
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (node instanceof HTMLIFrameElement) {
                        handleIframe(node);
                    }

                    if (node instanceof HTMLElement) {
                        node.querySelectorAll("iframe").forEach((iframe) => {
                            handleIframe(iframe as HTMLIFrameElement);
                        });
                    }
                });
            });
        });

        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
        });

        return () => {
            observer.disconnect();
        };
    }, []);

method two hiding the brand and adding ur own brand

   // ================== embed tawk.to script ==================
    useEffect(() => {
        if (typeof window === "undefined") return;
        const s1 = document.createElement("script");
        const s0 = document.getElementsByTagName("script")[0];
        s1.async = true;
        s1.src = "Add link to the widget";
        s1.charset = "UTF-8";
        s1.setAttribute("crossorigin", "*");
        s0?.parentNode?.insertBefore(s1, s0);
    }, []);

 // //================ latest hide branding and add ur custom branding =================
     useEffect(() => {
        const BRAND_TEXT = "Powered by bloodykheeng";
        const OVERLAY_ID = "custom-tawk-branding";

        // =========================
        // create stable branding overlay
        // =========================
        let branding = document.getElementById(OVERLAY_ID);

        if (!branding) {
            branding = document.createElement("div");
            branding.id = OVERLAY_ID;
            branding.innerText = BRAND_TEXT;

            Object.assign(branding.style, {
                position: "fixed",
                bottom: "30px",
                right: "100px",
                zIndex: "999999",
                background: "#fff",
                padding: "6px 12px",
                borderRadius: "999px",
                fontSize: "11px",
                color: "#6b7280",
                boxShadow: "0 4px 14px rgba(0,0,0,0.12)",
                pointerEvents: "none",
                transition: "opacity .2s ease",
                opacity: "0",
                visibility: "hidden",
            });

            document.body.appendChild(branding);
        }

        // =========================
        // show/hide overlay
        // =========================
        const showBranding = () => {
            if (!branding) return;

            branding.style.opacity = "1";
            branding.style.visibility = "visible";
        };

        const hideBranding = () => {
            if (!branding) return;

            branding.style.opacity = "0";
            branding.style.visibility = "hidden";
        };

        // =========================
        // tawk callbacks
        // =========================
        const w = window as any;

        w.Tawk_API = w.Tawk_API || {};

        w.Tawk_API.onChatMaximized = showBranding;
        w.Tawk_API.onChatStarted = showBranding;
        w.Tawk_API.onChatMinimized = hideBranding;
        w.Tawk_API.onChatHidden = hideBranding;

        // =========================
        // aggressively hide real branding
        // =========================
        const injectStyle = (doc: Document) => {
            if (doc.getElementById("hide-real-tawk-branding")) return;

            const style = doc.createElement("style");

            style.id = "hide-real-tawk-branding";

            style.textContent = `
            a[style*="font-size: 12px"][style*="padding: 0.5em"],
            a[style*="border-radius: 100px"] {
                opacity: 0 !important;
                visibility: hidden !important;
                pointer-events: none !important;
                transform: scale(0) !important;
            }
        `;

            (doc.head || doc.documentElement).prepend(style);
        };

        const handleIframe = (iframe: HTMLIFrameElement) => {
            const apply = () => {
                try {
                    const doc =
                        iframe.contentDocument ||
                        iframe.contentWindow?.document;

                    if (!doc) return;

                    injectStyle(doc);
                } catch {
                    // cross-origin
                }
            };

            apply();

            iframe.addEventListener("load", apply);
        };

        // existing iframes
        document.querySelectorAll("iframe").forEach((iframe) => {
            handleIframe(iframe as HTMLIFrameElement);
        });

        // future iframes
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (node instanceof HTMLIFrameElement) {
                        handleIframe(node);
                    }

                    if (node instanceof HTMLElement) {
                        node.querySelectorAll("iframe").forEach((iframe) => {
                            handleIframe(iframe as HTMLIFrameElement);
                        });
                    }
                });
            });
        });

        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
        });

        return () => {
            observer.disconnect();
            branding?.remove();
        };
    }, []);

@hazelcorp2011-cmd

Copy link
Copy Markdown

@hazelcorp2011-cmd πŸ”§ try this β€” it seems the Tawk guys were smart πŸ˜„ they removed the href, so you can’t easily target it anymore with:

a[href*="tawk.to"]

But haha πŸ˜„πŸ˜„πŸ˜„πŸ˜„πŸ˜„ you can still catch that anchor using other CSS attribute selectors. See below πŸ‘‡

method one just hiding the brand

  // ================== embed tawk.to script ==================
  useEffect(() => {
        const BRANDING_SELECTORS = `
        /* expanded widget branding */
        a[style*="font-size: 12px"][style*="font-weight: 400"][style*="padding: 0.5em"],

        /* minimized widget branding */
        a[style*="font-size: 12px"][style*="border-radius: 100px"]
    `;



        const injectStyle = (doc: Document) => {
            if (doc.getElementById("hide-tawk-branding")) return;

            const style = doc.createElement("style");
            style.id = "hide-tawk-branding";

            style.textContent = `
            ${BRANDING_SELECTORS} {
                display: none !important;
                visibility: hidden !important;
                opacity: 0 !important;
                pointer-events: none !important;
                width: 0 !important;
                height: 0 !important;
                overflow: hidden !important;
                max-width: 0 !important;
                max-height: 0 !important;
            }
        `;

            (doc.head || doc.documentElement).prepend(style);
        };

        const handleIframe = (iframe: HTMLIFrameElement) => {
            const apply = () => {
                try {
                    const doc =
                        iframe.contentDocument ||
                        iframe.contentWindow?.document;

                    if (!doc) return;

                    injectStyle(doc);
                } catch {
                    // cross-origin iframe β€” expected for non-tawk iframes
                }
            };

            apply();
            iframe.addEventListener("load", apply);
        };

        // existing iframes
        document.querySelectorAll("iframe").forEach((iframe) => {
            handleIframe(iframe as HTMLIFrameElement);
        });

        // future iframes
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (node instanceof HTMLIFrameElement) {
                        handleIframe(node);
                    }

                    if (node instanceof HTMLElement) {
                        node.querySelectorAll("iframe").forEach((iframe) => {
                            handleIframe(iframe as HTMLIFrameElement);
                        });
                    }
                });
            });
        });

        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
        });

        return () => {
            observer.disconnect();
        };
    }, []);

method two hiding the brand and adding ur own brand

   // ================== embed tawk.to script ==================
    useEffect(() => {
        if (typeof window === "undefined") return;
        const s1 = document.createElement("script");
        const s0 = document.getElementsByTagName("script")[0];
        s1.async = true;
        s1.src = "Add link to the widget";
        s1.charset = "UTF-8";
        s1.setAttribute("crossorigin", "*");
        s0?.parentNode?.insertBefore(s1, s0);
    }, []);

 // //================ latest hide branding and add ur custom branding =================
     useEffect(() => {
        const BRAND_TEXT = "Powered by bloodykheeng";
        const OVERLAY_ID = "custom-tawk-branding";

        // =========================
        // create stable branding overlay
        // =========================
        let branding = document.getElementById(OVERLAY_ID);

        if (!branding) {
            branding = document.createElement("div");
            branding.id = OVERLAY_ID;
            branding.innerText = BRAND_TEXT;

            Object.assign(branding.style, {
                position: "fixed",
                bottom: "30px",
                right: "100px",
                zIndex: "999999",
                background: "#fff",
                padding: "6px 12px",
                borderRadius: "999px",
                fontSize: "11px",
                color: "#6b7280",
                boxShadow: "0 4px 14px rgba(0,0,0,0.12)",
                pointerEvents: "none",
                transition: "opacity .2s ease",
                opacity: "0",
                visibility: "hidden",
            });

            document.body.appendChild(branding);
        }

        // =========================
        // show/hide overlay
        // =========================
        const showBranding = () => {
            if (!branding) return;

            branding.style.opacity = "1";
            branding.style.visibility = "visible";
        };

        const hideBranding = () => {
            if (!branding) return;

            branding.style.opacity = "0";
            branding.style.visibility = "hidden";
        };

        // =========================
        // tawk callbacks
        // =========================
        const w = window as any;

        w.Tawk_API = w.Tawk_API || {};

        w.Tawk_API.onChatMaximized = showBranding;
        w.Tawk_API.onChatStarted = showBranding;
        w.Tawk_API.onChatMinimized = hideBranding;
        w.Tawk_API.onChatHidden = hideBranding;

        // =========================
        // aggressively hide real branding
        // =========================
        const injectStyle = (doc: Document) => {
            if (doc.getElementById("hide-real-tawk-branding")) return;

            const style = doc.createElement("style");

            style.id = "hide-real-tawk-branding";

            style.textContent = `
            a[style*="font-size: 12px"][style*="padding: 0.5em"],
            a[style*="border-radius: 100px"] {
                opacity: 0 !important;
                visibility: hidden !important;
                pointer-events: none !important;
                transform: scale(0) !important;
            }
        `;

            (doc.head || doc.documentElement).prepend(style);
        };

        const handleIframe = (iframe: HTMLIFrameElement) => {
            const apply = () => {
                try {
                    const doc =
                        iframe.contentDocument ||
                        iframe.contentWindow?.document;

                    if (!doc) return;

                    injectStyle(doc);
                } catch {
                    // cross-origin
                }
            };

            apply();

            iframe.addEventListener("load", apply);
        };

        // existing iframes
        document.querySelectorAll("iframe").forEach((iframe) => {
            handleIframe(iframe as HTMLIFrameElement);
        });

        // future iframes
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (node instanceof HTMLIFrameElement) {
                        handleIframe(node);
                    }

                    if (node instanceof HTMLElement) {
                        node.querySelectorAll("iframe").forEach((iframe) => {
                            handleIframe(iframe as HTMLIFrameElement);
                        });
                    }
                });
            });
        });

        observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
        });

        return () => {
            observer.disconnect();
            branding?.remove();
        };
    }, []);

I was try, but still not remove tawk branding

@hazelcorp2011-cmd

Copy link
Copy Markdown

Anyone can help me for removing tawk chat branding with plan JS Code.

@smlaticc

Copy link
Copy Markdown

Removed branding and also 2 items from dropdown menu.
Tested on tawk.to plugin for wordpress.
Works on mobile also.
Here:

var removeBranding = function () {

  var iframes = document.querySelectorAll("iframe");

  iframes.forEach(function (ifr, idx) {

    try {
      var doc = ifr.contentDocument || (ifr.contentWindow && ifr.contentWindow.document);      
      if (!doc) return;

      var btn = doc.querySelector('a[class*="tawk-button-small"]');
      if (btn) {
        btn.remove();
      }

      var popoutIcon = doc.querySelector("i.tawk-icon.tawk-icon-popout");
      if (popoutIcon) {
        var popoutButton = popoutIcon.closest("button");
        if (popoutButton) {
          popoutButton.remove();
        }
      }

      var byHref = doc.querySelector('a[href*="tawk.to/?utm_source=tawk-messenger"], a[href*="tawk.to/?utm_"]');
      if (byHref) {
        console.log("Removed by href:", byHref);
        byHref.remove();
        return;
      }

      var svgBranding = doc.querySelector('a svg[viewBox="0 0 107 15"]');
      if (svgBranding) {
        var brandingLink = svgBranding.closest("a");
        if (brandingLink) {
          console.log("Removed SVG branding:", brandingLink);
          brandingLink.remove();
          return;
        }
      }

      var nodes = Array.from(doc.querySelectorAll("a, div, span"));
      var poweredBy = nodes.find(function (el) {
        return normalizeText(el.textContent).includes("powered by tawk.to");
      });

      if (poweredBy) {
        console.log("Removed powered by text:", poweredBy);
        var a = poweredBy.tagName === "A" ? poweredBy : poweredBy.querySelector("a");
        (a || poweredBy).remove();
      }
    } 
    catch (e) {

    }
  });
};
setInterval(removeBranding, 250);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment