Skip to main content

Waiting Room HTML page

Below is a sample HTML template for a waiting room page. This page is displayed to users who are redirected to the waiting room. It's fully customizable to suit your needs. Within the template, the class attributes queue-position, queue-depth, and avg-wait-time are used to display the visitor's current position in the queue, the total number of users in the waiting room, and the average waiting time, respectively.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Virtual Waiting Room</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
align-items: flex-start;
background-color: #f1f2f3;
background-image: radial-gradient(
farthest-corner,
#f1f2f3 10%,
#d7e1ec 100%
);
display: flex;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
"Segoe UI Symbol";
justify-content: center;
margin: 0;
min-height: 100vh;
padding: 1rem;
}
.container {
background-color: #ffffff;
border-radius: 12px;
box-shadow: rgba(50, 50, 93, 0.1) 0px 30px 60px -12px, rgba(
0,
0,
0,
0.2
) 0px 18px 36px -18px;
max-width: 672px;
padding: 2.5rem 1.5rem 1.5rem;
text-align: center;
}
h1 {
font-size: 1.5rem;
font-weight: 600;
letter-spacing: 0.0125rem;
margin-bottom: 1.25rem;
}
p {
color: #383b46;
margin: 1rem 0;
line-height: 1.5rem;
}
.details {
border-radius: 8px;
display: flex;
flex-direction: column;
justify-content: center;
}
.details > div {
margin: 0 1rem;
padding: 0.5rem;
}
.details p {
color: #535968;
margin: 0;
}
.details p.value {
color: #383b46;
font-size: 1.25rem;
font-weight: 600;
letter-spacing: 0.025rem;
line-height: 1.5rem;
margin-top: 0.25rem;
}
.small {
color: #6f768b;
font-size: 0.875rem;
}

@keyframes striping {
100% {
background-position: 100% 100%;
}
}

@media only screen and (min-width: 768px) {
body {
align-items: center;
}
h1 {
font-size: 2rem;
}
p {
font-size: 0.9375rem;
}
.container {
padding: 2.5rem 3rem 1.5rem;
text-align: center;
}
.details {
flex-direction: row;
}
}
</style>
<script>
function fetchData() {
fetch(`${window.location.href}/status`)
.then((res) => {
const status = res.status;
if (status === 302) {
// it is ok to go to origin now
showRedirectionMessage();
window.location.reload();
}
return res.json();
})
.then(renderData)
.catch((err) => {
console.error("Error fetching data:", err);
});
}

function formatNumber(num) {
return num
? num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ",")
: "";
}

function formatSeconds(seconds) {
seconds = Number(seconds);
const d = Math.floor(seconds / (3600 * 24));
const h = Math.floor((seconds % (3600 * 24)) / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = Math.floor(seconds % 60);

const dDisplay = d > 0 ? d + (d == 1 ? " day, " : " days, ") : "";
const hDisplay = h > 0 ? h + (h == 1 ? " hour, " : " hours, ") : "";
const mDisplay = m > 0 ? m + (m == 1 ? " minute, " : " minutes, ") : "";
const sDisplay = s > 0 ? s + (s == 1 ? " second" : " seconds") : "";
return dDisplay + hDisplay + mDisplay + sDisplay;
}

function showRedirectionMessage() {
const waiting = document.getElementById("waiting");
waiting.style.visibility = "hidden";

const redirecting = document.getElementById("redirecting");
redirecting.style.visibility = "visible";
}

function renderData(data) {
if (data.position === 0) {
showRedirectionMessage();
window.location.reload();
}

const depth = data?.queue_depth || 0;
const position = data?.position || 0;
const wait = data?.avg_waiting_time || 0;

document.getElementById("avg-wait-time").innerText =
formatSeconds(wait);
document.getElementById("queue-position").innerText =
formatNumber(position);
document.getElementById("queue-depth").innerText = formatNumber(depth);

document.getElementById("req-id").innerText = data.reqId;
}

function startPolling() {
fetchData();
setInterval(fetchData, 1 * 1000);
}
</script>
</head>
<body onload="startPolling()">
<div class="container">
<h1>Virtual Waiting Room</h1>
<div id="waiting">
<p>
Thank you for your patience. We are currently experiencing a high
volume of visitors. You will be automatically redirected when it is
your turn.
</p>
<div class="details">
<div>
<p>Visitors ahead of you:</p>
<p class="value" id="queue-position"></p>
</div>
<div>
<p>Visitors in the queue:</p>
<p class="value" id="queue-depth"></p>
</div>
</div>
<p class="small">
Estimated wait time: <span id="avg-wait-time"></span>
</p>
</div>
<p class="small">Request Id: <span id="req-id"></span></p>
<p class="small" id="redirecting" style="visibility: hidden">
You are being redirected. Thank you for your patience...
</p>
</div>
</body>
</html>