Fruitionで独自ドメイン化したNotionページにおける不具合を修正する

Notion のページを手軽に独自ドメイン化することができるスクリプト生成ツール「Fruition」。近頃はメンテナンスされておらず、Notion 側の仕様変更により正常に動作しなくなってしまった部分があるため、使うには少し手を加える必要がある。

発生事象

  • ブラウザの戻るボタンを押すと Notion のサインアップ画面に遷移してしまう。
  • ライト/ダークモードの切替ボタン(トグルスイッチ)が機能しない。

修正方法

Cloudflare のダッシュボードから Worker を編集し、fruitionsite.com で生成したコードの一部を以下の通りに修正する。

修正前

function onDark() {
  el.innerHTML = '<div title="Change to Light Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgb(46, 170, 220); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px);"></div></div></div></div>';
  document.body.classList.add('dark');
  __console.environment.ThemeStore.setState({ mode: 'dark' });
};
function onLight() {
  el.innerHTML = '<div title="Change to Dark Mode" style="margin-left: auto; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgba(135, 131, 120, 0.3); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px);"></div></div></div></div>';
  document.body.classList.remove('dark');
  __console.environment.ThemeStore.setState({ mode: 'light' });
}
function toggle() {
  if (document.body.classList.contains('dark')) {
    onLight();
  } else {
    onDark();
  }
}
function addDarkModeButton(device) {
  const nav = device === 'web' ? document.querySelector('.notion-topbar').firstChild : document.querySelector('.notion-topbar-mobile');
  el.className = 'toggle-mode';
  el.addEventListener('click', toggle);
  nav.appendChild(el);
  onLight();
}

修正後

function enableConsoleEffectAndSetMode(mode){
  if (__console && !__console.isEnabled) {
    __console.enable();
    window.location.reload();
  } else {
    __console.environment.ThemeStore.setState({ mode: mode });
   localStorage.setItem('newTheme', JSON.stringify({ mode: mode }));
  }
}
function onDark() {
  el.innerHTML = '<div title="Change to Light Mode" style="margin-left: 14px; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgb(46, 170, 220); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(12px) translateY(0px);"></div></div></div></div>';
  document.body.classList.add('dark');
  enableConsoleEffectAndSetMode('dark')
}
function onLight() {
  el.innerHTML = '<div title="Change to Dark Mode" style="margin-left: 14px; margin-right: 14px; min-width: 0px;"><div role="button" tabindex="0" style="user-select: none; transition: background 120ms ease-in 0s; cursor: pointer; border-radius: 44px;"><div style="display: flex; flex-shrink: 0; height: 14px; width: 26px; border-radius: 44px; padding: 2px; box-sizing: content-box; background: rgba(135, 131, 120, 0.3); transition: background 200ms ease 0s, box-shadow 200ms ease 0s;"><div style="width: 14px; height: 14px; border-radius: 44px; background: white; transition: transform 200ms ease-out 0s, background 200ms ease-out 0s; transform: translateX(0px) translateY(0px);"></div></div></div></div>';
  document.body.classList.remove('dark');
  enableConsoleEffectAndSetMode('light')
}
function toggle() {
  if (document.body.classList.contains('dark')) {
    onLight();
  } else {
    onDark();
  }
}
function addDarkModeButton(device) {
  const nav =
    device === 'web'
      ? document.querySelector('.notion-topbar').firstChild
      : document.querySelector('.notion-topbar-mobile')
  el.className = 'toggle-mode'
  el.addEventListener('click', toggle)
  const timeout = device === 'web' ? 0 : 500
  setTimeout(() => {
    nav.appendChild(el)
  }, timeout)
  const currentTheme = JSON.parse(localStorage.getItem('newTheme'))?.mode
  if (currentTheme) {
    if (currentTheme === 'dark') {
      onDark()
    } else {
      onLight()
    }
  } else {
    if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      onDark()
    } else {
      onLight()
    }
  }
  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
    toggle()
  })
}

参考