Technology in terms you understand. Sign up for the Confident Computing newsletter for weekly solutions to make your life easier. Click here and get The Ask Leo! Guide to Staying Safe on the Internet — FREE Edition as my thank you for subscribing!

How do I include one HTML file inside another?

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.

Become a Patron of Ask Leo! and go ad-free!

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="" -->

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, followed by the contents of a.html after the include line. Put the
HTML for your navigation bar in a file like, 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(""); ?>

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

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

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:

... 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

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

<script src="" type="text/javascript">

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

<? readfile(""); ?>

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 “”. 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. 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/" -->

It works like this:

  • The include executes with the parameter “”
  • then fetches from and prints it.

The result is that the contents of 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

The result is (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

<script src="" type="text/javascript">

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

  • is written in Perl. It does whatever it needs to gather
    the HTML for the story to be output.
  • outputs javascript. In fact,’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 constructed for today’s story.

Using in a server-side include looks like this:

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

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

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

  • executes on your server, and is passed the URL
  • fetches that URL, causing to execute
  • once again does whatever it needs to gather the HTML for the
    story to be output.
  • outputs the HTML to be included.
  • That output is returned to, 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 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:

Do this

Subscribe to Confident Computing! Less frustration and more confidence, solutions, answers, and tips in your inbox every week.

I'll see you there!

46 comments on “How do I include one HTML file inside another?”

  1. 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)


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


    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

  3. 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, 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

    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;

  4. 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

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

    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 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 I’m using:

    <!–#include virtual=”/cgi-bin/” –>

    At I’m using:

    <!–#include virtual=”/cgi-bin/” –>
    (note additional slash)

    Neither of these latter pages (using 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?

  6. So just running 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.

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

    The script now looks like this:

    use LWP::Simple;
    print “Content-type:text/html\n\n”;
    print $ENV{‘QUERY_STRING’} . “\n”;
    getprint ($ENV{‘QUERY_STRING’});

    Using the link now pulls in text that reads “”, 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 that pulls actual code from a page on a site that I control. IF you have some other idea, I’m all for it.

  8. 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.

  9. 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 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 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?

  10. 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.

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

    use LWP::Simple;
    print “Content-type:text/html\n\n”;
    print get(“”);

    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)?

  12. 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:
    <title>include test</title>
    <body bgcolor= “#ffffff” topmargin=”0″ leftmargin=”0″ marginheight=”0″ marginwidth=”0″>

    <!–#include FILE=”content.dat” –>


    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.

    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.

  13. 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


  14. 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.

  15. 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.

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

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

  18. dear Leo

    i have got three files help.htm ,contact.php and
    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

  19. 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.

  20. 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>


  21. 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?

  22. 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 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.

  23. 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.

    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.


    Version: GnuPG v1.4.7 (MingW32)


  25. 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.


  26. 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?

  27. 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.

  28. 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*

  29. 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.


  30. 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.

  31. 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?

  32. 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!!!

  33. Can a path be put in an HTML include file?

    This is the example given in the article.
    <!–#include FILE=”” –&gt

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

    For example,
    &lt!–#include FILE=”../otherdirectory/” –&gt.

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

    Please help,


    It depends on many of the specifics but in general – yes – it can be done.



Leave a reply:

Before commenting please:

  • Read the article.
  • Comment on the article.
  • No personal information.
  • No spam.

Comments violating those rules will be removed. Comments that don't add value will be removed, including off-topic or content-free comments, or comments that look even a little bit like spam. All comments containing links and certain keywords will be moderated before publication.

I want comments to be valuable for everyone, including those who come later and take the time to read.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.