I've never seen <base>
HTML tag actually used anywhere before. Are there pitfalls to its use that means I should avoid it?
The fact that I have never noticed it in use on a modern production site (or any site) makes me leery of it, though it seems like it might have useful applications for simplifying links on my site.
Edit
After using the base tag for a few weeks, I did end up finding some major gotchas with using the base tag that make it much less desirable than it first appeared. Essentially, the changes to href='#topic'
and href=''
under the base tag are very incompatible with their default behavior, and this change from the default behavior could easily make third party libraries outside of your control very unreliable in unexpected ways, since they will logically depend on the default behavior. Often the changes are subtle and lead to not-immediately-obvious problems when dealing with a large codebase. I have since created an answer detailing the issues that I experienced below. So test the link results for yourself before you commit to a widespread deployment of <base>
, is my new advice!
It's probably not very popular because it's not well known. I wouldn't be afraid of using it since all major browsers support it.
If your site uses AJAX you'll want to make sure all of your pages have it set correctly or you could end up with links that cannot be resolved.
Just don't use the
target
attribute in an HTML 4.01 Strict page.One thing to keep in mind:
If you develop a webpage to be displayed within UIWebView on iOS, then you have to use BASE tag. It simply won't work otherwise. Be that JavaScript, CSS, images - none of them will work with relative links under UIWebView, unless tag BASE is specified.
I've been caught by this before, till I found out.
I have found a way to use
<base>
and anchor based links. You can use JavaScript to keep links like#contact
working as they have to. I used it in some parallax pages and it works for me.You should use at the end of the page
To decide whether it should be used or not, you should be aware of what it does and whether it's needed. This is already partly outlined in this answer, which I also contributed to. But to make it easier to understand and follow, a second explanation here. First we need to understand:
How are links processed by the browser without
<BASE>
being used?For some examples, let's assume we have these URLs:
A)
http://www.example.com/index.html
B)
http://www.example.com/
C)
http://www.example.com/page.html
D)
http://www.example.com/subdir/page.html
A+B both result in the very same file (
index.html
) be sent to the browser, C of course sendspage.html
, and D sends/subdir/page.html
.Let's further assume, both pages contain a set of links:
1) fully qualified absolute links (
http://www...
)2) local absolute links (
/some/dir/page.html
)3) relative links including file names (
dir/page.html
), and4) relative links with "segments" only (
#anchor
,?foo=bar
).The browser receives the page, and renders the HTML. If it finds some URL, it needs to know where to point it to. That's always clear for Link 1), which is taken as-is. All others depend on the URL of the rendered page:
Now what changes with
<BASE>
being used?<BASE>
is supposed to replace the URL as it appears to the browser. So it renders all links as if the user had called up the URL specified in<BASE>
. Which explains some of the confusion in several of the other answers:<BASE>
differs from the one being called initially from the user)<BASE>
:An example explains it best
Say you want to "prettify" some URL using
mod_rewrite
:<DOCUMENT_ROOT>/some/dir/file.php?lang=en
http://www.example.com/some/dir/file.php?lang=en
http://www.example.com/en/file
Let's assume
mod_rewrite
is used to transparently rewrite the user-friendly URL to the real one (no external re-direct, so the "user-friendly" one stays in the browsers address bar, while the real-one is loaded). What to do now?<BASE>
specified: breaks all relative links (as they would be based onhttp://www.example.com/en/file
now)<BASE HREF='http://www.example.com/some/dir>
: Absolutely wrong.dir
would be considered the file part of the specified URL, so still, all relative links are broken.<BASE HREF='http://www.example.com/some/dir/>
: Better already. But relative links of "type 4" are still broken (except for "case B").<BASE HREF='http://www.example.com/some/dir/file.php>
: Exactly. Everything should be working with this one.A last note
Keep in mind this applies to all URLs in your document:
<A HREF=
<IMG SRC=
<SCRIPT SRC=
In the case of SVG images inlined in the page there is another important issue that arises when the
base
tag is used:Since with the
base
tag (as noted above already) you effectively loose the ability to use relative hash URLs like in<a href="#foo">
because they will be resolved against the base URL rather than the current document's location and thus are not relative anymore. So you will have to add the path of the current document to these kinds of links like in
<a href="/path/to/this/page/name.html#foo">
So one of the seemingly positive aspects of the
base
tag (which is to move the long URL prefixes away from the anchor tag and get nicer, shorter anchors) completely backfires for local hash URLs.This is especially annoying when inlining SVG in your page, be it static SVG or dynamically generated SVG because in SVG there can be a lot of such references and they will all break as soon as a
base
tag is used, on most, but not all user agent implementations (Chrome at least still works in these scenarios at the time of writing).If you are using a templating system or another tool-chain that processes/generates your pages, I would always try to get rid of the
base
tag, because as I see it, it brings more problems to the table than it solves.Working with AngularJS the BASE tag broke $cookieStore silently and it took me a while to figure out why my app couldn't write cookies anymore. Be warned...