Flutterで宣言的ルーティング!Navigator 2.0をシンプルにする「routemaster」パッケージ

Flutterアプリの開発が進むにつれて、画面遷移(ルーティング)の管理は複雑になりがちです。特にWeb対応やディープリンク、タブ切り替え、ガード機能(ログインチェックなど)を実装しようとすると、標準のNavigatorだけではコードが肥大化してしまいます。

そんなときに活躍するのが routemaster パッケージです。FlutterのNavigator 2.0(Router API)をベースに、URL駆動の宣言的なルーティングを驚くほどシンプルに実装できるライブラリです。

routemasterとは?

routemaster は、URLをベースにしたFlutterアプリ向けのルーティングライブラリです。モバイル(iOS/Android)だけでなく、Webでのブラウザ履歴やURL変更、タブナビゲーションにネイティブに対応しています。

主な特徴:

  • 宣言的なルート定義: URLパス構造に合わせた直感的なルートマップを作成できます。
  • 強力なタブ管理: スムーズなタブ切り替え、各タブごとの独立したナビゲーション履歴を簡単に実装可能です。
  • 柔軟なガード機能: 認証状態に応じたリダイレクト処理(未ログインならログイン画面へ)を数行で記述できます。
  • Web対応: ブラウザの「戻る・進む」ボタンやURLの直接入力に完全同期します。

インストール方法

pubspec.yaml に以下を追加します:

dependencies:
  routemaster: ^1.0.1

インストール後に実行:

flutter pub get

基本的な使い方

まずはアプリ全体のルートを定義する「ルートマップ」を作成し、MaterialApp.router に紐付けます。

import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';

// 1. ルートマップの定義
final routes = RouteMap(
  routes: {
    '/': (_) => const MaterialPage(child: HomeScreen()),
    '/feed': (_) => const MaterialPage(child: FeedScreen()),
    '/settings': (_) => const MaterialPage(child: SettingsScreen()),
  },
);

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      // 2. RoutemasterのRouterDelegateとRouteInformationParserを設定
      routerDelegate: RoutemasterDelegate(routesBuilder: (context) => routes),
      routeInformationParser: const RoutemasterParser(),
    );
  }
}

画面を遷移させる際は、URLパスを指定するだけでOKです。

// 指定したURLの画面へ遷移
Routemaster.of(context).push('/feed');

// 前の画面に戻る
Routemaster.of(context).pop();

認証ガード(リダイレクト)の実装

ログインしていないユーザーをマイページから追い出し、ログイン画面へリダイレクトさせる処理も一瞬で書けます。

final routes = RouteMap(
  onUnknownRoute: (path) => const Redirect('/'), // 不明なURLはホームへ
  routes: {
    '/': (_) => const MaterialPage(child: HomeScreen()),
    '/login': (_) => const MaterialPage(child: LoginScreen()),
    
    // ガード付きルート
    '/profile': (_) {
      final isLoggedIn = AuthService.checkLogin(); // 認証チェック
      if (!isLoggedIn) {
        return const Redirect('/login'); // 未ログインならログイン画面へ
      }
      return const MaterialPage(child: ProfileScreen());
    },
  },
);

タブナビゲーションの管理

routemaster の真骨頂はタブ管理です。TabPage を使うことで、各タブが独自のナビゲーションスタック(履歴)を持つ高度なUIが作れます。

final routes = RouteMap(
  routes: {
    '/': (_) => const TabPage(
          child: HomePage(),
          paths: ['/feed', '/settings'], // タブに対応するパス
        ),
    '/feed': (_) => const MaterialPage(child: FeedScreen()),
    '/settings': (_) => const MaterialPage(child: SettingsScreen()),
  },
);

// UI側の実装イメージ
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final tabState = TabPage.of(context);

    return Scaffold(
      body: TabPageBody(controller: tabState),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: tabState.index,
        onTap: (index) => tabState.index = index,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.list), label: 'フィード'),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: '設定'),
        ],
      ),
    );
  }
}

対応している機能一覧

機能対応状況備考
URLベースの画面遷移パスパラメータやクエリパラメータも取得可能
WebブラウザURL同期戻る・進む、URL直接入力に完全対応
認証ガード・リダイレクト条件に応じた柔軟なルーティング制御
独立したタブナビゲーション各タブで個別の画面スタックを保持
ネストされたルーティング親ルートの中に子ルートを配置可能
ダイアログ・ボトムシート表示CupertinoPage やカスタムページにも対応

互換性と対応プラットフォーム

Flutter 3.x 以降のRouter API(Navigator 2.0)に準拠して設計されています。

対応プラットフォーム:

Android, iOS, Web, macOS, Windows, Linux (全環境対応)

まとめ

特徴内容
シンプルなNavigator 2.0面倒なRouter APIの設定をラップし、URLベースで直感的に書ける
Web・ディープリンク最適化モバイルだけでなく、URLが重要になるWebアプリで強力に機能
高度なUIパターンタブ切り替えやガード機能など、実務で必須の機能を標準サポート

routemaster パッケージは、FlutterのNavigator 2.0の複雑さを解消し、シンプルかつクリーンなコードでルーティングを管理できるようにしてくれます。特にWeb対応や、タブごとに画面履歴を持たせたい複雑なアプリ開発において、開発効率を大きく向上させてくれるおすすめのライブラリです!

参考リンク

タイトルとURLをコピーしました