WWW FAQs: How do I include one HTML file in another?

2007-09-20: The easiest way, by far, is to use "server side includes" in your HTML. Almost all web servers support this, except for free web hosting companies. This is overwhelmingly the preferred way to go. And the same exact syntax works for ASP and ASP.NET sites. For webmasters who prefer PHP, a minor variation on this theme is the use of PHP syntax instead of traditional server side include syntax.

For those who cannot use server side includes, ASP, ASP.NET or PHP, we also present two client side methods: the JavaScript method, and the iframe method. Both have significant disadvantages and you should absolutely try to use server side includes first. Not to put too fine a point on it, but professionals do not use client side includes, except in very specialized circumstances. "I don't know how" and "I chose the wrong web host" are not acceptable reasons when someone is paying you to design a website.

How to Use Server Side Includes

Server side includes are a simple way to tell your web server to insert various things at various points in your HTML page. You can use them without major changes to your existing pages. However, some web servers require that you name your file .shtml rather than .html in order to enable the parsing of your file by the server in order to find server side include directives. If server side includes don't appear to work, try renaming the page with a .shtml file extension before you give up.

Of course, server side includes only work when a web server is being used to access your pages. This is only an issue when testing your pages on your local hard drive. If this becomes a problem, it may be time to install a web server on your own computer, for local testing purposes. After all, Apache is free for Windows, and both free and standard in Linux and MacOS X.

A simple server side include directive to include another file found in the same folder looks like this:

<!--#include virtual="insertthisfile.html" -->

include virtual and include file do almost the same thing. The difference is that include virtual takes a URL-style path, which is what you probably expect. include virtual can also execute CGI programs, if your web server supports that, and include their output. include file takes a file-system path, and cannot execute CGI programs. Both also accept relative paths, so for a simple case like the above they work the same. If you don't understand the difference between web paths and file system paths, use include virtual.
There are many more server side include directives available; for example, you can easily insert the current date into your page.

IF IT DOESN'T SEEM TO WORK, TRY NAMING YOUR FILE WITH A .shtml EXTENSION, instead of .html. Please do not ignore this tip and then email me asking why it doesn't work!

For more information, see the Apache server side includes tutorial, which also covers how to configure the free Apache web server correctly with support for server side include directives. For information about enabling Server Side Includes in Microsoft IIS, consult Microsoft TechNet.

How to Use PHP For Server Side Includes

If your server is configured to support PHP but not server side includes, or you just prefer to use PHP everywhere, you can easily include fragments of HTML in your PHP page like this:

<?php include("filename.html"); ?>

This is essentially the same thing as server side includes, just using a different syntax. The PHP page that contains this directive must have a .php extension and the server must support PHP. If you don't know PHP, you probably want to use ordinary server side includes instead as described above.

PHP include directives can also point at files on any website using a full URL:

<?php include("http://www.othersite.com/filename.html"); ?>

Of course, you must not steal content from another website without the express written permission of the owners. To do so is a copyright violation and may lead to legal action against you.

How to Use ASP and ASP.NET For Server Side Includes

If you are using old-fashioned ASP (.asp files), you're in luck. The server-side include commands discussed earlier in this article will work with no modifications. Naturally, your pages will have a .asp extension rather than a .shtml extension. Otherwise, no changes need be made. The files you include can also contain ASP code.

Since server-side includes are compiled in advance in ASP.NET, before any ASP.NET code is run, you can't use an ASP.NET variable as part of a filename to be included. Those who require such advanced capabilities can open files on the server directly from ASP.NET code. If you don't understand this... you probably don't need it! See the Microsoft Knowledge Base article How To Dynamically Include Files in ASP.NET for more information.

How to Use Client Side Includes

As I mentioned earlier, there are two ways to create client side includes: JavaScript and iframe. Let's look at the advantages and disadvantages of both before we tackle how to do it.

The JavaScript method is the more seamless of the two. JavaScript code can fetch a fragment of a page from any URL and insert it into another page at any point. The end result looks as good as a server-side include— but only if JavaScript is turned on. And search engines don't see the included text at all, which is a serious problem.

The iframe method is simpler. The iframe element can be used to force a second page to "embed" inside the first page, in much the same way that Flash movies, videos and MP3 players are embedded with the object element. And JavaScript doesn't have to be turned on. But there are disadvantages here too. The iframe element has a fixed width and height, no matter how big the content is. That can mean scrollbars inside your page. And, as of this writing, Google doesn't appear to index the separate page referenced by the iframe so that searchers can find your page.

Client-Side Includes: The JavaScript Method

Until recently web browsers did not support any elegant way of including one HTML document seamlessly into the body of another. While frames and inline frames have been available for a long time, these are ways to insert an obviously separate, scrollable sub-document into the page. Generating part of your page using JavaScript code kept in a separate file has also been possible for quite a while, but this requires that parts of your HTML be kept in JavaScript form, which is a pain to deal with.

With Firefox (on any system), Internet Explorer 5 and up (on Windows), and Apple's Safari browser (on MacOS X), the situation has improved. A new mechanism called XMLHTTP can be used to fetch XML documents "on the fly" from a JavaScript program. That includes fetching HTML files. And both of these browsers support inserting what we've fetched at any given point in the current page.

Professional designers: don't do this. Really, don't. It might be appropriate in some types of web applications, but it is not appropriate where server side includes would also work. It's just a workaround for people who can't afford real web hosting with support for PHP, ASP or server side includes. If you use this technique on a website you're being paid to design, and your client complains when the included content is invisible to Google— or doesn't show up in every browser— that's your own fault! Use the techniques earlier in this article for serious web development.
But this isn't a miracle cure. The web browser still has to be Firefox (on any operating system), Safari (on MacOS X), or IE 5 or better on Windows. That's the vast majority of users, but it's not everyone. And some users will have JavaScript turned off for security reasons.
VERY IMPORTANT: if you use this method with pages on your hard drive, not on a web server, the latest versions of Internet Explorer will warn the user that there is "active content" in the page and refuse to insert your included file unless the user goes out of their way to allow it. You won't have this problem once you move the page to a real web server. Then it becomes clear to Internet Explorer that the page and the included file are on the same website, and that nothing sneaky is going on.
OK, we've been warned, so how do we do it? By adding the following JavaScript code to the <head> element of the web page:

<script>
function clientSideInclude(id, url) {
  var req = false;
  // For Safari, Firefox, and other non-MS browsers
  if (window.XMLHttpRequest) {
    try {
      req = new XMLHttpRequest();
    } catch (e) {
      req = false;
    }
  } else if (window.ActiveXObject) {
    // For Internet Explorer on Windows
    try {
      req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        req = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        req = false;
      }
    }
  }
 var element = document.getElementById(id);
 if (!element) {
  alert("Bad id " + id +
   "passed to clientSideInclude." +
   "You need a div or span element " +
   "with this id in your page.");
  return;
 }
  if (req) {
    // Synchronous request, wait till we have it all
    req.open('GET', url, false);
    req.send(null);
    element.innerHTML = req.responseText;
  } else {
    element.innerHTML =
   "Sorry, your browser does not support " +
      "XMLHTTPRequest objects. This page requires " +
      "Internet Explorer 5 or better for Windows, " +
      "or Firefox for any system, or Safari. Other " +
      "compatible browsers may also exist.";
  }
}
</script>

Now we have the power to include another file at any point in the web page. We do that by creating a simple "placeholder" HTML element, giving it an ID that JavaScript code can recognize, and then passing both that ID and the URL of the file we want to include at that point to our clientSideInclude JavaScript function.

One tricky wrinkle: clientSideInclude doesn't always work unless the page has already been completely loaded. So we'll need to call it from the onLoad handler of the <body> element. That's the safest time to call because the browser has definitely parsed all of our HTML by then.

So at the point in your page where you wish to insert the file includeone.html, which is found in the same folder as the page, you'll need to do this:

<span id="includeone">
</span>

And at the beginning of the body of your page, you'll need to do this:

<body onLoad="clientSideInclude('includeone', 'includeone.html');">

Of course, a long, complicated onLoad handler can be very ugly. You can avoid that problem by moving the call (or calls!) to clientSideInclude to a function in a <script> element somewhere in the <head> element of the page. Then just call your function from onLoad.

JavaScript code in the included file might not be executed by all browsers. One more reason why server-side include is always better if you can use it.

You can make things even more elegant by moving the clientSideInclude function to a separate file, clientSideInclude.js, and including that in the <head> element of your page with a <script> element like this one:

<script language="JavaScript" src="clientSideInclude.js">
</script>

Client-Side Includes: The iframe Method

If the JavaScript method doesn't meet your needs, consider using the iframe element. This method has the advantage of simplicity, and doesn't require JavaScript. But bear in mind that search engines still don't like it very much. And you are forced to decide in advance exactly how much space your second document will get in your first document.

If the second document is too wide or tall, scrollbars will appear. Depending on your needs, this might be just perfect or a complete deal-breaker.

Using iframe is straightforward. If your second, embedded document is called included.html, just place the following element in the first, "parent" document to display it in an area 450 pixels wide by 400 pixels tall:


<iframe src="included.html" width="450" height="400">
<a href="included.html">Hmm, you are using a very old browser.
Click here to go directly to included content.</a>
</iframe>

Why do I have an ordinary a element inside the iframe element, linking to the document we're trying to embed? Because certain older browsers, and the major search engines, don't support iframe. While very few human beings are still stuck with Netscape 4, almost everyone is using search engines like Google. And we don't want those to ignore our embedded content completely!

The iframe element has additional attributes to control its appearance. In addition to setting width and height, which you must do, you can also decide whether to allow scrolling. In most cases, you'll want to accept the default behavior: displaying scrollbars when the embedded document is too wide or tall for the width and height of the iframe element. But if you absolutely don't want to permit scrolling, even if it prevents the user from seeing all of the embedded document, you can set the scrolling attribute to no instead.

You can also eliminate the visible border around the embedded page by setting the frameborder element to 0. This is important if you want the embedded page to look like a natural part of your page.

Here's the example again with no frame border:


<iframe src="included.html" width="450" height="400" frameborder="0">
<a href="included.html">Hmm, you are using a very old browser.
Click here to go directly to included content.</a>
</iframe>

For more information about iframe, see The Web Design Group's very thorough article on the iframe element.

What To Include, And What Not To Include

Some users have asked whether the file that is being included needs to be a fully complete and standards-compliant HTML document. For server-side includes and JavaScript client-side includes, the included document should not be a complete HTML document. If you include one complete HTML document into another, you wind up with two head elements, two body elements, and so on, which is just plain wrong.

Just think about it this way: what the web browser finally receives should be a complete, standards-compliant document. It doesn't matter what the pieces you assemble to create that document look like on the server. Only what ultimately reaches the web browser is important.

For iframe client-side includes, the situation is different. Here you are embedding a completely independent second page into the first page. So that second page should be a complete HTML document in its own right.

How can I include a file on another website in my page?

You can't do that legally without permission. Here I am assuming that both sites belong to you or your client.

It's easy enough to display a web page on another site as part of your page with the <iframe> element as described above. Of course, this doesn't look like a seamless part of the page, and search engines will not treat it as such.

You usually cannot use the JavaScript-driven client side include method to bring in a page from another site. This is because the security rules built into the web browser will refuse to fetch documents from third-party sites, as a precaution.

There is one exception: if the other site is part of the same domain, you can still do it, provided that you set document.domain to your domain name, like this:


<!-- At the top of the head element -->
<script>
document.domain = "mydomain.com";
</script>

After you do this, you will be able to use client-side includes to fetch content from another site in the same domain. That is, if your page is on www.mydomain.com, you can use a client-side include to fetch content from www2.mydomain.com. But you still can't fetch it from www.someotherdomain.com.

If your sites are hosted on the same server, though, the best solution is still to use server-side includes. You might expect this to work:


<!-- Sorry, doesn't work -->
<!--#include virtual="http://www.othersite.com/page.html"-->

Unfortunately, this tactic doesn't work, even if the other site is hosted on the same web server. include virtual works only within a single site.

So what can we do? We can use include file rather than include virtual. This way, we can access things by their location on the web server's hard drive, regardless of whether they are within a particular website's document root or not.

If we know that the two sites www.mydomain.com and www.myotherdomain.com are hosted in subdirectories of our home directory on the web host, something like this will work to fetch a file from the document root of www.myotherdomain.com:


<!--#include file="/home/myaccount/www.myotherdomain.com/html/file.html"-->

Here I am assuming a Unix-based (usually Linux-based) web host with a typical layout of directories. Yours may differ.

If you are going to share files between sites in this way, you might find it more convenient to make a separate subdirectory just for your shared includes. This has the advantage that the chunks of code to be included can't be fetched directly over the web by curious snoops:


<!--#include file="/home/myaccount/includes/file.html"-->

Note that you cannot invoke a dynamic PHP page or CGI program with include file. If you do you will get the source code in your page, not the output of that code.

Symbolic links: an elegant solution for Linux/Unix folks

I mentioned that we must use include file to include things from a second site on the same server, which is a bit clunky. But if both sites are hosted on a Linux-based server, there is an alternative: using symbolic links.

First, find out what the file system path (NOT URL!) of the document root for the first site is. For instance (just an example, yours will differ):


/home/myaccount/www.mydomain.com/html/

Next, find out what the file system path of the other site is. Again, this may look like:


/home/myaccount/www.mydomain2.com/html/

Now, at the Linux command line prompt, make a symbolic link that makes the document root of the second site visible as part of the first site.

THIS MUST BE ONE LINE, I have used two lines only for readability:


ln -s /home/myaccount/www.mydomain2.com/html/
  /home/myaccount/www.mydomain.com/html/mydomain2

What does this buy us, exactly? Symbolic links allow us to make the operating system believe that the same file or folder exists in two places. This neat trick means that if we ask www.mydomain.com for a URL like this:


http://www.mydomain.com/mydomain2/file.html

We will actually receive this:


http://www.mydomain2.com/file.html

Now we can use a simple include virtual to include a file from the second site in a page in the first one:


<!--#include virtual="/mydomain2/file.html"-->

However, this will only work if symbolic links are enabled in Apache. For security reasons, some web hosts turn support for following symbolic links off by default. And if they are turned off, you will receive an error when you try to follow them to reach a file. However, you can turn them on in your Apache configuration file (httpd.conf) or via a .htaccess file in your document root folder. The .htaccess file should contain the following:


Options +FollowSymlinks

Or, add +FollowSymlinks to the Options line for your site in your httpd.conf file and signal Apache to reload its configuration with the service httpd reload command.

"But I simply must include a page from a site hosted somewhere else!"

We now have good solutions for including files from sites hosted on the same server. But what if we absolutely must fetch something from a site hosted somewhere else? Well, there is one way. But be warned: it's not efficient. And you're putting your site at risk: if the other site is down, or runs slowly, your page doesn't work or runs slowly.

Still on fire to do this? OK: you can do it with PHP. We'll take advantage of the fact that PHP's readfile command, which is typically used to insert a file into the page output, also supports URLs.

Note that to take advantage of this technique your page (the one doing the including) must be written in PHP. If your web server doesn't support PHP, this technique won't work for you. Also, support for fetching URLs must be enabled in your build of PHP (it usually is).

Try this code in a page called mypage.php:


<?php
// Insert the page we want at this point in our page
readfile("http://www.othersite.com/page.html");
?>

Of course, if the other site is down or running slowly, your page will have problems. If you don't like that, look for a solution that doesn't require that you fetch things from other sites every time you output a page!

If this technique does not work, but you do have PHP, it is possible that the URL-fetching feature has been disabled in your particular PHP configuration. If you have access to the php.ini file, you can fix this yourself by adding this line at the end:


allow_url_fopen = 1

Then signal your web server to reload its configuration. At the Linux command line you can usually do that with this command (as root):


service httpd reload

If you do not have access to php.ini, ask your web host to take care of this for you.

Share |

Legal Note: yes, you may use sample HTML, Javascript, PHP and other code presented above in your own projects. You may not reproduce large portions of the text of the article without our express permission.

Got a LiveJournal account? Keep up with the latest articles in this FAQ by adding our syndicated feed to your friends list!


Follow us on Twitter | Contact Us

Copyright 1994-2014 Boutell.Com, Inc. All Rights Reserved.