移動先ページのURLにハッシュが含まれていれば、ヘッダー分移動してあげるというシンプルな作りです。
ミソはsetTimeOutで、これがないとうまくいきません。
headerHeightの値を取得する前にwindow.scrollByが終わってしまうということでしょうか。
document.addEventListener("DOMContentLoaded", () => {
if (location.hash) {
const headerHeight = document.getElementById("js-header").clientHeight;
setTimeout(() => {
window.scrollBy(0, - headerHeight);
},100)
}
})