Single Page
ブログを少しだけ移転した

更新履歴

2024-07-10

blog2へ再移転してblogは一旦凍結。

Nuxt SSR(VPSではないレンタルサーバ)でのgooglebotの受け入れ方がどうにも分からずWordPressライクのPHPコードに変更。

その代わりコードビューワ機能を追加したよ。

2024-06-19

blog2からblogへと仮復帰。

どうも.htaccessの設定が悪かった説ある。

ちょっと様子見です。

部屋替え移転

version 0.7系までの場所から少しだけ移転。

サブドメインが切り替わっただけの、外部的には部屋替え程度のものですがね。

  • 旧URL: https://blog.gothicum.xyz/post/new-post
  • 新URL: https://blog2.gothicum.xyz/?!/post/new-post

ドメインが blog.gothicum.xyz から blog2.gothicum.xyz へと、「2」が付きました。

内部システム変更

0.7系以前はNuxt.jsのSSR + Prismaを使っていたのを、PHP + MySQLiに変更しました。

ORMでアクセスしてたのを、MySQL文を直接書いてWordPressのDBから引っ張ってくる方法への変更。

ナウいやり方から古いやり方に戻した感じ。

一応はNuxt.jsの実例として旧版も残しておきますけれども。

移転決行をしたのはアナリティクスを見ていて、どうにもページがインデックス登録されない問題が発生してまして。

多分VPSじゃないレンタルサーバ上で無理やりNode.js + PM2を動かしているのが原因ではないかなと思った次第。

本来の用途ではないですからね。

これならインデックスに登録されるんじゃなかろうかと作り変えなどしてたのです。

ま、CMS部分はWordPress(ヘッドレス化済)なのでフロントエンドとミドルウェアだけの変更で済みましたがね。

ルーティング処理

でもただ単純に置き換えるのは詰まらないのでルーティング処理を自力で実装しました。

popstateへの割り込み

((w, d) => {
	/**
	 * ルーティング: ブラウザの戻る/進む
	 */
	w.addEventListener('popstate', h => {
	  let href = '', target = (h.target as Window) ?? null
	  if(target){
	    href = target?.location.href
	    if(href.indexOf('/?!') >= 0){
	      href = href.replace(/^.*?\/?!/, '/?!')
	    }else{
	      href = '/?!/'
	    }
	  }else{
	    href = '/?!/'
	  }
	
	  domUpdate(getParseUrl(href)['path'] ?? '')
	})
})(window, document)

historyAPIでページ遷移処理に割り込んで中断させ、URLを解釈した上でPHPにfetch(する処理はdomUpdate関数)。

帰ってきたデータを元にDOMを直接書き換えています。

(直接アクセスした場合はそのままPHPがHTMLを出力する)

一度アナリティクスを読み込ませていれば、ページ遷移に見立てたDOM更新を検知して「どのページにいるか」をきちんと取得してくれました。

アナリティクス用に更新したDOM

bodyタグは当然更新しますが、アナリティクス向けにheadタグの中身も更新します。

というより、こっちが本命。

タイトル
  • title
  • meta[property="og:title"]
デスクリプション
  • meta[name="description"]
  • meta[property="og:description"]
URL
  • meta[property="og:url"]
  • link[rel="canonical"]

アンカーとフォームへの割り込み

((w, d) => {
  d.addEventListener('DOMContentLoaded', () => {
    /**
     * 検索送信
     */
    d.querySelectorAll('#header form[role]').forEach(d => {
      d.addEventListener('submit', e => {
        try{
          e.stopPropagation();
          e.preventDefault();

          const searchWord = (e.target as HTMLElement)!.querySelector('input')!.value + ''

          if(searchWord.replace(/[  ]/g, '') === ''){
            setWarn('検索ワードを入力してください')
            throw new Error('検索ワードを入力してください')
          }

          fireRouting('?!/search/' + searchWord)
        }catch(e){
          console.log((e as Error).message)
        }

        return false;
      })
    })

    /**
     * ルーティング処理
     */
    d.querySelectorAll('a[data-local]').forEach(e => {
      e.addEventListener('click', elRouter)
    })
  })

  /**
   * === イベントリスナ ===
   */
  const elRouter = (e: Event) => {
    let target = <HTMLElement| null> e.currentTarget
    while(target && target?.tagName.toUpperCase() !== 'A'){
      target = target?.parentElement ?? null
    }
    if(target && target.getAttribute('href')){
      fireRouting(target.getAttribute('href') ?? '')
      e.stopPropagation()
      e.preventDefault()
    }
  }

  /**
   * ルーティング: アンカー押下 or フォーム送信
   * @param url リンク先URL
   */
  const fireRouting = async (url: string) => {
    history.pushState({}, '', url)
    domUpdate(url)
  }
})(window, document)

Aタグをクリックした時の処理はイベントリスナを引っ掛けておきました。

語句検索する場合はフォーム送信イベントから処理が発火します。

当然と言えば当然なんですが、DOM更新で新しくAタグが生成されて内部ルータで処理させたい場合。

そいつらにもイベントリスナを新しく登録する必要があるのが少し面倒なところ。

ともあれ部屋替えはアナリティクス対策なのでもう少し様子見。

まだだめなら何か方法を考えるかもです。