diff --git a/src/plugins/sib-history-scroll.js b/src/plugins/sib-history-scroll.js
new file mode 100644
index 0000000000000000000000000000000000000000..f514a52dd5a28b58a2c1492d5f9fed950489cc0a
--- /dev/null
+++ b/src/plugins/sib-history-scroll.js
@@ -0,0 +1,68 @@
+converse.plugins.add('sib-history-scroll', {
+    overrides: {
+        ChatRoomView: {
+            events: {
+                'wheel .chat-content__messages': 'onScrolledUp',
+            },
+        },
+        ChatBoxView: {
+            events: {
+                'wheel .chat-content__messages': 'onScrolledUp',
+            },
+
+            /**
+             * Fetch the old messages if there is no scroll available.
+             * @param {WheelEvent} ev
+             */
+            onScrolledUp(ev) {
+                const scrollable = this.msgs_container.clientHeight < this.msgs_container.scrollHeight
+                if (ev.deltaY < 0 && !scrollable) {
+                    const _converse = this.__super__._converse;
+                    _converse.api.trigger('chatBoxScrolledUp', this);
+                    converse.env.utils.safeSave(this.model, {
+                        scrolled: true,
+                        scrollTop: 0,
+                    });
+                }
+            },
+
+            /**
+             * Fix the scroll event when contained in the <solid-xmpp-chat> element.
+             * Replace the ev.target with the first element in composed path.
+             *
+             * @param {Event} ev
+             * @private
+             */
+            _markScrolled: function (ev) {
+                const _converse = this.__super__._converse;
+
+                let scrolled = true;
+                let scrollTop = null;
+                const is_at_bottom = this.msgs_container.scrollTop + this.msgs_container.clientHeight >= this.msgs_container.scrollHeight;
+
+                // TODO: use composed path
+                const target = ev.target || ev.path[0];
+
+                if (is_at_bottom) {
+                    scrolled = false;
+                    this.onScrolledDown();
+                } else if (this.msgs_container.scrollTop === 0) {
+                    /**
+                     * Triggered once the chat's message area has been scrolled to the top
+                     * @event _converse#chatBoxScrolledUp
+                     * @property { _converse.ChatBoxView | _converse.ChatRoomView } view
+                     * @example _converse.api.listen.on('chatBoxScrolledUp', obj => { ... });
+                     */
+                    _converse.api.trigger('chatBoxScrolledUp', this);
+                } else {
+                    scrollTop = target?.scrollTop;
+                }
+
+                converse.env.utils.safeSave(this.model, {
+                    scrolled,
+                    scrollTop
+                });
+            }
+        }
+    }
+});
diff --git a/src/solid-xmpp-chat.js b/src/solid-xmpp-chat.js
index 5e14d12f9fae4b54b266c159856c475e980d9556..b80778abd878384f918c97b2d45c04785762f91a 100644
--- a/src/solid-xmpp-chat.js
+++ b/src/solid-xmpp-chat.js
@@ -1,6 +1,7 @@
 import './conversejs/converse.min.js';
 import './conversejs/emojis.js';
 import './plugins/converse-rai.js';
+import './plugins/sib-history-scroll.js'
 import { Sib, store, StoreMixin } from 'https://cdn.skypack.dev/@startinblox/core@0.15';
 import ComponentPath from './path.js';
 
@@ -426,7 +427,17 @@ export const SolidXMPPChat = {
           fileupload: true, // Not working in current Converse
           toggle_occupants: false
         },
-        'whitelisted_plugins': ['rai', 'conversejs-sib-disconnected', 'conversejs-sib-connected', 'conversejs-sib-focused', 'conversejs-changechat', 'conversejs-rai', 'custom-hats', 'remove-notifications'],
+        'whitelisted_plugins': [
+          'rai',
+          'sib-history-scroll',
+          'conversejs-sib-disconnected',
+          'conversejs-sib-connected',
+          'conversejs-sib-focused',
+          'conversejs-changechat',
+          'conversejs-rai',
+          'custom-hats',
+          'remove-notifications',
+        ],
       });
 
       converse_sib.loaded_deferred.resolve();