Kinda Code
Home/Flutter/Flutter web: Removing hash symbol (#) from all URLs

Flutter web: Removing hash symbol (#) from all URLs

Last updated: May 18, 2023

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.

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:

You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.