14

With AngularJS 1.3, the <base> tag is required when in HTML5 mode and that got me thinking about what are the advantages/disadvantages of HTML5 mode vs Hash mode.

With Hash mode, the downside is that URLs are slightly ugly and not intuitive if you expect users to type URLs themselves. The downside of HTML5 mode (with 1.3) is that is requires the <base> tag which can create a number of issues (like making working with SVG a bit of a pain).

Are there any other downsides to either modes that I am not thinking of?

ryanzec
  • 27,284
  • 38
  • 112
  • 169
  • Can [this answer on SO](http://stackoverflow.com/a/19753427/2057033) help? – Blackhole Sep 04 '14 at 20:46
  • @Blackhole I had tried that without luck however looking into the issue more, it seems like something in the iconic.js library is causing the issue because when I use just the SVGInjector library and the technique mentioned in that link, the icons work fine. I would still like to know the difference between HTML5 mode/hash mode in AngularJS (updated my question to reflect that). – ryanzec Sep 05 '14 at 12:13
  • Didn't notice any troubles with HTML5 mode during 3 years using on different websites, except svg (had some gradient paths problem, related to base as you wrote, had to specify full path) – Rantiev Dec 17 '16 at 20:12

2 Answers2

5

Using the history API allows you to have a real URL that can have the appropriate content provided directly by the server.

This:

  • Allows you to load the page in the correct state even if the first page visited by the user isn't the homepage. (This is faster than loading it in the homepage state then changing it with JS after reading the hashbang)
  • Gives good content to search engines for indexing (without using Google's horrible (and now deprecated) hashbang hack)
  • Allows the URLs to work even if the JavaScript fails for any reason.

See also Breaking the Web With Hash Bangs.

The hashbang approach:

  • Works in ancient browsers
  • Doesn't pretend to have a server side fallback if you don't invest the effort in building one.

NB: Ancient browsers can fall back to simply following links to the server generated page when you use the History API.


That said, Angular's use of the History API is pretty poor.

Quotes below are from the documentation:

Using this mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html).

This advice is terrible. If you are using the history API, then you should be writing your server side code with progressive enhancement in mind. By rewriting every URL to an HTML document which bootstraps Angular and does nothing else, you making having different URLs that are handled by the server pointless. You also depend entirely on the JS working as there is no way to get the server to deliver the content when it fails.

In short, this approach uses the History API for purely cosmetic reasons and then uses a dirty hack to avoid 404 errors.

For browsers that support the HTML5 history API, $location uses the HTML5 history API to write path and search. If the history API is not supported by a browser, $location supplies a Hashbang URL.

This is the result of Angular following through with the philosophy that the History API is there for cosmetic, rather than practical, reasons. Instead of falling over to regular pages delivered by the server, Angular resorts to having two URLs (a History API one and a Hashbang one) for every resource.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • And how it's supposed to work if JS fails? Browser will load that URL of course but what user will see? Nothing, because if JS fails app router doesn't work. – Rantiev Dec 17 '16 at 20:14
  • @Rantiev — That's the point of having "the appropriate content provided directly by the server". See also [this](https://en.wikipedia.org/wiki/Unobtrusive_JavaScript) and [this](https://en.wikipedia.org/wiki/Progressive_enhancement). – Quentin Dec 17 '16 at 21:26
  • You have to point this then, because no one has this set as usual. A lot of SPAs go without any server side as static website that takes info from any API. So server side URLs handling is a very specific case. In most cases if JS fails it means your website fails. – Rantiev Dec 18 '16 at 13:20
  • @Rantiev — Then you might as well use hashbangs and be done with it. – Quentin Dec 18 '16 at 18:56
  • i think if we are talking about percents, then 1% of all angular apps use serverside URLS handling like this. And 99% will use beauty urls (html5 mode). I have increased numbers a bit, to help you understand my point. it's quite complex task to implement serverside rendering that's less people do this, and turning html5 mode is just a couple lines of code. (with angular at least, i have never done this phantom JS and other staff myself) – Rantiev Dec 19 '16 at 14:39
0

Using HTML5 mode requires URL rewriting on server side, basically you have to rewrite all your links to entry point of your application (e.g. index.html). Requiring a <base> tag is also important for this case, as it allows AngularJS to differentiate between the part of the url that is the application base and the path that should be handled by the application.

For more information, see

georgeawg
  • 48,608
  • 13
  • 72
  • 95