Flutter WebのhistoryモードのNavigationとRoutingをFirebase Hostingで行う方法

image

Flutter WebのhistoryモードのNavigationとRoutingをFirebase Hostingで行う方法を解説します。

Routingの種類

まず、Flutter WebはSPA(Single Page Application)なので、Routingにはhistoryモードとhashモードがあります。

hashモード

hashモードとはhash「#」の後にSPAで定義したRoutingがURLになる方式です。
例: http://localhost:3000/#/blog

historyモード

hashモードはSPAで定義したRoutingがそのままURLになる方式です。
例: http://localhost:3000/blog



SPAは/index.htmlを呼んで、そのページで全てが完結するので、何も考えないとRoutingはhashモードになる事が多いです。Flutter Webも同様です。

なぜデフォルトでhashモードになるかと言うと、静的Hostingサービスで/blogにアクセスした場合、/blogというファイルが存在していないため404判定を受けてしまうからです。
hashモードのURLの場合は、hashがある事によって、/#/blog/index.htmlを見に行っているので問題なく目的のページが表示されるわけです。
しかし、hashモードのURLはあまり見慣れないので、Flutter Webでもhistoryモードにする方法をみていきます。

vrouter

historyモード実現のために、vrouterというFlutter Pluginを使用します。
https://pub.dev/packages/vrouter

//blogというURLがあって、それ以外のURLにアクセスがあった場合は/にリダイレクトするという動きをするアプリのサンプルコードです。

  
  Widget build(BuildContext context) {
    return VRouter(
      debugShowCheckedModeBanner: false,
      mode: VRouterModes.history,
      routes: [
        VWidget(
          path: '/',
          widget: IndexPage(),
          buildTransition: (animation, _, child) {
            return FadeTransition(opacity: animation, child: child);
          },
        ),
        VWidget(
          path: '/blog',
          widget: BlogPage(),
          buildTransition: (animation, _, child) {
            return FadeTransition(opacity: animation, child: child);
          },
        ),
        VRouteRedirector(
          redirectTo: '/',
          path: r'*',
        ),
      ],
    );
  }

vrouterでは、VRouter()MaterialApp()の代わりに使うので、MaterialApp()は不要になります。
modeVRouterModes.historyに設定し、サンプルコードの通りにroutes実装するとRouting設定は完了です。

以下のコードで/から/blogに遷移できます。

context.vRouter.push('/blog');

動作確認

ChromeをターゲットにDebug Runしてみます。

デモ

無事historyモードでURLが表示されました!

ちなみに、ここでlocalhost:54025/blogのページをリロードしても、問題なくブログページは表示されます。

Firebase Hosting

Firebase Hostingにこのアプリをデプロイしてみます。

Firebaseでプロジェクトを作成し、Flutterアプリのディレクトリ内でfirebase initし、Firebase Hostingにデプロイできるようにします。

flutter build web --web-renderer html
firebase deploy

でFirebase Hostingにデプロイします。

動作確認

デプロイ先のリンクを見てみます。

デモ

いい感じに動作しています。

リロードする

/blogのページをリロードしてみます。すると、、、

デモ

404になってしまいました...これは最初に説明したように、/blogというファイルが存在していないからですね。

Firebase Hostingの設定を変更する

firebase.jsonの設定で、アクセスされたURLをrewriteする事ができるので、全てのURLアクセスを/index.htmlを見るように変更させます。

{
  "hosting": {
    ...
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

リロードを再度試す

再度Build&Deployして、リロードを試してみます。

デモ

/blogでリロードし、無事blogのページが表示されました🎉🎉🎉

さいごに

これで、Flutter Webでも通常のWebページと同じようなURLでRoutingできるようになりました。
vrouterはusers/:idのようなdynamicなURLにも対応しているので、Flutter WebでWebサービスを開発するという選択も現実的になってきたのではないでしょうか。
Hostingを使ってSPAをデプロイしている以上、ogpの問題はありますが、そこまでogpが重要なサービスも少ないでしょう、という事でそこは目を瞑って...