Mastodon

/

Removing the # in URLs from Flutter web apps

If you are working on a Flutter web application you may have noticed the URL contains a # in it. This behaviour isn’t always desired. I’ll show you how to quickly remove this and have your URLs looking clean.

Page Cover
corinne-kutz-tMI2_-r5Nfo-unsplash.jpg

Removing the # in URLs from Flutter web apps

If you are working on a Flutter web application you may have noticed the URL contains a # in it. While developing locally you may see something similar to http://localhost:57278/#/. Even after a proper deployment this will stay the same, and you can observe it viewing most public Flutter web applications like the Flutter Gallery Demo.
 
This behaviour isn’t always desired and that’s probably why you are visiting this page! I’ll show you how to quickly remove this and have your URLs looking clean.
 
Firstly if you don’t already have flutter_web_plugins in your pubspec.yaml file, let's add it.
dependencies:
  flutter_web_plugins:
    sdk: flutter
  flutter:
    sdk: flutter
This allows us to take advantage of some web specific capabilities.
 
Next we configure our Flutter app on startup to use the “PathUrlStrategy” which tells the Flutter web runtime to handle URLs differently, removing the #.
 
In main.dart we add two lines. We import the library we added above, and we call usePathUrlStrategy() before starting the rest of the application.
import 'package:flutter_web_plugins/url_strategy.dart';

void main() {
  usePathUrlStrategy();
  runApp(const MyApp());
}
Now if you run your app using flutter run -d chrome or similar, you won’t see the # in the URL.
 
However there is a catch! We aren’t done yet!
 
While this will work for local development, we need to do some additional configuration for production. Removing the # means that the full URL will be used for routing on most web servers. We need to ensure that all routes are processed by the same Flutter Web entrance point, index.html.
 
I’ll show you how to do this for Vercel. The configuration for most hosting services should be similar. Create a vercel.json file in the root of your project with the following contents.
{
  "rewrites": [
    { "source": "/(.*)", "destination": "/index.html" }
  ]
}
As I described above, this is telling the server that any incoming request should be handled by index.html, which is the entry point for Flutter Web apps. Hope this helps!