The reason you are seeing localhost:3000/login#/login
is because your $stateProvider configuration uses the .otherwise
route which goes to #/login
. The first /login
is part of your URL path to the endpoint that retrieves the HTML for your Single Page Application (SPA) - it is part of your base URL.
For developers first starting out with SPAs, it might appear counter-intuitive that "navigation" in the app doesn't actually change the URL path - and thus endpoints of the server. Because of that there are no HTTP requests or HTTP-302 redirects. The app (or Angular, in this case) only changes the fragment (#) portion of the URL - that is how $stateProvider or $routeProvider "navigation" works.
So, the routes you configure in SPA determine "logically" which view to show. While the content of the view could load from an external URL, it is not related to the "route" definition itself.
Determine where your SPA will live. Determine what belongs to your SPA and what doesn't - and would be serviced by a different endpoint. Within SPA, "navigate" via #/path/to/view
-style routes. Change url via $location.path
to navigate outside of your SPA to a different endpoint.
== Same endpoint / different "routes" - all part of the same App:
baseurl.com/basePath#/about
baseurl.com/basePath#/login
baseurl.com/basePath#/product/153
== Different endpoints - different apps. Each one is an HTTP request to the server:
baseurl.com/basePath/about
baseurl.com/basePath/login
baseurl.com/basePath/product/153/
EDIT:
It is possible to use /page-view/other/params
without #
, turns out. Take a look at the following SO question.
In short, it's called HTML5 mode, and it can be configured with $locationProvider:
$locationProvider.html5Mode(true);
This however requires a bit more configuration and also more configuration on the server: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode