Skip to content

Instantly share code, notes, and snippets.

@mikeckennedy
Last active August 20, 2023 18:55
Show Gist options
  • Save mikeckennedy/4b64418d9cd4872a7b54d7d69b5b2cde to your computer and use it in GitHub Desktop.
Save mikeckennedy/4b64418d9cd4872a7b54d7d69b5b2cde to your computer and use it in GitHub Desktop.
Server-side hot reload checker by Michael Kennedy. When the contents of the page change in any way, the page will be reloaded.
// *************************************************************************
// server-hot-reload.js v1.0.5
//
// Server-side hot reload check by Michael Kennedy (https://mkennedy.codes).
// Released under the MIT open source license, 2023.
//
// When the contents of the page change in any way, the page will be reloaded.
//
// Usage:
//
// * Include this file in your "application shell" layout template
// or directly into any page you'd like to check.
//
// * Call toggleServerReload() within the browser console to pause/resume
// when you want it to give your server a break. Useful when you want to
// step through breakpoints and don't want the noise, etc.
//
// * Set the checkIntervalInMs time to the frequency you need. Usually 1 sec
// should be fine, but if a page is slow maybe increase the delay.
//
let currentPageHash = "UNKNOWN";
let checkIntervalInMs = 1000;
let active = true;
// *************************************************************************
// When the doc is ready, we'll start checking for changes.
//
document.addEventListener("DOMContentLoaded", function () {
console.log("Server hot reload active at " + new Date().toLocaleTimeString() + ". Watching for changes ...");
const url = document.location.href;
setInterval(() => downloadHtml(url).then(reloadIfNecessary), checkIntervalInMs);
});
// *************************************************************************
// Called on every page content check (interval is checkIntervalInMs milliseconds).
//
function reloadIfNecessary(html) {
if (!active) {
return;
}
if (html == null || html.length === 0) {
console.log("Something went wrong with server hot-reload check... Trying again at interval.")
return
}
const newHash = hashCode(html);
if (!newHash) return;
if (currentPageHash === "UNKNOWN") {
// Compute the hash since have never seen this response on this URL before (first run).
currentPageHash = newHash;
return;
}
if (newHash === currentPageHash) {
return;
}
// Something, somewhere in the page has changed. Reload
console.log("Page change detected, reloading now!")
window.location.reload();
}
// noinspection JSUnusedGlobalSymbols
function toggleServerReload() {
active = !active;
const msg = "Server hot reload is now " + (active ? "ACTIVE" : "PAUSED") + ".";
//console.log("Server hot reload is now " + (active ? "active" : "paused") + ".");
return msg;
}
function hashCode(html) {
let hash = 0, i, chr;
if (html.length === 0) return hash;
for (i = 0; i < html.length; i++) {
chr = html.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
}
async function downloadHtml(url) {
if (!active) {
return null;
}
const thisURL = new URL(url)
thisURL.searchParams.append('server_hot_reload_check', 'true')
try {
const request = await fetch(thisURL);
return request.text();
} catch (e) {
return '';
}
}
@mikeckennedy
Copy link
Author

Description:

Server-side hot reload check by Michael Kennedy (https://mkennedy.codes).
Released under the MIT open source license, 2023.

Usage: Include this file in your "application shell" layout template or directly into any page you'd like to check.

Set the checkIntervalInMs time to the frequency you need. Usually 1 sec should be fine, but if a page is slow maybe increase the delay.

When the contents of the page change in any way, the page will be reloaded.

@mikeckennedy
Copy link
Author

Thanks to @fimion for some modernization improvements. :)

@mikeckennedy
Copy link
Author

I decided to move this to a proper repo over at https://github.com/mikeckennedy/server-hot-reload

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment