Support
Why a donation alert fires twice after refreshing the browser source

Why one donation triggers two alerts after refreshing the browser source

Why one donation triggers two alerts

After refreshing the browser source, the page starts over. The script connects to the server again, subscribes to events, and creates handlers to display notifications. If the old handler isn't removed or two connections run at the same time, a single donation event gets processed multiple times.

The refresh itself isn't necessarily the cause of the failure. It often only exposes an error in the connection logic. For example, the initialization function may run on page load, then again when the connection is restored, and once more after receiving a service message. Each run adds a new subscription to the donation event.

As a result, the server sends one donation object, but the browser calls the same function twice. Sometimes the duplication happens on the server side: the application treats the new connection as a separate recipient and sends the event to both the old and the new session. So first you need to determine where the repeat appears: in the source, in the handler, or at the display stage.

How to find where the duplicate occurs

Start with a simple test. Open the browser source link in a separate window or tab, leave only one instance of the page, and send a test event. If the alert appears once, the cause is most likely related to scene settings or multiple instances of the source. If it duplicates already in a separate tab, check the page code and the subscription mechanism.

It helps to split donation processing into several stages: receiving the event, validating the event, queuing the alert, and rendering. Temporarily log a marker at each stage in the log or console. If the receipt entry appears twice, the problem lies before the visual layer. If the event is received once but there are two items in the queue, the error is in the handler. If the queue contains one item but there are two alerts on screen, check the display function and the HTML container.

For diagnostics, add the event's identifier to each event if it's passed in the donation data. Log this identifier on receipt and before display. The same identifier in two calls shows that one event was processed twice. Two different identifiers indicate two deliveries, which need to be investigated separately.

Don't just check the number of tabs. In OBS, two instances can appear after copying a scene, adding a nested scene, or re-adding a browser source with the same address. Sometimes one source stays in a separate layer and the second is added on top of it. Visually this looks like a double alert, even though the event arrived once.

Resubscription after reconnecting

The most common cause is that the handler is added on every connection but not removed on disconnect. Simplified, the problem looks like this: the function calls socket.on with an alert-display handler, then the connection drops, the app reconnects and repeats socket.on. After that, one incoming donation triggers two functions. On the next reconnect there may be even more.

The same error occurs with a regular addEventListener. If the initialization function is called several times, the browser adds several listeners for the same event. Checking an "already initialized" flag doesn't always help: a full page refresh resets the variables, but on a reconnect within the same page the problem persists.

The subscription should be created once per connection lifecycle, and the old subscription should be explicitly removed before the new one. For event handlers, use removeEventListener with the same function reference that was passed on connection. For socket libraries, you usually need an off method, unsubscribe, or a similar way to detach.

A minimal socket pattern might look like this: const onDonation = data => showAlert(data); socket.off('donation', onDonation); socket.on('donation', onDonation); function cleanup() { socket.off('donation', onDonation); window.removeEventListener('beforeunload', cleanup); socket.close(); } window.addEventListener('beforeunload', cleanup);

What matters here isn't the specific library but the order of actions. The handler is stored in a variable, so it can be removed with the same reference. Before a new subscription, the old one is removed, and when the page closes or the source stops, cleanup runs. If a new socket is created on every run, close the old one first and only then create the new one. Otherwise both connections may keep receiving the same data.

When reconnecting, also close the old connection and clear related timers. Otherwise the old socket may keep receiving data while the new one is already running. This happens especially often when the code starts a new reconnect timer without canceling the previous one.

What to check in OBS and the browser source

If a separate window shows the alert once, move on to the scene. Stop the preview, temporarily remove extra layers, and leave one browser source. Then check the behavior on the target scene. This test is faster than checking all scenes and filters at once.

  • Look for two sources with the same page address.
  • Check scene copies and nested scenes where the same overlay may be present.
  • Make sure the alert isn't displayed simultaneously by the browser source and another layer with the same page.
  • After changing settings, fully restart the source rather than just switching scenes.

Sometimes an old browser source tab lingers in OBS after the URL or parameters change. Closing and re-adding the source helps test the hypothesis, but it doesn't replace fixing the code. If the problem returns after every refresh, look for re-registration of the handler or a double connection.

Also keep the disconnect delay in mind. On refresh, the old session may not close instantly. If the server considers it active for a few seconds, an event arriving in that window can end up in two sessions. Proper server logic should remove inactive connections and not leave a subscription after the page closes.

Two golden bells on the streamer's desk illustrate duplicate donation alerts.

Protection against re-delivery of a single event

Even when the browser source works correctly, a single event can sometimes be delivered twice. This is possible during connection recovery, message resending, or a failure between receiving an event and confirming its processing. That's why the alert handler should be resilient to repeats.

The best approach is to check the donation's unique identifier. Before queuing the event, save its identifier in a set of already processed events. If that identifier has been seen before, skip the repeat. Keep the list for a limited time so it doesn't grow indefinitely.

Don't rely only on the amount, sender name, or message text for this. Two different donations can have identical data. Time-based checks are also unreliable: several different donations can arrive almost simultaneously. If there's no identifier, you can temporarily compare a combination of fields and timestamps, but that's a fallback with the risk of mistakenly merging two events.

Duplicate protection should sit before the alert is shown, not inside the animation. Otherwise the second call will still add an element to the page, play the sound, or put another entry in the queue. Control the queue separately: one event should be added to it once, and a repeat call shouldn't start a second independent queue.

If the event is passed between multiple tabs or components, check whether several recipients are processing it at once. A single shared message channel may be connected to several handlers. In that case, either keep a single consumer or explicitly define which component is responsible for showing the alert.

Why clearing the cache doesn't always help

After refreshing the browser source, people often advise clearing the cache. This can fix the situation if an old version of the script was loaded, but the cache doesn't remove extra handlers in an already running page and doesn't close a second copy of the source. If the duplicate keeps repeating after every reconnect, the cause is almost certainly in the connection logic or the scene structure.

Check whether the new version of the files is actually being loaded. Temporarily change the resource URL or use the provided update mechanism, then restart the browser source. After that, run the test again with one window and one instance of the source. Don't add random parameters to the link permanently: this can create many cache variants and make diagnostics harder.

If an intermediate cache or service worker is in use, it can also serve a stale script. In that case, compare the version of the loaded file with the version you expect to see. But even with an old file, you need to fix the cause of the resubscription, otherwise the problem will return after the next refresh.

What to check in the alert code

First, find all the places where socket.on, addEventListener, connection functions, and queue startup are called. Sometimes the problem isn't one handler but that two different modules independently listen to the donation event and each triggers its own display.

Then check the component lifecycle if the alert is rendered through a framework. The subscription is placed in an effect or similar block and returns a cleanup function. You must not create a new handler on every state update without removing the previous one. In plain JavaScript, it's important to store a reference to the active socket and the current handler so they can be properly closed when the page stops.

Check the reconnect timers. A new timer shouldn't start on top of an old one. Otherwise, after several drops, parallel connection attempts are created, and with them extra subscriptions. Each timer needs to be cleared with clearTimeout or clearInterval if it's no longer needed.

Also look at the code that shows the alert. It must not simultaneously add an element to the queue and immediately call the display function for the same object. Also check whether the animation restarts when the element's state changes. If the log shows one receipt and one queue entry but there are two notifications on screen, that's exactly where to look.

Diagnostics checklist: what to do in order

  1. Open the browser source URL in a separate tab and send one test donation. Note whether the duplicate appears outside OBS.
  2. Leave only one instance of the source in the scene. Check scene copies, nested scenes, and layers where the same address may be present.
  3. Add logging with the event identifier at the receipt, queuing, and display stages. This will show where the number of objects increases.
  4. Find all calls to socket.on and addEventListener. Check whether old handlers are removed via socket.off and removeEventListener with the same function reference.
  5. Check reconnection: is the old socket closed, is the old timer canceled, and is a new subscription created on top of the previous one.
  6. Add a check of the donation's unique identifier before queuing, then fully restart the source and repeat the test with a single event.

If a separate tab receives the event once but OBS shows two alerts, look for a second instance of the source or duplication in the scenes. If the event arrives twice already in a separate tab, check subscriptions, connections, and server delivery. If receipt and queuing are logged once but there are two notifications on screen, the problem lies in the visual layer.

Last Articles

New website design

What has changed in design and functionality We have updated the website to make working with it faster and more convenient. The main changes affect ..

15/08/2026 New

News SP

Good afternoon, I've collected all the news during this time.: 1. The main news is that prices for twitch viewers have been greatly reduced, while Tw..

08/04/2026 Update

We have collected all current promotions and giveaways for you until 01.01.2026

1. Use promo code "December2025" for a 15% discount for all our viewers2. We have reduced the base prices for our configurator and the most affordable..

26/12/2025 Ended

Cooperation with squads and resellers

Twitch services are working stably, so we are ready to cooperate with squads, resellers, service owners, bot owners, and many others.Individual te..

22/10/2025 For partners

Twitch viewers are stable, but there are some nuances.

We have completely updated our Twitch viewer services, and they are now working stably. We only use high-quality IP addresses for the viewers.The ..

22/10/2025 Update

Twitch Viewer Configurator and Control Panel

Hello everyone! Today, we are announcing a new feature—"Twitch Viewer Configurator". Now, you can customize any plan for your Twitch channel. Choo..

15/06/2025 New

If YouTube is blocked, where to stream now?

Greetings, I have compiled a guide for streamers, which will be very relevant at the moment. Now YouTube and twitch have disabled monetization from vi..

16/03/2022 Important

Reseller Panel API SP

We have finally developed the APINow it will be more convenient for our partner sites to work with us.To update the maximum tariffs for YouTube, an up..

02/09/2021 For partners

PARTNERS AND REFERRALS: NEW TERMS!

Due to the huge popularity of the partnership services and referral program, we have made a cooperation table. The essence is very simple: more live a..

12/08/2020 For partners

Viewer control panel [Twitch | Kick | YouTube | VK Video Live]

Build your own custom plan
Deposit funds, one-click order, discounts and bonuses are available only for registered users. Register.
If you didn't find the right service or found it cheaper, write to our support in Telegram or chat, and we will resolve any issue.
New

Telegram bot @BOT_SP_RU_BOT

Order or repeat in a minute, balance and order statuses — right in Telegram

Repeat orderOrder statusesBalance top-upPromo codes