Apache Week

Copyright 1996-2005
Red Hat, Inc.

First published: 9th August 1996

Using Server Side Includes

While standard HTML files are fine for storing pages, it is very useful to be able to create some content dynamically. For example, to add a footer or header to all files, or to insert document information such as last modified times automatically. This can be done with CGI, but that can be complex and requires programming or scripting skills. For simple dynamic documents there is an alternative: server-side-includes (SSI).

SSI lets you embed a number of special 'commands' into the HTML itself. When the server reads an SSI document, it looks for these commands and performs the necessary action. For example, there is an SSI command which inserts the document's last modification time. When the server reads a file with this command in, it replaces the command with the appropriate time.

Apache includes a set of SSI commands based on those found in the NCSA server plus various extensions. This is implemented by the includes module (mod_includes).

Telling Apache to Use SSI

By default, the server does not bother looking in HTML files for the SSI commands. This would slow down every access to a HTML file. To use SSI you need to tell Apache which documents contain the SSI commands.

One way to do this is to use a special file extension. .shtml is often used, and this can be configured with this directive:

  AddHandler server-parsed .shtml
  AddType    text/html     shtml

The AddHandler directive tells Apache to treat every .shtml file as one that can include SSI commands. The AddType directive makes such that the resulting content is marked as HTML so that the browser displays it properly.

An alternative method of telling the server which files include SSI commands is to use the so-called XBitHack. This involves setting the execute bit on HTML files. Any file with a content type of text/html (i.e. an extension .html) and with the execute bit set will be checked for SSI commands. This needs to be turned on with the XBitHack directive.

For either method, the server also needs to be configured to allow SSIs. This is done with the Options Includes directive, which can be placed in either the global access.conf or a local .htaccess (although the latter must first be enabled with AllowOverride Options). Since some SSI commands let the use execute programs which could be a security risk, an alternative option, IncludesNOExec lets SSI commands work except for any which would execute a program.

SSI Commands

All SSI commands are stored within the HTML in HTML comments. A typical SSI command looks like this:

  <!--#flastmod file="this.html" -->

In this case the command is flastmod, which means output the last modified time of the file given. The arguments specify the file "this.html" (which might be the name of the file containing this command). The whole of the command text, including the comment marker <!-- and --> will be replaced with the result of this command.

In general, all commands take the format:

  <!--#command arg1="value1 arg2="value2 ... -->

where arg1, arg2, etc are the names of the arguments and value1, value2 etc are the values of those arguments. In the flastmod example, the argument is 'file' and it's value is 'this.html'. Often commands can take different argument names. For example, flastmod can be given a URL with the argument virtual, to get the last modified time from the server. For example:

  <!--#flastmod virtual="/" -->

to get the last modification time of the home page on the server (this is useful if the page being accessed might have a different file name, for instance).

Besides flastmod, there are SSI commands which get the size of a file or URL, the contents of a variable (passed in by the server), the contents of another file or URL, or the result of running a local file. These are documented in the NCSA tutorial on server side includes.

When SSI commands are executed, a number of 'environment variables' are set. This include the CGI variables (REMOTE_HOST etc), and some more, such as DOCUMENT_NAME and LAST_MODIFIED. These can be output with the echo command (so a better way of getting the last modification time of the current file would be <!--#echo var="LAST_MODIFIED" -->).

Extended SSI

Apache extends the standard (NCSA-compatible) SSI language considerably. Some of the extensions include:

  • Variables in commands: Apache allows variables to be used in any SSI commands. For example, the last modification time of the current document could be obtained with <!--#flastmod file="$DOCUMENT_NAME" -->
  • Setting variables: the set command set be used within the SSI to set variables.
  • Conditionals: SSI commands if, else, elif and endif can be used to include parts of the file based on conditional tests. For example, the $HTTP_USER_AGENT variable could be tested to see the type of browser and different HTML codes output depending on the browser capabilities.


Here are some examples of using SSI:

Displaying document information
The following code puts the document modification time on the page:
  Last modified: <!--#echo var="LAST_MODIFIED" -->

Adding a footer to many documents
Add the following text to the bottom of each of the documents:
  <!--#include file="footer.html" -->

Hide links from external users
Use the if command and the REMOTE_ADDR CGI variable to see if the user is in the local domain:
  <!--#if expr="$REMOTE_ADDR = /^1.2.3./" -->
    <a href="internal-documents.html">Internal Documents</a>
  <!--#endif -->

(Where 1.2.3 is the IP address prefix of the local domain).

Comments or criticisms? Please email us at editors@apacheweek.com