Helping people with computers... one answer at a time.

Using "include files", you can more easily organize data and remove the need to repeat the same information in several different files on your web site.

How do I include one HTML file inside another?

It's very common practice to have a consistent theme on a web site. You might have a standard navigation bar or a logo or even just a page footer with copyright and administrative information. Rather than actually having that information on each and every page it would certainly be nice if you could write your navigation bar once, keep it in one file, and then reference that file in each of several different pages. Make a change to the navigation bar in one place and instantly all pages are updated.

Welcome to "include" files - an incredibly powerful facility that can do this, and so much more, on your web site.

Includes break down into two categories: client and server. A "client" side include is one performed by your browser. Unfortunately, there is no specific syntax in HTML for client side includes so we have to play a small game using javascript. A "server" side include is exactly that - the include happens on your web server so the client browser never even knows it happened.

Server Side Includes

We'll start with the conceptually easier one: the server side include. The specific syntax will vary based on what type of server you have and what language your pages are written in.

Simple HTML pages on most common web servers can use a syntax called Server Side Include, or SSI. As an example in an HTML file a.html we can place this line:

<!--#include FILE="b.inc" -->

The page seen by a browser viewing a.html will consist of the contents of a.html before the include line, followed by the contents of b.inc, followed by the contents of a.html after the include line. Put the HTML for your navigation bar in a file like b.inc, and all your pages can show the exact same bar.

SSI is available on both Apache and Microsoft IIS web servers. On Apache some configuration may be needed but even if you don't have access to the actual server configuration files it can typically also be enabled by commands in a file named .htaccess that you will either find or can create in your server's web directory. Read more about Apache SSI here. Under IIS, SSI is enabled anytime you use ".asp" pages -- so the only configuration you need do is to name your pages .asp instead of .html. Read more about Server Side Include in ASP pages here.

Another popular ASP-like programming environment is PHP. PHP's include syntax is very simple:

<? readfile("b.inc"); ?>

Naturally, PHP has a host of additional processing ability but much like ASP the only requirement to make the include above work is to have PHP on your web server and name your file ".php".

With all of the above approaches, the browser viewing the page knows absolutely nothing about the include - it all happened before the page was downloaded. However, sometimes processing an include on the server isn't the right option. That's where processing an include on the client comes in.

Client Side Includes

As I mentioned above, there is no actual syntax for a client-side include but we can mimic one using Javascript. For example:

<script src="b.js" type="text/javascript"> </script>

When encountered, the browser downloads the script "b.js", executes it, and prints any output that the script might generate as if it were inline HTML. Technically that's not an include but the script "b.js" could be nothing more than a series of javascript "print" statements such as these:

document.write("<table>")
document.write("<tr>")
... and so on
"Welcome to 'include' files - an incredibly powerful facility that can do this, and so much more, on your web site."

You can see it's "printing" the HTML you want included. In other words, if you can format your include file as a series of javascript prints, you can use client-side include to insert it.

Now things can get very interesting, because we'll introduce two things: remote includes, and CGI programs, into the mix.

Remote Includes

The files we've included so far have been assumed to be on your own server in the same location as your other HTML pages. In almost all cases you can "include" using a full URL to any other server on the internet.

For client-side includes it's very simple. It just works:

<script src="http://example.com/b.js" type="text/javascript"> </script>

This works just like the earlier example except that b.js will get loaded from example.com rather than your own server. Similarly, PHP also "just works":

<? readfile("http://example.com/b.inc"); ?>

Unfortunately Apache SSI directives do not support remote includes. But there's almost always a way and we have a workaround using CGI.

CGI Includes

So far we've included only "static" HTML pages. As it turns out you can "include" the output of a server-run CGI program. This then becomes our solution for Apache's lack of support for remote includes. We'll start with this very short Perl program:

use LWP::Simple;
print "Content-type:text/html\n\n";
getprint ($ENV{'QUERY_STRING'});

We'll call it "proxy.pl". Proxy.pl must be appropriately installed on your server into your cgi-bin directory or its equivalent. By being local to your server, Include directives can reference it.

Proxy.pl simply fetches the contents of the URL passed as a parameter. This means we can perform an apache remote include this way:

<!--#include VIRTUAL="/cgi-bin/proxy.pl?http://example.com/b.inc" -->

It works like this:

  • The include executes proxy.pl with the parameter "http://example.com/b.inc"
  • Proxy.pl then fetches b.inc from example.com and prints it.

The result is that the contents of b.inc show up as an included file.

Includes + remote includes + CGI

So far we've used a CGI program to fetch what is essentially just another static html file. In fact, if we put all these pieces together we can create some very useful and interesting internet applications.

Randy Cassingham of This is True wanted to be able to provide his readers who had web sites the ability to host one of his stories. Sounds like a job for an include file, right? But he also wanted that story to change every day. That's more than a static HTML page; that's a CGI program that outputs a different story each day.

The result is tad.pl (True-A-Day) - a Perl script that picks a new story every day and outputs HTML. Given what we've talked about so far so you can probably guess how it's used. As a client side include:

<script src="http://www.thisistrue.net/cgi-bin/tad.pl" type="text/javascript"> </script>

That's it in its simplest form. Note that:

  • tad.pl is written in Perl. It does whatever it needs to gather the HTML for the story to be output.
  • tad.pl outputs javascript. In fact, tad.pl's output is nothing more than a series of "document.write" statements.
  • The client browser executes the javascript. The result is that it prints the HTML that tad.pl constructed for today's story.

Using tad.pl in a server-side include looks like this:

<!--#include VIRTUAL="/cgi-bin/proxy.pl?http://www.thisistrue.net/cgi-bin/tad.pl?ssi=1" -->

Note that as discussed above we had to use a local CGI program, proxy.pl, to fetch the remote URL.

Note also that we've added an additional parameter, ssi=1. This causes tad.pl to output the HTML it gathers without the javascript document.write statements. The final sequence looks like this:

  • proxy.pl executes on your server, and is passed the URL "http://www.thisistrue.net/cgi-bin/tad.pl?ssi=1".
  • proxy.pl fetches that URL, causing tad.pl to execute on www.thisistrue.net.
  • tad.pl once again does whatever it needs to gather the HTML for the story to be output.
  • tad.pl outputs the HTML to be included.
  • That output is returned to proxy.pl, which in turn prints it, where it becomes the "included text".
  • The client browser sees nothing but HTML - the HTML from the containing page with the HTML from tad.pl inserted in place of the include statement.

As you can see, includes are not only a great organizational tool allowing you to collect common information into fewer files, but also a powerful way to add functionality to your web site and perhaps others. I'll end this with True-A-Day included via a client side include:

Article C1891 - February 8, 2004 « »

Share this article with your friends:

Share this article on Facebook Tweet this article Email a link to this article
Leo Leo A. Notenboom has been playing with computers since he was required to take a programming class in 1976. An 18 year career as a programmer at Microsoft soon followed. After "retiring" in 2001, Leo started Ask Leo! in 2003 as a place for answers to common computer and technical questions. More about Leo.

Not what you needed?

46 Comments
Robert Persig
February 11, 2005 7:42 AM

The local IT guru said: "It is not possible to include HTML code to an existing html file. You have to edit all these 500 files and change the header manually."
No comment! Of course it is possible to edit 500 files at once and change strings in them, provided your local IT hero has not decided to have Micro$oft as OS and Livelink as web server.
Anyway, this hint helped me solving the problem, the local IT superman gave me week to finish the job. I had a lot of fun during this week ;o)

Cheers.

sindergoth
March 29, 2005 5:38 PM

this is just another more reliable verion of a previous post for php...


or

by doing it this way, you are making sure that the webserver no matter what brand will understand it, because >> alone is asp style..


the second choice >> include_once ensure that if a file being included to the page is already present it doesn't include it agaiin

Roland
September 18, 2005 6:14 PM

Glad I found this, I make extensive use of ssi includes I have spent ages trying to figure how to pass VARS to ssi, I see this can't be done.

I would like to have a page with a number of link to static pages like /product/1001.html and /product/1002.html and have them appear in the current page (without frames) when clicked

The closest I can get to this is by modifying your script proxy.pl, I'm am sure there is a more elegant way, especialy since the pages I am linking to are on the same website?
Regards Roly

#!/usr/bin/perl
use LWP::Simple;
print "Content-type:text/html\n\n";

open (FILE, "header.txt") || die "cannot open file: $!";
undef $/; # read in file all at once
print ;
close FILE;

getprint ($ENV{'QUERY_STRING'});

open (FILE, "footer.txt") || die "cannot open file: $!";
undef $/; # read in file all at once
print ;
close FILE;

MetaNeko
November 20, 2005 6:13 PM

for people
require_once("./file.ext"); // Requires File only once
Require("./file.ext"); // Requires File
include("./file.ext"); // Includes file

Now I am learning php and im quite good at it so ill drop a few php methods.
I always have a tons of files.. i spread my code everywere and its neatly sorted. but sometimes like lets say you wanna make a dice script you would put
ReRoll";
?>

Joe Formtester
December 18, 2005 4:58 PM

I cannot seem to get proxy.pl to work at all, even locally. Am I correct that the script file should simply be as follows:

#!/usr/bin/perl
use LWP::Simple;
print "Content-type:text/html\n\n";
getprint ($ENV{'QUERY_STRING'});

Can someone please help? SSI is working fine locally, CGI is enabled, the script is chmod'd to 755 (as is the directory), and I've tried every variant thinkable for the links on the shtml pages. Please see the following examples:

At http://www.tcconcepts.com/pagetest1.shtml I'm using a normal include like so:

<!--#include virtual="page1.txt" -->

...which is pulling in the sample text (everything below the line) just fine from the referenced .txt file.

At http://tcconcepts.com/pagetest2.shtml I'm using:

<!--#include virtual="/cgi-bin/proxy.pl?page1.txt" -->

At http://tcconcepts.com/pagetest3.shtml I'm using:

<!--#include virtual="/cgi-bin/proxy.pl?/page1.txt" -->
(note additional slash)

Neither of these latter pages (using proxy.pl) works. Nor do any other variants of the link including "./", "../" etc. I've also tried referencing different (later) versions of Perl. I'm not even getting error messages. The space is created, it's just not populated with the content. Any ideas?

Leo
December 18, 2005 5:48 PM

It's expecting a URL. So you'd want proxy.pl?http://whatever.... - that's the point of proxy.pl.

Joe Formtester
December 18, 2005 6:58 PM

Understood. But when that didn't work, I thought I'd try local. In any event, see:

http://www.tcconcepts.com/pagetest4.shtml where I'm using the following:

<!--#include virtual="/cgi-bin/proxy.pl?http://www.comptonmfg.com/page1.txt" -->

Again, the space is created, but no content fills it. To my non-Perl brain, this implies that it's seeing the need to insert something, but not what that something is.

Leo
December 18, 2005 7:20 PM

So just running http://tcconcepts.com/cgi-bin/proxy.pl?http://www.comptonmfg.com/page1.txt will test it outside of the SSI environment. It should just print the contents of the referenced file.

Obviously yours doesn't, and I'm not sure I see an obvious reason why. I would add a print statement before the getprint:

print $ENV{'QUERY_STRING'} . "\n";

That should simply ensure that the QUERY_STRING is coming in correctly. If it is (and I'd guess it is) then I would suspect some kind of configuration issue on your server that's preventing getprint from working.

Joe Formtester
December 18, 2005 8:15 PM

Okay, that pulls in the URL, but not the contents of the URL.

The script now looks like this:

#!/usr/bin/perl
use LWP::Simple;
print "Content-type:text/html\n\n";
print $ENV{'QUERY_STRING'} . "\n";
getprint ($ENV{'QUERY_STRING'});

Using the http://www.tcconcepts.com/pagetest4.shtml link now pulls in text that reads "http://www.tcconcepts.com/page1.txt", rather than the HTML code that resides in that file.

Just curious. Could the fact that my version of LWP is 5.53 have anything to do with it? By the way, thanks for your help; I really appreciate it.

For what it's worth, what I'm trying to do is find a way to allow others (remote sites) to be able to insert an include (and perhaps a small cgi script like proxy.pl) that pulls actual code from a page on a site that I control. IF you have some other idea, I'm all for it.

Leo
December 18, 2005 8:20 PM

It's possible that LWP is an issue, but then other things could be as well. I'd look at your error logs, and if you have shell access, telnet in or ssh in to the server and run the perl script directly from a command line and see if it does what you expect. See if you can get ANY "getprint" to work.

An alternative might be to try PHP if your server has it. A test.php in your regular (not cgi-bin) directory that has this will tell you if it would work:

<? include ("http://whatever"); >

This *may* work, if your PHP configuration has it enabled.

Joe Formtester
December 18, 2005 8:48 PM

Well, running it from Telnet (if I'm even doing it correctly) yields the following error message:

No such file or directory

...as if it's looking for a file named proxy.pl?http://www.comptonmfg.com/page1.txt rather than actually going to the address in the query string.

I've adjusted the path to perl to a later version of perl. No help there. I'm an HTML guru, not a perl guru, so I am admittedly ignorant of a lot of this. How do I test getprint?

Also, I'm wondering if as small as this script is, it might not be overkill for my needs. What I mean is, if everyone who I want to use this script is going to be referencing the same page, is there an even simpler way; for example, embedding the actual URL in the proxy.pl script. That may be what we've achieved with the extra line of code, in which case we still have a getprint issue, but I thought it worth mentioning. The bottom line is if people will need to install the script anyway, and if the only thing I want them pulling data from is a pre-determined text file, is there a way to do that and bypass the query string altogether?

Leo
December 18, 2005 9:05 PM

Form the command line you have to specify the parameter using environment variables (set QUERY_STRING) and so on.

But yes, hard code a URL into the perl script instead of attempting to use the parameter and see if you can get that working.

Joe Formtester
December 18, 2005 9:40 PM

Here is how I'm hard coding the URL into the script:

#!/usr/bin/perl5.00405
use LWP::Simple;
print "Content-type:text/html\n\n";
getprint (http://www.comptonmfg.com/page1.txt);

And I'm referencing it like this in the shtml page file:

<!--#include VIRTUAL="/cgi-bin/proxy.pl" -->

and it returns an error. Is this correct or am I missing something?

Joe Formtester
December 18, 2005 10:06 PM

Hey, it looks like I got it to work with this:

#!/usr/bin/perl
use LWP::Simple;
print "Content-type:text/html\n\n";
print get("http://www.comptonmfg.com/page1.txt");

Does that make sense? There's no getprint involved. I was just goofing around and, poof, it worked. Second question: If this DOES make sense, should that same script work with other Apache configurations (I'm assuming that people with ASP and PHP will be able to simply pull in the content from my page with just the appropriate include, skipping the script)?

Dave
January 17, 2006 3:49 PM

and again
obviously no tags allowed
#include VIRTUAL="/cgi-bin/GetRemote.pl?http://www.colosoccer.com.au/pentire.html"

Paul Evans
May 22, 2006 9:12 AM

Try using CSS and putting images as backgrounds to

within the HTML code.
Have a look at www.promotion-croisieres.com to see how this is done. Its a php file calling an include for the navbar, but the background image is tucked away in the CSS...

qixsilver
May 26, 2006 1:11 PM

Shraddhan,

If you're following the guidelines listed in this article, then technically everything should be ok. I was just fiddling around with this, and had some issues getting the includes to display properly. But by simply renaming my file from curious.html to curious.asp, the include then worked flawlessly. The include didn't care what the file extension was (html, asp, dat etc) for the file I used to hold the included data, it simply took what was in the included file and flowed it into the .asp file.

As an overview, I used 2 files:
- curious.asp
- content.dat

curious.asp holds:
<html>
<head>
<title>include test</title>
</head>
<body bgcolor= "#ffffff" topmargin="0" leftmargin="0" marginheight="0" marginwidth="0">

<!--#include FILE="content.dat" -->

</body>
</html>

content.dat holds:
<table width=764 BORDER=0 CELLSPACING=0 CELLPADDING=0>
<tr valign=top>
<td align=left valign=top>
Stuff I wanna say and images I want to include etc.
</td>
</tr>
</table>

A stumbling block that could be messing things up for you is: is the server that's hosting your files .asp compatible? if it's not, then your includes will not work. (using the format of: <!--#include FILE="content.dat" --> ). Hope that helps you out. To my knowledge, the framesets should not be causing a problem.

Naseer
May 31, 2006 10:43 PM

Hi All,

Well i read all the solutions provided but i could'nt find any solution to my problem. i have two html files ie index.html and menu.html , i want to include the menu.html in my index.html. i used <!-- #include FILE="menu.html --> but its not working.. please provide me the better solution

regards
Naseer

Leo
May 31, 2006 10:48 PM

a) you have a space between the "-" and the "#" - that's enough to have it fail.

b) the server must be configured to support SSI. You should check.

skimaster18
June 11, 2006 10:41 AM

i can't ge this to work. i am using apache, i admit fairly new with apache, but i have followed the steps numerous times to use SSI on apache, and everytime, it just completely ignores my include statement. using the correct context also.

Leo
June 11, 2006 3:24 PM

Check with your host - it may need to be enabled, or it may only be enabled for certain file extensions (like .shtml).

Mahesh
September 3, 2006 9:56 PM

I use the code
as u mensioned. and also
tested.
in my main html page. but it doesn't work.
I want to include my common header in to all pages.
Please help me.
Thanks

Kris
September 7, 2006 6:29 AM

dear Leo

i have got three files help.htm ,contact.php and ..inc
i have called the inc file inside teh php file
now i want to call this php file inside teh htm file , i.e when i click help.htm the contents of contact.php should called
i tried the below mentioned php tag on help.htm but all in vain. apprecaite your invaluable assistance

AXIS Engineering Consultants

Leo Notenboom
September 7, 2006 11:36 AM

That type of include (<?) needs to happen in a PHP file, you have it in an HTML file. You probably need to use SSI include. The style of include needs to match the type of source file, not the type of file being included.

T.ashok kumar
May 12, 2007 4:30 AM

I've idea about how to write include syntax in a html file. http://www.seobbsr.com/

jfk
May 25, 2007 7:29 AM

Hi Leo, thanks for this informative article.

Suggestion to all those who want to include html in html and don't know much about servers, php and or ssi: Use the client-side method described here. It's easy and it works as long as Javascript is not disabled on the visitors browser. For this case you still can add this:
<noscript>Please enable Javascript in your Browsersettings!</noscript>

cheers

David Smith
July 29, 2007 2:19 AM

Thank-you for the helpful info on %includes.
I've used them in programming in other non-web languages (PL1, JCL PL/SQL etc), but not in web context.

Text at top/left of web pages often contributes to a page's ranking for search engines. If this text is removed, a menu for example, to a seperate document (by any of the described methods) will this likely mean the page has a lower ranking with such keyword text omitted?

HELPFUL
November 23, 2007 8:22 PM

I READ THIS ARTICLE, IT DOESN'T HELP AT ALL FOR CLIENT SIDE SCRIPTS aka INCLUDING A FILE IN ANOTHER FILE...

HERE IS A VERY HELPFUL ARTICLE:

http://www.moock.org/webdesign/javascript/client-side-include/index.html

Volker
January 24, 2008 12:43 AM

I finally got my problem solved, which was not only a client side include, but a client side include where I had to calculate which include to include. (Did I make myself clear or what? ;-> )
I wanted to include the daily watchwords (see www.ebu.org) in my "Outlook Today" page.

This is my code (I hope it shows well):


function fuehrendeNull(wert)
{
if (wert")


If the cite-tags are showed, they are the ones which shouldn't show...
If it doesn't show at all or only very strange, my trick is to do a "document.write" that writes ANOTHER "script"-Statement, in which the variable is inserted.

Volker
January 24, 2008 12:53 AM

Well, the code didn't show really well.
Here it is again, only with much less

sezer
July 13, 2008 12:41 PM

Html Attribute for -- Marquee Slide Image and Text ---
http://html-lesson.blogspot.com/2008/06/marquee-slide-image-text.html

Henry Leparskas
July 16, 2008 8:36 AM

for apache, when you want to use Server Side Includes, with the default configuration, you will have to have your file 'file.shtml' and not just 'file.html'. This is easy to trip over when you first start.
I believe that you can have apache look at all 'html' files for includes, but there is a penalty for this, which I can't recall -could be efficiency.

Leo
July 17, 2008 10:14 AM

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I've found that ".shtml", while common, is not at all
standard. It definitely pays to understand your specific web
server's configuration.

Also, scanning all .html (and .inc) is definitely possible,
and not a large performance hit at all. This site, for
example, is configured that way.

Leo


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)

iD8DBQFIf33UCMEe9B/8oqERAgHjAJ4vvXyNhWpDmcRM5pHuHK5dp1Hi1ACgiVua
BPNQ1KC/NkFsfqPPBwRR0xI=
=KL4T
-----END PGP SIGNATURE-----

Bruce A. Julseth
August 3, 2008 7:54 PM

Couldn't get the included file to display correctly. Used php require_once("BaseMenu.php"): You can see the problem at URL: http://medical.julseth.net/disMP.php

cheap propecia
May 30, 2009 2:20 PM

Excellent site, It was pleasant to me.

Gamel
November 2, 2009 6:28 PM

Thank you! It works with an URL?

Gregory Kramida
January 4, 2010 7:48 PM

How could you not mention iframes! iframes! iframes!

Iframes don't include files, they include pages. There are also other intricacies that iframes introduce that make them less than idea in the general case.
Leo
05-Jan-2010

Leonid
May 20, 2010 10:23 AM

I found that when include is used instead of the hard coding it inserts an extra line as if it's adding
. Why is that and how this can be avoided?

trans1t
September 21, 2010 12:43 PM

Leonid:
I've found that this can occur when the included file is encoded as "UTF-8". Change it to "UTF-8 without BOM" using a program like Notepad++ and you should be good to go.

JustYourAverageCodemonkey
February 11, 2011 11:00 PM

Excellent article! Including files as opposed to pages, such as in iframes, is far more convenient, in my opinion. I know that with HTML5, iframes will be going the way of the dodo. Do you know if included files will still be valid, and if they will be, will there be any changes to the syntax?

Much thanks for writing this! *bookmarked*

Christian Reed
June 3, 2011 8:35 AM

Thanks. BTW, it seems to me that JSP's include syntax was left out. For example:

higgsy
July 27, 2011 8:14 AM

thanks, my include now works - but if I want to include a footer on every page, does this mean iIhave to rename all 56 pages in my site from .htm to .php? thanks

Depends on exactly what you did, wich technique you used, and what the capabilities of your web server are.
Leo
27-Jul-2011

Tom
August 19, 2011 7:01 AM

Hello. Great article thanks! However i'm having problems with teh client side include. I have sucessfully used to pull in a simple line of text into my page, for example: document.write("

i am an include

") . This is all cool. However, if I try to add a class to that paragraph, I get nothing. For example: document.write("

i am an blue include

") doesn't work. It seems as though the "" characters are breaking it. Any ideas? I need to be able to style what's in my include! Thanks in advance.

Greg McGee
August 21, 2011 7:59 AM

1. I subscribed but didn't get an email.
2. Question: I have a dropdown menu with a pick list of every country in the world. Its set up as a regular "select" box with all the data on the html page right now. But it slows down the page load and makes working with the file in Dreamweaver very slow too. I've tried moving it off the page with an #include, but it no longer works. What can I do?

sumeet chawla
February 8, 2012 10:16 AM

thank u
very much sir!!
i was really stuck in this problem!!!
but after going through your article!!!
i solved this problem very easily!!!
once again thank u
very much!!
jai gurudev!!!

Mike Tennor
March 27, 2013 12:28 PM

Can a path be put in an HTML include file?

This is the example given in the article.
<!--#include FILE="b.inc" -->

But is it possible to have a path or relative path within the include file statement?

For example,
<!--#include FILE="../otherdirectory/b.inc" -->.

I've tried this and it didn't work so either it can't be done or I've done something wrong.

Please help,

Thanks,
Mike

It depends on many of the specifics but in general - yes - it can be done.
Leo
28-Mar-2013

Comments on this entry are closed.

If you have a question, start by using the search box up at the top of the page - there's a very good chance that your question has already been answered on Ask Leo!.

If you don't find your answer, head out to http://askleo.com/ask to ask your question.