Idle on Your Terms
Set how long without interaction counts as idle, and get a warning event before it fires, for the session dialog.
NWD Status Checker (User/Tab/Net) answers three questions your app cannot ask on its own: whether the person is still interacting, whether your tab is in front and holding focus, and whether the device has a network connection. Each answer arrives as states and events you can build on, so workflows and conditionals run on measured presence instead of guesswork, and recurring work stops while nobody is watching.
Built for what Bubble does not cover.
Bubble has no native way to tell whether the person is still there. Workflows keep running for someone who walked away, and a tab left open in the background looks exactly like one being used.
Set how long without interaction counts as idle, and get a warning event before it fires, for the session dialog.
Activity ranges from keyboard only up to taps, clicks, keys and movement, so a reading page and a form can disagree.
Working in a second tab of your app keeps the person active, instead of every tab counting its own silence.
Tab visibility and window focus arrive as separate signals, because a tab in view is not always the one being typed into.
The device losing and regaining its connection, from the browser's own events, apart from anything the person is doing.
Four actions let your app reset the timer, mark someone idle, and pause or resume detection on demand.
In detail
Place it anywhere on a page or a reusable that is always present while the user is signed in, and ensure it is always visible.
In Bubble, any element-type plugin must be visible to work properly.
Go idle after is how many seconds without interaction count as idle. The two labels are the texts returned by the status state.
Use the exposed events to react when the person, the tab or the network changes, read the exposed states to use the current situation anywhere in your app, and run the exposed actions when your app needs to drive the detection itself.
Sets how many seconds without interaction before the user counts as idle. It accepts any number or a dynamic value from your app, so the threshold can follow the plan, the role or the screen. Zero marks the user idle as soon as the element loads.
Sets the text published in User status label while the user is interacting. It exists for binding straight to a text element; a conditional should use User is idle, which is a yes/no and does not depend on the wording.
Sets the text published in User status label once the user goes idle.
Chooses which interactions reset the idle timer. The three options build on each other, from the narrowest to the widest. Keyboard only counts typing and nothing else, which suits a screen the visitor reads while typing elsewhere. Taps clicks and keys adds deliberate actions, including touch, and ignores a pointer that merely moves. Taps clicks keys and movement adds pointer movement, scrolling and touch dragging, which is the default because a visitor reading a long page is present without clicking anything. Pick the middle one when presence has to mean a deliberate act, as in a session timeout, since a nudged desk moves the pointer on its own.
Keeps the person active while they interact with your app in another tab or window. Each tab runs its own timer, so with this off someone working in a second tab is reported idle in the first. It carries activity between tabs of the same origin, which means the same scheme, host and port: another site can neither hear it nor speak to it, and it never reaches another browser or another device. Two cases are worth knowing: the test version and the live version of your app share an origin, so working in one keeps the other active; and your Bubble address and your own domain are different origins, so a tab on each will not see the other.
Fires the User idle warning event this many seconds before the user goes idle, which is what a "your session expires in 30s" dialog needs. Zero turns the warning off.
Publishes User seconds idle on this cadence, for a live counter on screen. It comes off, and off is the right default: every published state makes Bubble re-evaluate everything bound to it, so a value republished every second re-renders conditionals every second. For a countdown without that cost, use User goes idle at and let the page do the arithmetic.
Publishes Tab is visible and Tab is focused, and fires the four tab events, when the visitor switches away from your tab or window and back. Visibility and focus are different signals: switching to another tab in the same window, or minimising, turns visibility off, while moving to another window or another monitor leaves the tab visible and only removes focus. Neither is the same as idle, which measures interaction rather than attention.
Fires Pointer left through the top when the pointer leaves the page by its top edge, where the tabs, the address bar and the close button are. It is a guess and not a detection: no browser tells a page that someone is about to switch tabs, because the shortcuts belong to the browser and the tab strip is outside the page. It also fires when the visitor reaches for a bookmark or the address bar, it cannot happen at all on touch devices, and it means nothing when the window is not at the top of the screen. Useful for a cart or a draft, never for a session or anything about security. Off by default for all of those reasons.
Publishes Network is online and fires the network events when the device gains or loses its network connection. Note what this measures: the device being attached to a network, not the internet working and not your app being reachable. False is reliable; true only means there is a network: a hotel captive portal, a router whose uplink is down or your own server being offline all look online from here.
Values the element exposes for the rest of the page to read.
This element watches three different things, and the prefix of every name tells you which: the person interacting, the tab being in front, and the device's network. They are independent of each other. A visible tab is not always a focused one, someone can be focused and idle at the same time, and the network can drop with nobody touching anything.
Yes once the user has gone the configured time without interacting. This is what a conditional should read: it does not depend on the label wording, which the app may translate.
The instant of the last interaction counted as activity. It updates on every return to activity, not on every mouse move.
The instant the user will be marked idle if nothing else happens, published once per activity. Subtract the current date from it for a countdown without the plugin republishing a value every second.
The wording from the two label fields, following the current state. It exists for binding to a text element.
Seconds since the last activity, published only while the tick above is on. With the tick off it stays empty, and the countdown comes from User goes idle at.
Yes while the Pause activity detection action is in effect. Idle time stops being counted and interactions stop resetting it, so the user neither goes idle nor comes back until detection resumes. Reset returns it to no.
Yes while your tab is the one in front. It comes from the browser's own visibility signal and fires reliably, including when the visitor switches apps on a phone.
Yes while this window has keyboard focus. It is not the same as Tab is visible: focusing another window, or another monitor, leaves your tab visible while this turns no. For "is the person here", read this one; for "is the tab in front", read the other.
The instant the tab last went to the background.
Whether the device has a network connection. No is reliable; yes only means a network exists, and says nothing about a captive portal, a router whose uplink is down or your own server being up.
The instant the device last lost its network connection.
Where a workflow can start.
Fires once when the user crosses the idle threshold. It does not repeat while they stay idle.
Fires once when an idle user interacts again. It does not fire on every interaction, only on the return.
Fires the configured number of seconds before the user goes idle, and only when that field is above zero. It fires once per idle approach and resets on any activity.
Fires when the visitor switches to another tab, another window or another application, and also when the tab is being closed, because the browser marks the page hidden before it goes away. This is the reliable moment to save a draft or stop a timer: there is no separate closing event, since nothing a page can listen for survives a killed process or a swipe-away on a phone.
Fires when your tab comes back to the front.
Fires when the window stops receiving keyboard input, which happens when the visitor moves to another window or another application while your page stays on screen.
Fires when the window receives keyboard input again.
Fires when the pointer leaves the page by its top edge, with the detection turned on. Read it as an intention, not a fact: the visitor may be going for a bookmark, the address bar or another tab, and someone switching with the keyboard produces nothing at all. It fires once per exit and rearms when the pointer comes back over the page.
Fires when the device loses its network connection.
Fires when the device regains a network connection. It does not mean your app is reachable again: the device may be on a network that cannot reach it.
What a workflow can tell the element to do.
Counts this moment as activity without the user touching anything, for a save, an API answer or any workflow step that proves the session is alive.
Marks the user idle immediately, without waiting for the timer, for an explicit "I am away".
Stops counting idle time, for a video playing or a long upload where the user is present without interacting.
Starts counting again and treats this moment as activity.
By a countdown you configure. Every interaction the element is watching restarts it, and when it runs out the status state flips and the idle event fires. Nothing is sent anywhere and nothing is measured on a server: the whole decision happens in the person's browser, from events the browser already reports.
Yes, if you leave that option on, and it is on by default. Without it each tab counts its own silence, so someone working in a second tab is reported idle in the first. It carries activity between tabs of the same origin, which means the same scheme, host and port. Two cases are worth knowing: the test version and the live version of your app share an origin, so working in one keeps the other active, and your Bubble address and your own domain are different origins, so a tab on each will not see the other.
Visible means the tab is the one on screen in its window. Focused means that window is the one receiving the keyboard. They part company often: a visible tab in a window behind another app is not focused, and someone reading your page with a video call in front of it is visible and unfocused at the same time. The element exposes the two separately so you can decide which one your feature actually needs.
Yes, and there are two ways. The cheapest is to read the state User goes idle at and let your own countdown work from it, which costs nothing while it runs. If you would rather the element do the counting, set Publish seconds idle every and it publishes the remaining seconds at that interval. Leave it at zero unless you are showing the number: publishing every second is work the page does not need otherwise.
No, and that is deliberate. Browsers do not report a closing tab reliably: the event arrives late, twice, or never, and it behaves differently on phones, where a tab is usually suspended rather than closed. An earlier version of this plugin exposed it anyway and the result was workflows firing on people who had not left. What is measurable is the tab being hidden, which covers switching away, minimising and locking the screen, and that is what Tab was hidden reports. There is also an optional exit intent event for the pointer leaving through the top edge, which is a guess about intention and not a closing tab, and it is off by default for that reason.
The element was rebuilt. Every option, state and event was replaced, so an app installed before this version keeps rendering but stops reacting. Plan one pass through the workflows that used it.
This plugin is maintained by GCS Studios and is part of the NWD Utility family, plugins that give your app a capability it does not have natively, working on their own instead of attaching to something you already built. Each one does one job end to end and hands you the result as states, events and actions you can build on, and is tested in real applications before release. See more plugins on the GCS Studios contributor page.