-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfooter.js
More file actions
47 lines (43 loc) · 1.54 KB
/
footer.js
File metadata and controls
47 lines (43 loc) · 1.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// footer.js. Adds the site footer after React hydration on landing.
// Static pages already have it in HTML; only the landing needs runtime injection.
// React may strip it after hydrate, so we keep an observer that re-injects if removed.
(function () {
function build() {
const f = document.createElement('footer');
f.className = 'site-footer';
f.setAttribute('aria-label', 'Site footer');
f.innerHTML = `
<p class="site-footer-copy">Nipcode © 2026</p>
<nav class="site-footer-links" aria-label="Legal">
<a href="/changelog">Changelog</a>
<a href="/privacy">Privacy</a>
<a href="/terms">Terms</a>
<a href="/faq">FAQ</a>
</nav>
`;
return f;
}
function ensure() {
if (document.querySelector('.site-footer')) return;
document.body.appendChild(build());
}
function start() {
ensure();
// Re-check on common hydration milestones in case React replaced body children
setTimeout(ensure, 200);
setTimeout(ensure, 800);
setTimeout(ensure, 2000);
// Long-term guard: if React ever removes our footer, put it back
const obs = new MutationObserver(() => {
if (!document.querySelector('.site-footer')) ensure();
});
obs.observe(document.body, { childList: true });
}
// Wait for window.load so React finishes hydration before we touch body.
// Earlier injection triggers React error #418 (hydration mismatch).
if (document.readyState === 'complete') {
start();
} else {
window.addEventListener('load', start, { once: true });
}
})();