From ce9467f8fb229763c1c1bb5f95c35b3ff7d676ae Mon Sep 17 00:00:00 2001 From: Dmitry Verkhoturov Date: Tue, 26 May 2026 18:36:03 +0100 Subject: [PATCH] site: address PR review on version badge fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - gate DOM update on DOMContentLoaded — inline.js is loaded sync in , so a cache-hit fetch can resolve before the placeholder span is parsed. - hide placeholder span by default (`hidden`) so a failed/blocked fetch doesn't leave a 0.5rem stray gap before the github icon. - log fetch failures (rate limit, offline, blocked) instead of silently swallowing — matches the prior behaviour of build-time github.js. --- site/src/includes/components/header.njk | 2 +- site/src/includes/inline.js | 25 ++++++++++++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/site/src/includes/components/header.njk b/site/src/includes/components/header.njk index 21319f23..a51d88aa 100644 --- a/site/src/includes/components/header.njk +++ b/site/src/includes/components/header.njk @@ -9,7 +9,7 @@
- + diff --git a/site/src/includes/inline.js b/site/src/includes/inline.js index c9ba4ef7..9526f3ab 100644 --- a/site/src/includes/inline.js +++ b/site/src/includes/inline.js @@ -7,14 +7,25 @@ if ((theme && theme === 'dark') || (!theme && mq.matches)) { // fetch the latest release version client-side so the badge tracks releases // without needing a site rebuild. GitHub serves this with Cache-Control: -// public, max-age=60 so the per-visitor cost is bounded. fallback stays -// empty on any failure — graceful degradation, no broken UI. +// public, max-age=60 so the per-visitor cost is bounded. placeholder is +// `hidden` in the template so a failed/blocked fetch leaves no stray gap. fetch('https://api.github.com/repos/umputun/remark42/releases/latest') - .then((r) => (r.ok ? r.json() : null)) + .then((r) => (r.ok ? r.json() : Promise.reject(new Error('HTTP ' + r.status)))) .then((d) => { if (!d || !d.tag_name) return - document.querySelectorAll('[data-remark42-version]').forEach((el) => { - el.textContent = d.tag_name - }) + // script is loaded synchronously in , so a cache hit can resolve + // before is parsed and [data-remark42-version] exists. defer the + // DOM update until the document is ready. + const apply = () => { + document.querySelectorAll('[data-remark42-version]').forEach((el) => { + el.textContent = d.tag_name + el.hidden = false + }) + } + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', apply) + } else { + apply() + } }) - .catch(() => {}) + .catch((err) => console.warn('remark42-site: latest version fetch failed', err))