Search code examples
firebaseflutterdartfirebase-hosting

how to setup 404 Not found page in Flutter using Firebase Hosting


I am trying to show a custom 404 not found page in my website with Flutter.

I am using the following code :

MaterialApp(
        debugShowCheckedModeBanner: false,
        initialRoute: "/",
        routes: {
          "/": (context) => Scaffold(),
          "/test": (context) => TestPage()
        },
        onUnknownRoute: (settings) {
          return MaterialPageRoute(builder: (_) => Scaffold(
            body: Center(
              child: Text("Page not found !"),
            ),
          ));
        }, 

i have rebuild my app and deploy it with Firebase Hosting. However i am seeing this if i enter a wrong url :

enter image description here

Since i am using flutter, i don't really want to add an .html file as it is said, even if it works.
I would rather display a custom page built in dart.

How can i display my custom "Page not found" in such case ?

EDIT :

Here is my current firebase.json file :

{
  "hosting": {
    "cleanUrls": true,
    "public": "build/web",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

What i have tried and what didn't work :

  • Not having rewrites
  • Having rewrites in hope that flutter routing would take the lead
  • Test the project in localhost
  • Change the Flutter routing Strategy from URL to PATH according to the documentation

In the end :

  • My existing pages in the website are working fine
  • All wrong urls are redirected to /index.html

The only thing that is working is :

  • Adding a 404.html file in my /build/web folder
  • Remove rewrites in firebase.json

However this is not what i want, i would like to display my not_found_page.dart instead.

This might be a Flutter issue, i keep this open in the meantime but i will dig deeper on the Flutter side.


Solution

  • The problem was indeed on the Flutter side. I was using "/" as initialRoute and "/" as another route which was creating conflicts apparently and was actually useless in my code as the first page returned is defined under the MaterialApp's child.

    Flutter was redirecting my routes to "/" instead of calling onUnknownRoute and there was a conflict with the rewrites in firebase.json

    So i have removed the "/": (context) => Scaffold(), from the routes map. I have also removed rewrites in firebase.json in order for this to work.

    I have also set back the URL strategy, all the steps above were not working with the PATH strategy.

    EDIT : i have figured out that the PATH strategy can work only if there is no home property on the MaterialApp widget.
    If so, all of the wrong routes will be redirected to the home and not call the onUnknownRoute

    • For the / route, the home property, if non-null, is used.
    • Otherwise, the routes table is used, if it has an entry for the route.
    • Otherwise, onGenerateRoute is called, if provided. It should return a non-null value for any valid route not handled by home and routes.
    • Finally if all else fails onUnknownRoute is called.

    PS : There is no need to implement 404.html file