This article shows you how to remove the hash symbol (#) from Flutter web application URLs. You’ll also learn a technique to avoid a common error you will likely run into if you’re building a cross-platform app.
Table of Contents
Overview
By default, Flutter web uses the hash fragment URL strategy. A normal URL looks like this:
kindacode.com/#/some-path/to-the-moon
This URL format is practically not used much in real life. Instead, it would be better to remove the hash (#) from the URLs. Fortunately, we can do this without using any third-party packages. All we need to do is to set the URL strategy to PathUrlStrategy(), like so:
// main.dart
import 'package:flutter/material.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
void main() {
runApp(const MyApp());
setUrlStrategy(PathUrlStrategy());
}
This will only run on the web because importing package:flutter_web_plugins/flutter_web_plugins.dart will cause an error on native platforms like Android and iOS. If you want your app to run everywhere, see the solution in the complete example below.
Example
App Preview
The sample web app we’re going to build consists of 2 pages: Home (/) and About (/about). The user can navigate from Home to About by using the elevated button in the center of the Home page.
The Code
If you’re developing a cross-platform app for both web and native, you will run into a fatal error if you import package:flutter_web_plugins/flutter_web_plugins.dart directly.
1. The solution here is to create two new files named url_strategy_web.dart and url_strategy_native.dart in the lib folder:
.
├── main.dart
├── url_strategy_native.dart
└── url_trategy_web.dart
2. Here’s the code for url_strategy_web.dart:
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
void urlConfig() {
setUrlStrategy(PathUrlStrategy());
}
If you see a warning (not an error, just a warning) like this:
The imported package 'flutter_web_plugins' isn't a dependency of the importing package.
Just edit your pubspec.yaml file like so:
dependencies:
flutter:
sdk: flutter
# Add these two lines
flutter_web_plugins:
sdk: flutter
And the annoying warning will go away.
3. And here’s the code for url_strategy_native.dart:
void urlConfig() {
// Do nothing on native platforms
}
4. Hook up everything in main.dart:
// kindacode.com
// main.dart
import 'package:flutter/material.dart';
import './url_strategy_native.dart'
if (dart.library.html) './url_strategy_web.dart';
void main() {
runApp(const MyApp());
urlConfig();
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
// Remove the debug banner
debugShowCheckedModeBanner: false,
title: 'KindaCode.com',
routes: {
'/': (context) => const HomePage(),
'/about': (context) => const AboutPage()
},
);
}
}
// Home Page
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('KindaCode.com')),
body: Center(
child: ElevatedButton(
child: const Text('Go to About page'),
onPressed: () {
Navigator.of(context).pushNamed('/about');
},
),
),
);
}
}
// About Page
class AboutPage extends StatelessWidget {
const AboutPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('About')),
body: const Center(
child: Text(
'About Page',
style: TextStyle(fontSize: 24),
),
),
);
}
}
Conclusion
You just learned how to set up URLs without the # sign when running a Flutter app on the web by calling setUrlStrategy(PathUrlStrategy()). You also studied an example of how to implement it in a cross-platform app. If you’d like to explore more new and fascinating things about modern Flutter development, take a look at the following articles:
- How to run Flutter web with a custom port
- Flutter Web: 2 Ways to Change Page Title Dynamically
- Check if a Flutter app is running on the web
- Using GetX (Get) for Navigation and Routing in Flutter
- How to get the Current Route Name in Flutter
- Flutter: Don’t use BuildContexts across async gaps
You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.