Photopea adds remover

Remove the ads side bar on desktop, and the bottom ads banner on mobile. Also removes ad related popups.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Photopea adds remover
// @namespace    https://www.photopea.com/
// @version      4/13/2026
// @description  Remove the ads side bar on desktop, and the bottom ads banner on mobile. Also removes ad related popups.
// @author       pooiod7
// @match        https://*.photopea.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=photopea.com
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    window.originalVisualViewport = window.visualViewport;

    async function addCustomEvent() {
        // mobile devices get adds on the bottom, so push them out
        if (window.screen.width < 750 && /Mobile|Android|iPhone|iPad/i.test(navigator.userAgent)) {
            document.addEventListener('resizecanvas', () => {
                window.innerHeight = document.documentElement.clientHeight + (100);
                document.body.style.overflow = "hidden";
            });
        } else {
            document.addEventListener('resizecanvas', async () => {

                var app = document.querySelector('.flexrow.app');

                var viewportWidth = window.innerWidth;
                var docWidth =  document.documentElement.clientWidth;

                var target = Array.from(app.children).find(function(d) {
                    return d.querySelector('.alertcont');
                })

                Array.from(app.children).forEach(function(el) {
                    if(el !== target){
                        el.style.display = 'none';
                    }
                })

                var inner = app.querySelector('.flexrow .panelblock.mainblock');

                if(inner){
                    var rect = inner.getBoundingClientRect();

                    var offset = viewportWidth - rect.width;

                    var pageWidth = docWidth;
                    var adsWidth = offset;

                    var newWidth = pageWidth + adsWidth;

                    document.documentElement.style.width = newWidth + 'px';
                    document.body.style.width = newWidth + 'px';

                    Object.defineProperty(window, 'visualViewport', {
                        configurable: true,
                        value:new Proxy(originalVisualViewport, {
                            get: function(target, property){
                                if (property == 'width'){
                                    return pageWidth + adsWidth;
                                }
                                return target[property];
                            }
                        })
                    })

                    Object.defineProperty(window, 'innerWidth', {
                        configurable: true,
                        get: function(){
                            return pageWidth + adsWidth;
                        }
                    })

                    // imagine using intervals
                    if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
                    setTimeout(()=> {
                        rect = inner.getBoundingClientRect();
                        if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
                    }, 100);
                    setTimeout(()=> {
                        rect = inner.getBoundingClientRect();
                        if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
                    }, 500);
                    setTimeout(()=> {
                        rect = inner.getBoundingClientRect();
                        if (rect.left != 0) document.body.style.marginLeft=(-rect.left) + 'px';
                    }, 1000);
                }
            });
        }
    }

    document.documentElement.setAttribute('onreset', `(${addCustomEvent})()`);
    document.documentElement.dispatchEvent(new CustomEvent('reset'));
    document.documentElement.removeAttribute('onreset');

    function resize(event = {}) {
        if (!event.skip) {
            document.dispatchEvent(new CustomEvent('resizecanvas'));
            var resizeEvent = new Event('resize');
            resizeEvent.skip = true;
            window.dispatchEvent(resizeEvent);
        }
    }

    let debounce;
    window.addEventListener('resize', event => {
        clearTimeout(debounce);
        debounce = setTimeout(() => resize(event), 100);
    });

    function doresizewhenready() {
        new Promise((resolve) => {
          const observer = new MutationObserver(() => {
            const element = document.querySelector(".flexrow.app .flexrow .panelblock.mainblock");

            if (element) {
              observer.disconnect();
              resolve(element);
              window.dispatchEvent(new Event("resize"));
            }
          });

          observer.observe(document.documentElement, {
            childList: true,
            subtree: true,
          });
        });
    } doresizewhenready();
    setTimeout(doresizewhenready, 1000);
    setTimeout(doresizewhenready, 2000);

    document.querySelectorAll("div.alertpanel.tpanel").forEach(removeAlert);

    // remove the "something is changing our source code" popup
    const observer = new MutationObserver(mutations => {
      for (const m of mutations) {
        for (const node of m.addedNodes) {
          if (node.nodeType !== 1) continue;

          if (node.matches?.("div.alertpanel.tpanel")) {
              if (node.textContent.includes("changing our source")) {
                node.remove();
              }
          }

          node.querySelectorAll?.("div.alertpanel.tpanel").forEach(removeAlert);
        }
      }
    });

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

    setTimeout(() => observer.disconnect(), 10000);

    // Hide adblocker popup
    const check = () => {
        const els = Array.from(document.querySelectorAll("*"));
        for (const el of els) {
            if (el.innerText && el.innerText.includes("Are you using an ad blocker")) {
                console.log("Detected target text");

                const btn = el.parentElement?.parentElement?.querySelector("button");
                if (btn) {
                    setTimeout(() => {
                        btn.click();
                    }, 200);
                }
            }
        }
    };

    const obs = new MutationObserver(check);
    obs.observe(document.body, { childList: true, subtree: true });
    check();
})();