You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Repository navigation
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
Running an Angular app in a subdirectory is painful. All your routes, resources, locations, etc etc have to be manually prefixed with the application context. Example:
It's annoying and also error prone if your development env runs in a subdirectory (pretty common).
One current solution is to add a <base href="/myroot/"> tag to the document. This solves the problems from the Angular perspective but causes many issues of its own, especially for third-party libs/widgets that use anchors.
The ideal would be to make $location configurable with a base path, much like Backbone router's root config.
$locationProvider.baseHref="/myroot/";$location.path('/awesome');// goes to /myroot/awesome$routeProvider.when('/mypath', ...);//matched at /myroot/mypath$resource('/some/resource');//maps to /myroot/some/resource
This change would make running Angular in different contexts much easier.
A workaround I found for this was to redefine the behaviour of the $browser.baseHref() function in the application module's run() function like so:
// override the $browser.baseHref() method so it returns "/" without needing to use a <base href="/"> element// in the head of the document (which causes problems with SVG patterns amongst other things)$browser.baseHref=function(){return"/"};
Reacted by Reuven Karasik
Reacted by Reuven Karasik, Ilya Shapkin and fatchul01
@greglockwood I like that solution for setting base href asssuming you can get angular loaded with a correct path first ;) I'm hoping to put that to use tomorrow!
Correct me if I'm wrong -- is this issue about making angular apps that don't need to be tweaked when their actual root path changes? I'm still really looking forward to some sort of solution to being able to deploy apps in subdirectories without modifying their code.
@stu-salsbury I don't believe you are right in saying that this issue is about having Angular apps working in subdirectories without modifying lines of code. This issue is about being able to specify in code what is currently pulled from the <base href="..."> tag in the <head> of the document, as that <base> tag introduces other, unwanted problems. Regardless of those other problems, though, if you want to deploy an Angular app to http://server/directory, you are going to need to change the "base URL", which is a code change either way (either updating the <base> tag in the HTML or, if this feature gets added, in the JS code).
One way I have come up with in the past to get around an application being able to be deployed in a subdirectory or not and still work is to determine the base URL from the full URL, since you can subtract any known relative path from the whole URL. You could combine that trick with either my workaround above, or if this feature gets added, with the official function call to have this kind of "deploy anywhere" functionality.
Let me illustrate what I meant above in more concrete terms. Let's say I have all my application routes starting with /app, and I want it to work if deployed at either http://localhost:9000/ or http://sub.domain.com/my/new/angular-app/ or anywhere. What I can do when I start up in my Angular app is examine the current full URL, subtract everything from the last /app onwards, and then subtract the server and port and be left with the correct base URL. Then I could combine that with my workaround above to override the $browser.baseHref() function so it returns that base URL. Then, as far as I know, Angular will correctly prepend that base URL to the URL for all requests and everything should just work. Note: I haven't tested this.
@wmertens correct. For asset paths in HTML files (paths in CSS are ok, they're loaded relative to the CSS file) you'd still need to prefix your paths with the root if you have a variable root.
we dove into this yesterday with @geddski and we have a plan to implement ngAppRoot directive which will take in a string that represents url prefix that should be used internally for $location, $http and $route urls.
with this and some sort of serverside templating (signified by [[ ]] in example below) you'll be able to do this:
Thought about base, but don't want to mislead people into thinking it
behaves like <base href=
On Jun 28, 2013 7:41 AM, "Pete Bacon Darwin" [email protected]
wrote:
Would ngAppBase not be more consistent and less confusing given we
already have $rootScope and root element concepts?
—
Reply to this email directly or view it on GitHubhttps://github.com//issues/2805#issuecomment-20188585
.
correct. the resolution rules for base[href] and "root" are very different, so we want to make the difference clear.
for example if base[href]="/foo/bar" and url is "/baz" then the final url is still "/baz". however if root is "/foo/bar" then the final url is "/foo/bar/baz".
For those of trying to make sense of this, it would be helpful if someone provided an example of what we are supposed to do. Currently it is clear as mud.
The problem is, how do I know if angular is running in a subpath? Where can I get the value for that from? It'd be nice to just be able to do something like
var url = $location.baseHref() + '#/my/route';
Then I could easily generate URLs for things like "share buttons".
For those who still search for a solution, you can use $window.location.pathname.
I don't know why '$location.path()' returns not the same as '$window.location.pathName()', but it works for me.
Activity
0x-r4bbit commentedon May 27, 2013
👍 yeap!
oztune commentedon May 27, 2013
Would simplify my life and save us quite a few lines of code. +1
laurelnaiad commentedon May 27, 2013
👍
lgalfaso commentedon May 30, 2013
You know you can add
to
<head>and it will be picked?laurelnaiad commentedon May 30, 2013
that reference was in error, please ignore
greglockwood commentedon Jun 14, 2013
A workaround I found for this was to redefine the behaviour of the
$browser.baseHref()function in the application module's run() function like so:laurelnaiad commentedon Jun 14, 2013
@greglockwood I like that solution for setting base href asssuming you can get angular loaded with a correct path first ;) I'm hoping to put that to use tomorrow!
Correct me if I'm wrong -- is this issue about making angular apps that don't need to be tweaked when their actual root path changes? I'm still really looking forward to some sort of solution to being able to deploy apps in subdirectories without modifying their code.
greglockwood commentedon Jun 14, 2013
@stu-salsbury I don't believe you are right in saying that this issue is about having Angular apps working in subdirectories without modifying lines of code. This issue is about being able to specify in code what is currently pulled from the
<base href="...">tag in the<head>of the document, as that<base>tag introduces other, unwanted problems. Regardless of those other problems, though, if you want to deploy an Angular app to http://server/directory, you are going to need to change the "base URL", which is a code change either way (either updating the<base>tag in the HTML or, if this feature gets added, in the JS code).One way I have come up with in the past to get around an application being able to be deployed in a subdirectory or not and still work is to determine the base URL from the full URL, since you can subtract any known relative path from the whole URL. You could combine that trick with either my workaround above, or if this feature gets added, with the official function call to have this kind of "deploy anywhere" functionality.
Let me illustrate what I meant above in more concrete terms. Let's say I have all my application routes starting with
/app, and I want it to work if deployed at eitherhttp://localhost:9000/orhttp://sub.domain.com/my/new/angular-app/or anywhere. What I can do when I start up in my Angular app is examine the current full URL, subtract everything from the last/apponwards, and then subtract the server and port and be left with the correct base URL. Then I could combine that with my workaround above to override the$browser.baseHref()function so it returns that base URL. Then, as far as I know, Angular will correctly prepend that base URL to the URL for all requests and everything should just work. Note: I haven't tested this.wmertens commentedon Jun 25, 2013
The html still needs to reference js, images etc with relative paths, and if the base href in the file is incorrect, then those references won't work.
Making the references be absolute makes putting apps in subdirs broken again.
So I think this can't be solved with something added to $locationProvider, since Angular starts sometime after the document is loaded.
Right?
geddski commentedon Jun 26, 2013
@wmertens correct. For asset paths in HTML files (paths in CSS are ok, they're loaded relative to the CSS file) you'd still need to prefix your paths with the root if you have a variable root.
IgorMinar commentedon Jun 27, 2013
we dove into this yesterday with @geddski and we have a plan to implement ngAppRoot directive which will take in a string that represents url prefix that should be used internally for $location, $http and $route urls.
with this and some sort of serverside templating (signified by
[[ ]]in example below) you'll be able to do this:All of your urls in javascript will then remain absolute-root urls (e.g.
/cats).petebacondarwin commentedon Jun 28, 2013
Would
ngAppBasenot be more consistent and less confusing given we already have$rootScopeand root element concepts?geddski commentedon Jun 28, 2013
Thought about base, but don't want to mislead people into thinking it
behaves like <base href=
On Jun 28, 2013 7:41 AM, "Pete Bacon Darwin" [email protected]
wrote:
geddski commentedon Jul 1, 2013
closing in favor of #3102
IgorMinar commentedon Jul 1, 2013
correct. the resolution rules for base[href] and "root" are very different, so we want to make the difference clear.
for example if base[href]="/foo/bar" and url is "/baz" then the final url is still "/baz". however if root is "/foo/bar" then the final url is "/foo/bar/baz".
agray commentedon Nov 25, 2015
..So is this resolved?
For those of trying to make sense of this, it would be helpful if someone provided an example of what we are supposed to do. Currently it is clear as mud.
Thanks in advance
joshribakoff commentedon Jan 13, 2016
The problem I'm having is I need to give the users a "share" button, which should generate a full URL to one of my routes:
if the app is running in a subdirectory
or if the app has its own domain
So to attempt to construct this dynamically, I try this:
The problem is, how do I know if angular is running in a subpath? Where can I get the value for that from? It'd be nice to just be able to do something like
Then I could easily generate URLs for things like "share buttons".
bes1002t commentedon Feb 5, 2018
For those who still search for a solution, you can use $window.location.pathname.
I don't know why '$location.path()' returns not the same as '$window.location.pathName()', but it works for me.