DEV Community

Surhid Amatya
Surhid Amatya

Posted on

How to Remove the # from URLs in Flutter Web

FLutter was used recently to develop mobile and web apps for a FinTech. Wile loading the URL flutter displayed a # in every URL path and I was amazed. After some research I found By default, Flutter web apps use a HashUrlStrategy, which results in URLs like example.com/#/home

While this ensures smooth navigation without special server configurations, it doesn’t look clean or SEO-friendly or deeplinking-friendly.

So, how do you remove the # and achieve a clean URL structure like this?
example.com/home

The answer is PathUrlStrategy

Understanding URL Strategies in Flutter Web
Flutter web apps support two ways of configuring URL-based navigation:

  1. Hash URL Strategy (Default) Paths are stored in the hash fragment (#) of the URL. Example: flutterexample.dev/#/path/to/screen. No server-side configuration is required.
  2. Path URL Strategy (Recommended) Paths are stored without a hash (#). Example: flutterexample.dev/path/to/screen. Uses the History API, requiring some server-side configuration.

To switch to PathUrlStrategy, follow the steps below.

Step 1: Update Your Dependencies
The _flutter_web_plugins_ library is part of the Flutter SDK. You don't need to install it separately via pub add, but you must include it in your pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  flutter_web_plugins:
    sdk: flutter
Enter fullscreen mode Exit fullscreen mode

Step 2: Modify main.dart to Use PathUrlStrategy
To configure your Flutter web app without the # in URLs, add the following import and function call before running the app:

import 'package:flutter/material.dart';
import 'package:flutter_web_plugins/url_strategy.dart';

void main() {
  usePathUrlStrategy(); // Removes '#' from URLs
  runApp(MyApp());
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Configure Your Web Server
Since PathUrlStrategy uses the browser's History API, additional server-side configuration is required to handle routing correctly.

For Nginx
Modify your nginx.conf to ensure unknown routes serve index.html:


location / {
  try_files $uri /index.html;
}
Enter fullscreen mode Exit fullscreen mode

For Apache (.htaccess)
Add this to your .htaccess file:


<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule .* /index.html [L]
</IfModule>
Enter fullscreen mode Exit fullscreen mode

For Firebase Hosting
If using Firebase, enable single-page app (SPA) mode by updating your firebase.json:

"hosting": {
  "public": "build/web",
  "rewrites": [
    {
      "source": "**",
      "destination": "/index.html"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Adjust base href for Non-Root Hosting
If you are hosting your Flutter web app in a subdirectory (e.g., myapp.dev/flutter_app), update the <base> tag in web/index.html:

<base href="/">

Important:
For relative paths, ensure the considers the full URL structure to prevent issues when navigating nested routes.

Bonus: Maintain Backward Compatibility
If your users rely on the #/ format, but you still want to remove it, use this:

usePathUrlStrategy(includeHash: true);
Enter fullscreen mode Exit fullscreen mode

This removes the # but still supports hash-based routes in legacy browsers.

By implementing PathUrlStrategy, you can:

  1. Clean up your URLs – No more # in the address bar!
  2. Improve SEO – Search engines prefer structured, clean URLs.
  3. Enhance User Experience – Users expect modern, readable URLs.

Top comments (0)