diff --git a/aleksis/core/static/js/include_ajax_live.js b/aleksis/core/static/js/include_ajax_live.js
new file mode 100644
index 0000000000000000000000000000000000000000..e42164e8f676b4788172f3c9b870acff0af468e0
--- /dev/null
+++ b/aleksis/core/static/js/include_ajax_live.js
@@ -0,0 +1,39 @@
+const asyncIntervals = [];
+
+const runAsyncInterval = async (cb, interval, intervalIndex) => {
+  await cb();
+  if (asyncIntervals[intervalIndex]) {
+    setTimeout(() => runAsyncInterval(cb, interval, intervalIndex), interval);
+  }
+};
+
+const setAsyncInterval = (cb, interval) => {
+  if (cb && typeof cb === "function") {
+    const intervalIndex = asyncIntervals.length;
+    asyncIntervals.push(true);
+    runAsyncInterval(cb, interval, intervalIndex);
+    return intervalIndex;
+  } else {
+    throw new Error('Callback must be a function');
+  }
+};
+
+const clearAsyncInterval = (intervalIndex) => {
+  if (asyncIntervals[intervalIndex]) {
+    asyncIntervals[intervalIndex] = false;
+  }
+};
+
+let dashboard_interval = setAsyncInterval(async () => {
+  console.log('fetching new data');
+  const promise = new Promise((resolve) => {
+    $('#dashboard').load("/?include_by_ajax_full_render=1 #dashboard");
+    resolve(1);
+  });
+  await promise;
+  console.log('data fetched successfully');
+}, 15000);
+
+$(document).on('include_by_ajax_all_loaded', function() {
+    console.log('Now all placeholders are loaded and replaced with content');
+})