The <base> Element
Per MDN the
<base> element specifies the base URL to use for all relative URLs contained within a document.
Consider the following example:
Let’s assume this HTML appears on this domain (
http://tjvantoll.com). When the link is clicked on, the browser will navigate to
http://foo.com/bar.html rather than
It’s important to note that hash links are also relative to the specified base. Therefore on the following:
When the link is click on, the browser will navigate to
http://foo.com#bar and NOT
http://tjvantoll.com#bar. This detail is important; it’s the root cause of confusion when using a
<base> tag with the tabs widget.
jQuery UI Tabs
Here is the intended HTML structure to be used by the tabs widget:
1 2 3 4 5 6 7 8 9 10
Which produces the following:
In this example both links begin with a hash (
#), indicating that their content is located on the current page. If that is not the case, the tabs widget will retrieve the tab’s contents server side via an XHR call. Consider the following:
1 2 3 4 5 6 7 8 9
Here the local link will work as in the previous example - when it is clicked on, the tabs widget will simply display the contents of the
However, when the external link is clicked, the tabs widget will perform an XHR request to retrieve the contents. Assuming this HTML is located on
http://tjvantoll.com, an XHR GET will be performed for
http://tjvantoll.com/external. The contents returned are dynamically added to the DOM and displayed.
#local container on
http://tjvantoll.com. The external link will do a full page navigation to
<base> + tabs
Given the descriptions above, the behavior of the
<base> tag with the tabs widget shouldn’t be surprising. Here’s the first example given for the tabs widget again. This time, a
<base> tag to
http://foo.com has been added:
1 2 3 4 5 6 7 8 9 10 11 12
Let’s again assume this HTML is located on
http://tjvantoll.com. Because of the
<base> tag, the links used in the tabs widget are actually external links to
http://foo.com. Therefore, upon instantiation, the tabs widget will attempt to load the contents of the first tab from
http://foo.com regardless of the domain the page is viewed on.
From the numerous bug reports, it seems that a lot of people have applications with
<base> tags and want hashed links to be relative to the current page. How can you fix your application?
1) Remove the
<base> tag. It’s that simple. After the removal, the tabs widget will never attempt to load external content from any links with leading hashes. Of course, this approach requires changing any other links on the page that are dependent on the
<base> tag’s leading path.
2) Provide full URLs on links used to build the tabs widget. If approach #1 isn’t feasible, you can also provide a fully qualified URL in the links used to build the tabs widget. Here’s the earlier example modified to show this approach:
1 2 3 4 5 6 7 8 9 10 11 12
Since the links in the tabs are now fully qualified paths to the current page, the tabs widget will not perform a request to retrieve external content.
A more robust way of handling this would be to inject the current path server side. For example the following PHP could be used to inject the link used in the first tab above:
'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '#tab-1'
The hack is shown below, simply call the
makeTabs function with the selector used to create the tabs widget:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
As noted by the warning box, you should really fix this the right way. But desperate times call for desperate measures. You’ve been warned.
Hopefully if you didn’t understand how to use the
<base> tag and jQuery UI’s tab widget together you do now. If you are still having issues after reading through this please let me know in the comments.
Update (March 6th, 2013)
Per comments from rubensa, I’ve removed