経験知ロゴ

React LocationをElectronで使う方法

react Location

ElectronでReact Locationを使うと、サーバを使ったローカル環境なら動きますが、buildしてファイルパスでのアクセスになると機能しなくなります。

公式ドキュメントによると、Memory Routingを使うとのこと。

書いてあるとおり、createMemoryHistoryにルートパスを設定し、ReactLocationに渡します。

 import { createMemoryHistory, ReactLocation } from '@tanstack/react-location'
 
 // Create a memory history
 const memoryHistory = createMemoryHistory({
   initialEntries: ['/'] // Pass your initial url
 })
 
 // Set up a ReactLocation instance with the memory history
 const location = new ReactLocation({
   history: memoryHistory,
 })

これで一応うまくいくのですが、新規ウィンドウを開くと、指定したURLではなくルートに設定したページが開かれるか、ファイルアクセスエラーが出ます。

力技ですが、lodadUrlをハッシュ使用のパスにし、「initialEntries」に表示させたいパスを入れる方法で解決しました。

メインプロセスで、別ウィンドウで開きたいURLをハッシュを使ってロードする。

// index.htmlまでのパス。index.htmlの後に「#」をつけ、その後にルーティングを書く。
const loadUrl = 'path/to/html/index.html#/hoge/fuga';
//ハッシュ付きのパスをロード
window.loadUrl(loadUrl)

レンダープロセスでは、URLを解析して

// 現在のパスとハッシュプロパティをつなげる
let path = window.location.pathname + window.location.hash;
// index.htmlを探す
let index = path.indexOf("index.html");
// index.htmlが存在したらパスを変更
if (index) {
  // ローカルパスからindex.html以降の値を取得。
  const localPath = path.substring(index);
  // パスが「index.html」だけならpathをルートに設定
  if (localPath === "index.html") {
    path = "/";
  } else {
    // ハッシュパラメーターがある場合は、「index.html#」を取り除いてパスを作成
    path = localPath.replace("index.html#", "");
  }
}
// 開発環境では、「#」が残るので削除。
path = path.replace("#/", "");

// initialEntriesにpathを設定
const memoryHistory = createMemoryHistory({
  initialEntries: [path],
});

export const location = new ReactLocation({ history: memoryHistory });

後は「Router」の「location」で上記「location」を渡せばOK。

おわりに

スマートなやり方では無いですが、とりあえず動いて良かったです。

React Locationのloaderを使いたくてなんとか解決しました。

React RouterならhashRouterで簡単に解決します。

役に立ったらこの記事のシェアをお願いします

ブログのフォロー・RSS購読は下記ボタンから