PHPackages                             kdjfs/user-presence - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. kdjfs/user-presence

ActiveKirby-plugin

kdjfs/user-presence
===================

Shows who is currently working in the Kirby Panel, right in the users view

1.0.0(today)01↑2900%MITPHPPHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0CI passing

Since Jul 30Pushed todayCompare

[ Source](https://github.com/kdjfs-design/kirby-user-presence)[ Packagist](https://packagist.org/packages/kdjfs/user-presence)[ Docs](https://github.com/kdjfs-design/kirby-user-presence)[ Fund](https://buymeacoffee.com/janstieler)[ Fund](https://paypal.me/kdjfs)[ RSS](/packages/kdjfs-user-presence/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (3)Versions (2)Used By (0)

User Presence
=============

[](#user-presence)

[![Shows who is currently working in the Kirby Panel, right in the users view — the users list with a green dot for an active admin and a blue dot for an idle editor](headerimage.jpg)](headerimage.jpg)

[![Deutsche Fassung](https://camo.githubusercontent.com/a79eb63e201938e18d1b33ec824338b2ac4d212a985b3bf7169d4e072104b996/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c616e672d44452d4432414132363f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d353535353535)](https://github.com/kdjfs-design/kirby-user-presence/blob/main/README.de.md)

[![Latest version](https://camo.githubusercontent.com/ad1559b0d22d0db988b6528a0914544151a99f425460b21bd97452c269cf9dc2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b646a66732f757365722d70726573656e63653f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d353535353535)](https://packagist.org/packages/kdjfs/user-presence)[![Tests](https://camo.githubusercontent.com/1fd4c31afa70b2947fbeb2218a9558dca1413f83964cbd13c3a97dee828e716b/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6b646a66732d64657369676e2f6b697262792d757365722d70726573656e63652f74657374732e796d6c3f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d353535353535266c6162656c3d5465737473)](https://github.com/kdjfs-design/kirby-user-presence/actions/workflows/tests.yml)[![License](https://camo.githubusercontent.com/df5a9257a6eee20cc56ac7410b47539816b7e44f111bb661c39388782d603023/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f6b646a66732f757365722d70726573656e63653f7374796c653d666f722d7468652d6261646765266c6162656c436f6c6f723d353535353535)](LICENSE)

Shows who is currently working in the Kirby Panel, right in the users view.

DotMeaninggreenactive in the Panel within the last few minutesbluesigned in, but idle for a whileno dotnot signed inGreen means worked in the Panel: opened a view, edited a page, saved a field. An open tab on its own is not activity, so a forgotten browser window turns blue like everyone else.

Three tabs filter the list, and they combine with the role filter (`/users?role=editor&presence=active`):

TabQueryShows*Active*`presence=active`the green dots*Idle*`presence=idle`the blue dots*Signed in*`presence=signedin`both, everyone with a session*Signed in* is the union of the other two, so someone working right now appears under *Active* and under *Signed in*, but never under *Idle*.

A presence tab always shows every role: *Active* means every active user, never a subset. To combine, pick the presence first and the role second — the role tabs keep an active presence filter. Kirby's own *All* tab clears both at once and is the way back to the unfiltered list.

The active dot pulses. Anyone who has asked for less motion in their system settings (`prefers-reduced-motion`) gets it at rest — colour and meaning stay the same.

Requirements
------------

[](#requirements)

Kirby 5.2 or newer, PHP 8.2 or newer. No build step and no npm.

Installation
------------

[](#installation)

**With Composer**

```
composer require kdjfs/user-presence

```

The `getkirby/composer-installer` places the plugin in `site/plugins/`.

**Without Composer**

Copy the directory to `site/plugins/user-presence/`. The plugin loads its own classes, so no autoloader is required.

Options
-------

[](#options)

In `site/config/config.php`, all values in seconds:

```
'kdjfs.user-presence' => [
    'activeWithin'   => 300,   // green up to here, blue after
    'sessionTimeout' => 1800,  // no dot beyond this
    'throttle'       => 60,    // minimum gap between writes
    'staleAfter'     => 120,   // when the stale notice appears
],

```

Presence is kept in the plugin cache, which is enabled by default (`kdjfs.user-presence.cache`). A different cache type can be configured as for any Kirby plugin.

If the cache is unavailable, the plugin follows Kirby's own convention: with `debug` enabled the request fails with the original error message, so a misconfigured cache is fixed rather than worked around. In production the message goes to the error log, every user counts as offline, and the Panel keeps working. Nothing is swallowed silently either way.

**Which cache type.** The default file cache is fine for a few hundred users. Beyond that a shared in-memory cache is noticeably quicker, because filtering by presence reads one entry per user:

```
'kdjfs.user-presence' => [
    'cache' => ['type' => 'apcu'],
],

```

Kirby's `memory` type is **not** the one you want: it lives for a single request only, so every user would always appear offline. `apcu` needs no extra service; use `memcached` or `redis` when several web servers have to share the data. Losing it on a restart is harmless — everyone shows offline until their next click.

Language
--------

[](#language)

The Panel labels ship in English and German and follow the Panel language of the signed-in user. Any other language falls back to English.

A language is added in `site/config/config.php`, no plugin required:

```
'extensions' => [
    'translations' => [
        'fr' => [
            'kdjfs.user-presence.tab.active'   => 'Actif',
            'kdjfs.user-presence.tab.idle'     => 'Inactif',
            'kdjfs.user-presence.tab.signedin' => 'Connecté',
            'kdjfs.user-presence.stale'        => 'État d’il y a {{ minutes }} minutes.',
            'kdjfs.user-presence.refresh'      => 'Actualiser',
        ],
    ],
],

```

The `extensions` wrapper is what makes it work: only `api`, `routes` and `hooks` are read straight from the options, everything else has to sit below that key. A `translations` key at the top level of the config has no effect.

The same route renames single labels, because config extensions are registered after the plugins and merged recursively — so this changes one word and leaves the rest of the German set alone:

```
'extensions' => [
    'translations' => [
        'de' => ['kdjfs.user-presence.tab.idle' => 'Abwesend'],
    ],
],

```

A language that others should get too is welcome as a pull request; it then ships with the plugin instead of living in one project's config.

Privacy
-------

[](#privacy)

The plugin stores one timestamp per user — when they were last seen in the Panel — and shows everyone with access to the users view who is currently working.

It is built to keep as little as possible:

- **No history.** Only the latest timestamp is held, never a trail.
- **Automatic deletion.** Entries live in the cache with `sessionTimeout` as their lifetime, 30 minutes by default, and expire on their own.
- **Removed on sign-out**, immediately.
- **No export, no API, no third party.** The data never leaves the site.

Even so, in an employment context a display of colleagues' activity is a technical facility *capable* of monitoring conduct and performance. Under German law that can require the works council's agreement (§ 87 (1) no. 6 BetrVG), and comparable rules exist in other jurisdictions — being capable of it is enough, an intention to monitor is not required. This is not legal advice: please check it before rolling the plugin out to a team.

Limitations
-----------

[](#limitations)

The list shows the state at the time it was loaded. If it stays open, a notice appears offering to refresh it. There is deliberately no automatic refresh in the background: it would put constant load on the server for information that is rarely urgent.

Closing the browser without signing out leaves a user marked as signed in until `sessionTimeout` expires. They turn blue after `activeWithin`, so the display never claims presence that isn't there.

Your own account is always green and never appears under *Idle* — not as a matter of principle, but because the display only changes when you act: loading the list is activity, and so is the refresh from the notice. Watching your own entry grow old would take a refresh in the background, and that refresh would have to be excluded from activity itself — the way the keep-alive ping is. There deliberately is no such refresh, see the paragraph above.

With a role and a presence filter set at once, only the presence tab is underlined. Both filters still apply — the tab bar can mark just one of them.

Support the work
----------------

[](#support-the-work)

This plugin is free and stays that way. If it saves you some time, you are welcome to buy me a coffee or chip in directly:

[![Buy Me A Coffee](https://camo.githubusercontent.com/0cf29a542375e1a46e84d8bf5805a4e5c0a6ee98b6547ccdc0c55eed49d99c69/68747470733a2f2f63646e2e6275796d6561636f666665652e636f6d2f627574746f6e732f76322f64656661756c742d79656c6c6f772e706e67)](https://buymeacoffee.com/janstieler) [![Donate via PayPal](https://camo.githubusercontent.com/c7f82721b1fedcc70a6e850e2b5ec6c478bcc80a13ec9ac933e9e1eddd1f20f8/68747470733a2f2f7777772e70617970616c6f626a656374732e636f6d2f6469676974616c6173736574732f632f776562736974652f6d61726b6574696e672f617061632f43322f6c6f676f732d627574746f6e732f6f7074696d697a652f34345f59656c6c6f775f50617950616c5f50696c6c5f427574746f6e2e706e67)](https://paypal.me/kdjfs)

Internals
---------

[](#internals)

How the plugin is put together, and which Panel behaviour it relies on, is described in [ARCHITECTURE.md](ARCHITECTURE.md).

Licence
-------

[](#licence)

MIT — see [LICENSE](LICENSE).

---

Eine deutsche Fassung dieser Datei liegt unter [README.de.md](README.de.md).

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance100

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/ef6fd78eb64a4bf7832b7afa924eccded22dec0638833c2f95095f3a59af516f?d=identicon)[janstieler](/maintainers/janstieler)

---

Top Contributors

[![janstieler](https://avatars.githubusercontent.com/u/754880?v=4)](https://github.com/janstieler "janstieler (55 commits)")

---

Tags

Userskirbykirby-pluginkirby-cmspanelpresence

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kdjfs-user-presence/health.svg)

```
[![Health](https://phpackages.com/badges/kdjfs-user-presence/health.svg)](https://phpackages.com/packages/kdjfs-user-presence)
```

###  Alternatives

[medienbaecker/kirby-modules

Easily add modules to your pages

895.5k1](/packages/medienbaecker-kirby-modules)[bnomei/kirby3-janitor

Kirby Plugin for running commands like cleaning the cache from within the Panel, PHP code or a cronjob

9342.8k2](/packages/bnomei-kirby3-janitor)[bnomei/kirby-janitor

Kirby Plugin for running commands like cleaning the cache from within the Panel, PHP code or a cronjob

935.5k2](/packages/bnomei-kirby-janitor)[grommasdietz/kirby-blueprint-areas

Add custom Panel areas via blueprints on Kirby CMS

211.2k](/packages/grommasdietz-kirby-blueprint-areas)[grommasdietz/kirby-hidden-characters

Kirby CMS plugin for visualising hidden characters in the Panel

461.9k](/packages/grommasdietz-kirby-hidden-characters)[bnomei/kirby3-feed

Generate a Atom/JSON/RSS-Feed and XML-Sitemap from Pages-Collections

7227.2k](/packages/bnomei-kirby3-feed)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
