Angular Dart Router - Configure LocationStrategy

lejardh

Hadrien Lejard

Posted on January 16, 2021

Angular Dart Router - Configure LocationStrategy

In this article, I will explain how to correctly configure the router for development and production environment.

If you come from Angular Dart Tour of Heroes tutorial, you might have already configured your project to use package:angular_router and would like to remove the ugly # from your app URL. To do that you need to correctly configure the LocationStrategy you use.

Most of the time people try to use the default strategy, PathLocationStrategy which does not fit all environments, for example during development when running with webdev serve and try to refresh a page of your app, you will get 404 Not Found, because webdev does not support this LocationStrategy

What is LocationStrategy

The LocationStrategy is responsible for representing the RouterState as an url.

  • HashLocationStrategy
    The router will produce url with # at the beginning (ex: example.com#/foo).

  • PathLocationStrategy
    The router will produce cleaner urls, without the #. (ex: example.com/foo)

Which one should I use?

You probably want to use PathLocationStrategy in production to have a clean url in your app, but to do that you will also need to setup your webserver to redirect every 404 response to your index.html.

However during development, you can't configure webdev serve to do the redirection, you need to use HashLocationStrategy.

More about SPA Routing

Router injection

You can conditionally inject a strategy or the other, using an environment variable that can be set in your build.yaml.

Your main.dart

import 'package:angular/angular.dart';
import 'package:angular_router/angular_router.dart';
import 'app_component.template.dart' as ng;
import 'main.template.dart' as ng;

// default is false
const isProd = bool.fromEnvironment('prod');

@GenerateInjector([routerHashModule])
final devInjector = ng.devInjector$Injector;

@GenerateInjector([routerModule])
final prodInjector = ng.prodInjector$Injector;

void main() {
  runApp(
    ng.AppComponentNgFactory,
    createInjector: isProd ? prodInjector : devInjector,
  );
}
Enter fullscreen mode Exit fullscreen mode

And your build.yaml

global_options:
  build_web_compilers|ddc:
    options:
      environment:
        prod: false
  build_web_compilers|entrypoint:
    release_options:
      # https://dart.dev/tools/dart2js
      dart2js_args:
        - -Dprod=true
        - -O4

Enter fullscreen mode Exit fullscreen mode

That's it, if you run webdev serve during development, it will run Dart Dev Compiler with prod: false and when building your app for production with webdev build it will use dart2js compiler with prod: true.


You can find a working github repo here :)

💖 💪 🙅 🚩
lejardh
Hadrien Lejard

Posted on January 16, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related