This blog post is going to help you clean up your URLs when you’re developing a SPA (Single Page App). In addition, I’m going to show you how to enable a browser refresh when you do. And finally, I’m going to show you how to enable ASP.NET MVC’s ReturnUrl functionality when the target page is an Angular route. If any of these things interest you, then keep reading.

What do I mean about cleaning up URLs? Well, if you’ve ever clicked around an Angular web site, you might have noticed the “#” (hashtag, or pound) in the URL, like this:

This is not specific to Angular, it applies to all SPAs. In a nutshell, the path before the pound will be handled by your server router, the path after the pound will be handled by your Angular router. The default page in your web app will be responsible for initializing and launch your Angular bits, and will decide which view to load. In our web applications, we typically have one MVC controller (HomeController) which loads a razor Index.cshtml page. This page bootstraps Angular and from that point on, we’re dealing with Angular views.

So what’s the problem with the pound? Well, it’s kinda ugly, isn’t it? I think the URL would look much better without it. Wouldn’t we all look a little better if we dropped a few pounds? But more importantly, the presence of the pound indicates to all your users that your web site is a SPA. Oh sure, they’ll be able to tell from the snappy response times and glorious user experience; but I’ve never liked giving away the underlying technology in my URLs (especially when the extension is cfm, but that’s a subject for another post).

It is in fact very simple to configure your application so that the pound is not used. However, when you do, there are a few gotchas. This blog post will describe how to get rid of the pound from the URL and how to resolve the issues that arise.

The technologies being used are Angular 1, ASP.NET Web API 2, ASP.NET MVC 6 and IIS 8. This post assumes you have a working knowledge of each.

Dropping the Pounds

As I indicated earlier, getting rid of the pound is very easy. In your Angular config function (probably in app.js), inject $locationProvider and include the following line:


And that’s all there is to it! Save this change, refresh your page, and the pound will magically disappear.

Handling Navigation between Pages

If you didn’t plan for this ahead of time and you’ve already been creating pages, there’s a good chance you’ve just broken your page navigation. Every page link will have to be modified to omit the pound. So you’ll have to change these:

<a href=”/#/customer/list”>Customer List</a>

To this:

<a href=”/customer/list”>Customer List</a>

And you’ll have to change your controller navigation from these:


To this:


When I first started out with Angular, I needed the pounds during development. I was changing pages and needing to refresh the browser to see those changes. Unfortunately, without some tweaking, browser refreshes do not work (more on that in the next section). I wanted a way to be able to toggle in and out of pound mode without breaking all my page links, so my URLs would look pretty in production, without the overhead of having to change all my page navigation. Surely there’s an easier way. Lucky for us, there is. And it’s called UI-Router.

UI-Router ( saves the day. It’s a wonderful and very popular tool. It’s loaded with functionality, but I’m most interested in its feature where you name your routes.

Instead of using the out-of-the-box Angular router, you use UI-Router’s $stateProvider. Setting up a route looks like this:

            .state('customerList', {
                url: '/customer/list',
                templateUrl: '/app/components/customer/list.html',
                controller: 'customers'

The syntax is very similar to the regular router, but you’ll notice we passed “customerList” in to name the state for the customer list page. Now, when you create a page link, you can do this:

<a ui-sref=”customerList”>Customer List</a>

“ui-sref” is a UI-Router directive, and it replaces the standard href. If you’re navigating to a page from Angular, you can do this:


In an app that uses UI-Router, your html and JavaScript are completely absent of URL paths. This enables you to safely toggle in and out of pound mode and UI-Router will render the correct links for you.

The Browser Refresh

The reason I wanted pounds in the URL to begin with is so that I could refresh a page in the browser to load my latest changes. This is usually a problem with a SPA because when you refresh a page, it gets a new request for the URL and the server has no way to know that the path corresponds to an Angular route. So in this case, MVC pukes and gives us a page not found.

I found a number of different ways to solve this issue, but the one I found most effective was to include a rewrite section in your web.config, like this:

        <rule name="Main Rule" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_URI}" pattern="api/" ignoreCase="true" negate="true" />
            <add input="{REQUEST_URI}" pattern="Home/" ignoreCase="true" negate="true" />
            <add input="{REQUEST_URI}" pattern="Account/" ignoreCase="true" negate="true" />
            <add input="{REQUEST_URI}" pattern="Manage/" ignoreCase="true" negate="true" />
            <add input="{REQUEST_URI}" pattern="bundles/" ignoreCase="true" negate="true" />
            <add input="{REQUEST_URI}" pattern="Content/" ignoreCase="true" negate="true" />

            <!-- Static files and directories can be served so partials etc can be loaded -->
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          <action type="Rewrite" url="/" />

The entries will vary depending on your application, but the general idea is you include all the paths that correspond to MVC controllers or physical files or directories. In an ideal world, we wouldn’t be using MVC controllers at all, but the MVC Visual Studio project templates provides some great out of the box functionality, such as dealing with user management and authentication. Just be careful that you don’t have an MVC route that is the same as an Angular route, otherwise confusion will ensue. In order for this to work, you have to install the IIS Rewrite Module, and it isn’t installed by default. It can be downloaded from here:

Deep Links

If you want a user to deep-link into an application but you require your users to login first, this presents a problem. In an MVC application, this is commonly achieved using the build-in ReturnUrl parameter in the URL. For example, if a user tries to go to http://myapp/secure/page, MVC will redirect them to login and adjust the URL to http://myapp/account/login?ReturnUrl =%2fsecure%2fpage. The value of ReturnUrl is an encoded version of the path they initially attempted to access. The issue is that the mechanism inside MVC that handles the ReturnUrl sees that “/secure/page” is not an MVC route, and nulls out ReturnUrl.

Thankfully, this issue is fairly easy to fix. The ReturnUrl functionality is actually implemented in the Authorize attribute. All we have to do extend this class and provide the extra bit of functionality that it’s missing. Here is a code snippet:

public class AuthorizeAttributeSPA : System.Web.Mvc.AuthorizeAttribute
        public override void OnAuthorization(AuthorizationContext filterContext)

            if (filterContext.Result is HttpUnauthorizedResult)
                string returnUrl = "/";
                if (filterContext.HttpContext.Request.HttpMethod.Equals("GET", System.StringComparison.CurrentCultureIgnoreCase))
                    returnUrl = filterContext.HttpContext.Request.RawUrl;
                string url = string.Format("/Account/Login?ReturnUrl={0}", HttpUtility.UrlEncode(returnUrl));
                filterContext.Result = new RedirectResult(url);

This custom attribute overrides the default behavior and handles the ReturnUrl parameter appropriately. Simply apply this attribute to the MVC controllers you want to secure, and deep links to protected pages will work.

And that’s it! I hope this information is helpful to you. As I mentioned earlier, there are several ways to solve these issues, and the techniques described in this post are the ones I’ve felt to be most effective. If you have other ways, please feel free to describe them in the comments section below. Thanks for reading, see you next time.

Thinking of refreshing your website in 2016? Here are the latest trends and cutting edge web tech you need to be aware of.

IE8 Dies (Finally)

keyboard close up

The final nail in the coffin for Internet Explorer 8 is January 12, 2016. That’s the day when Microsoft will only support the latest browsers on the versions of Windows it still supports. For most users, this means you’ll need to be running Internet Explorer 11 or Edge in order to get support, updates, and security fixes from Microsoft. (If you’re not running Windows 10 and Edge yet, you should really consider upgrading: it’s awesome!).

There’s no need to fret: seeing IE8 ride into the sunset is not a bad thing. Most web frameworks and plugins are planning on dropping or have already dropped IE8 support – examples include Angular 2, Bootstrap 4, and jQuery 2. IE8 is only at 1.2% worldwide usage at the end of November 2015, and that number will sharply drop in 2016.

For designers, this means we can fully utilize modern web features without fear, such as media queries, CSS3 properties, SVG icons and images, and better JavaScript support. For clients, this means faster development, faster sites and applications, and decreased development support cost.

ECMAScript 6 Improves JavaScript

2015 was arguably the year of JavaScript. 2016 is shaping up to be a repeat. The driver this time is the release and ramp-up of support for ECMAScript 6 (also known as ES6 or ECMAScript 2015), the latest version of JavaScript. ES6 is a significant upgrade, with the last major advancement released all the way back in 2009 (which is a long time in web years!).

For developers, ES6 brings support for classes, arrow functionsmodules, templating, and more. If you still need support for ES5, a library like babel.js will translate your JavaScript backwards for compatibility with older browsers. Check out the support chart for browser compatibility and a full rundown of ES6 features.

For clients, ES6 doesn’t manifest into many things you’ll see on the front-end of your site or app, but you’ll benefit with cleaner and faster code driving your sites, which will also be prepared for the future of the web.

Static Website Generators

Did you know that the first ever website, Tim Berners-Lee’s original home page for the World Wide Web, was static? Soon after, SQL databases and web stacks such as LAMP (which drive sites build on WordPress, Drupal, and Joomla) became popular to help separate content from design and to make the web editable by the masses.

In 2016, we’ll see the return to the static website through increased popularity in tools such as Jekyll, Middleman, and Assemble. Static website generators such as these take a back-to-basics mentality to solve the issues that have become common with the web and many content management systems – security, speed, and caching.

Static site generators use a variety of languages at their core (such as JavaScript, Ruby, and Python), but the main language they are built on is called Markdown, a simplified way of writing HTML for writing, blogging, and note-taking. Once mastered, Markdown can replace WYSIWYG editors found in most CMS platforms.

These generators still have some growing up to do, but be sure that you’ll be hearing more about them in 2016 and beyond as they gain more traction and start replacing simple blog and marketing websites. Check out this list of popular static site generators for more info.

Increased Flexbox Usage

Flexbox (also known as the flexible box module) is an advanced CSS property that will gain widespread adoption this year. Its purpose is to provide a more efficient way to lay out and align a website’s design. Flexbox will allow designers to build grid systems without relying on CSS floats, complicated percentages for widths, or any need for JavaScript or jQuery hacks for equal height columns.

The main attributing factor for flexbox not being widely adopted is because of older browsers. Flexbox was first introduced for Internet Explorer 10 in 2012, and used a different syntax than what is now the current specification. With Microsoft now pushing users to IE11 and Edge on the latest operating systems, we’ll see flexbox used much more in 2016.

A great guide to using flexbox can be found at CSS Tricks, and for a full list of supported browsers and known bugs check out Can I Use. A useful grid system has been developed that you can download and use in your site designs today.

Card Layouts In Mobile and Desktop Designs

The web has matured over its lifetime from a page-based desktop system to a content on any device system. Cards is a layout device that is at the forefront for allowing content to be easy viewed and digested by users. Examples of cards are tweets from Twitter, an Instagram post, or a Pinterest pin. Google has moved to using cards as part of their Material Design framework on their web apps and their native apps.

Cards are a useful device for designers because they are responsive design friendly — they scale well on mobile devices and on large desktop screens. They are best used for small, short bursts of information, like a photo, a short amount of text, a small handful or links or function, or a combination of the bunch.

Cards are also useful in native devices, as users can touch them, swipe them, and scroll through a list of them. They can also animate and flip to allow for more functionality, if needed. They should not be used for long-form text or data entry, where traditional pages are better suited to present that type of information.

If you have good case for using cards, be sure to check out these resources:

Take a look at the next 5 trends in Part Two of this blog series