Adam Adam - 3 months ago 54
AngularJS Question

AngularJS pretty URLs does work only partialy

I have a problem with AngularJS ui-routing, for some reason the routing works only partialy when I want to use "pretty URLs", I looked up many tutorials and threads on these forums, but I just can't find any solution for this.

I have an app just like this one:,
the only change I made is, that I added

<base href="/">
of index.html file.

By default it works fine, but in the url there is always hastag so the url looks like

but I want it to look like this

before you start downvoting me that this is a duplicate, here comes the problem:

On every forum I looked at, this is supposed to be the solution, paste it in your config and magic will happen.


This is how my app.js looks like with the hasbang code

// app.js
var routerApp = angular.module('routerApp', ['ui.router']);

routerApp.config(function($stateProvider, $urlRouterProvider, $locationProvider) {




// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'partial-home.html'

Now the # is gone, but if I refresh the page, I get a weird results or 404. So again I looked up for a solution and found out, that you have to add this code to .htaccess (source)

RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html to allow html5 state links
RewriteRule ^ index.html [L]

Yay, now it works with refresh and direct links as well, but here is the real problem for which I can't find a solution:

When I hit refresh on page

It works fine, but when I go directly (or by refresh) on page

it breaks, simply, second "/" will just nuke the page from orbit, it stops working and I have no idea why, the only thing I found out is, that when I open the console in chrome I get really weird results such as:

app.js:3 Uncaught SyntaxError: Unexpected token <
angular.js:3660 Uncaught Error: [$injector:modulerr] Failed to instantiate module routerApp due to:
Error: [$injector:nomod] Module 'routerApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.$injector/nomod?p0=routerApp
at ensure (
at module (
at Array.forEach (native)
at forEach (
at loadModules (
at createInjector (
at doBootstrap ($injector/modulerr?p0=routerApp&p1=Error…trap%20(

and the biggest mindblown is, that when I open app.js in resources, the js code is gone and it's replaced with the HTML from index.html ಠ_ಠ

Any help appreciated and sorry for bad English...

By the way, the problem persists when I use ng-route instead of ui-route.

EDIT: I found out that when I set the locationProvider to false and hit refresh, the url turns into this thing, which seems to be wrong:


After lot of googling and putting things together, I finally stumbled upon an answer, that makes this work. The mistake I made is that I used absolute paths for my assets and links, which is wrong, you have to use relative paths, for example:

I had paths set up like this:

<!-- index.html file -->
<link href="assets/css/bootstrap.min.css" rel="stylesheet">
<script src="assets/libs/angular.min.js"></script>
<a href="about">About</a>

Notice the missing "/" at the beggining of each link, that's the catch, because, if you want to use $locationProvider.html5Mode(true) you have to set up a <base href="/"> to make it work and now you are referring to it.

Simply, to make it work you have to make sure all your links start with "/" symbol.

Like this:

<!-- index.html file -->
<link href="/assets/css/bootstrap.min.css" rel="stylesheet">
<script src="/assets/libs/angular.min.js"></script>
<a href="/about">About</a>

To make the hasbang work even with refresh on page you have to set up .htaccess properly as well.

This is how my .htaccess looks like:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ /#!/ [L]

Notice that I use "/#!/", you can set that up in angular routes where the location provider is, like this: