Navigation menu


Page best viewed in
800x600 with lots of colours
ArgoNet Support

Note: SSI is not yet available for general use on the ArgoNet server. This document has been prepared in anticipation of this service being made available.


The SSI (Server Side Includes) system is a little like a primitive JavaScript, in that you embed commands inside comments and these can re-write parts of your document based on certain environment variables (such as time). However, SSI commands are executed by the server while it's serving your web page, so that by the time the page reaches the viewer's browser all they see is the resultant HTML with no trace of the original commands; the upshot of this is that unlike JavaScript they work with all browsers. It's generally used by ISPs to create error documents that can give you useful information.

The downside is that SSI is much more limited than something like JavaScript, and in fact there are only six basic commands, and you'll probably only get five of these to work. They all follow the same syntax, which must be followed exactly:

<!--#command cmd_argument="value" -->
Note that there is no gap between the <-- and the #, and between the # and the command.


  • config

    This sets the format of output generated by certain environment variables - for instance, using long or short months in dates. You can have more than one of these in a page, just put one right before it's needed for one command, and then another just before the second command and so on.

    There are three possible arguments for this command: timefmt, sizefmt and errmesg.

  • timefmt
    You can set the time and date format of various echo commands using a system of Unix-style tokens (very similar to those used on Acorn machines for !Alarm, or SYS"OS_ConvertDateAndTime" for the technically minded). To set the format for the date to dd/mm/yy, you would use:
    <!--#config timefmt="%d/%m/%y" -->

    And here's a full list of those tokens:

    %a abbreviated weekday name
    %A full weekday name
    %b abbreviated month name
    %B full month name
    %c locale's appropriate date and time representation
    %C default date and time format
    %d day of month - 01 to 31
    %D date as %m/%d/%y
    %e day of month - 1 to 31 (single digits are preceded by a blank)
    %h abbreviated month name (alias for %b)
    %H hour - 00 to 23
    %I hour - 01 to 12
    %j day of year - 001 to 366
    %m month of year - 01 to 12
    %M minute - 00 to 59
    %n insert a new-line character
    %p string containing ante-meridiem or post-meridiem indicator (by default, AM or PM)
    %r time as %I:%M:%S %p
    %R time as %H:%M
    %S second - 00 to 61, allows for leap seconds
    %t insert a tab character
    %T time as %H:%M:%S
    %U week number of year (Sunday as the first day of the week) - 00 to 53
    %w day of week - Sunday = 0
    %W week number of year (Monday as the first day of the week) - 00 to 53
    %x Country-specific date format
    %X Country-specific time format
    %y year within century - 00 to 99
    %Y year as ccyy (4 digits)
    %Z timezone name

  • sizefmt
    This is to set the format for how file sizes are displayed:
    <!--#config sizefmt="<x>" -->
    sizefmt="abbrev" 19K

  • errmesg
    This sets what error message is displayed when SSI generates an error - for instance, when you try to include a file which doesn't exist.

    The following shows the format of this command, but using the text that appears as the default - change this as you see fit, perhaps even using it to to errors appearing altogether!

    <!--#config errmesg="[an error occurred while processing this directive]" -->

  • echo

    This command allows you to basically dump the contents of some of the web server's internal variables to the page - for instance, where the viewer has just come from or when the page was last updated. Not all of these will return meaningful responses, sometimes because that part isn't in use for the particular page, and sometimes because the services isn't in use on that server.

    DATE_GMTSaturday, 15-Dec-2018 22:29:39 GMT *
    DATE_LOCALSaturday, 15-Dec-2018 22:29:39 GMT *
    LAST_MODIFIEDSunday, 22-Apr-2007 20:31:31 BST *¹
    * - can be altered using the config command
    ¹ - see also flastmod

    <!--#echo var="DATE_LOCAL" -->
    Saturday, 15-Dec-2018 22:29:39 GMT

  • include

    This allows you to include the contents of another file in the HTML file - so for instance you can automatically add the same header to each page on your site and only need to change one file to automatically change the header for every page.

    There are two ways of referencing the file you want to include - file and virtual.

    <!--#include file="text.txt" -->
    file allows you to specify a file with an address working up from the current file - for instance file="text.txt" or file="textfiles/text.txt"; note however you cannot go backwards, for instance you cannot use file="../text.txt". For that you must use the virtual version:
    <!--#include virtual="../text.txt" -->

  • fsize

    This command is called in the same way as include (i.e. with the argument of file or virtual), but simply prints the size of the file specified. The output can be changed by the config command.
    <!--#fsize file="SSI.html" -->

  • flastmod

    Again, this command is called in the same way as include (i.e. with the argument of file or virtual), but prints the date the file was last modified. It can be influenced by the config command too.
    <!--#flastmod file="SSI.html" -->
    Sunday, 22-Apr-2007 20:31:31 BST

  • exec

    This is used to execute programs - and will probably be switched off so you can't damage the server.

    SSI programming

    So far you've learnt some fun commands which can add that extra touch to your websize; however, if you want to get into the more advanced use of SSI, you can also do things like conditional checks. For instance, change the colour of a web page background colour based on the time of day!

    This documentation is taken from the Apache website,

  • printenv

    The printenv command - just used on its own, with no arguments - prints out a listing of all existing variables and their values. This is only useful when you've set some variables!

  • set

    This sets the value of a variable.


    <!--#set var="category" value="help" -->
    The name of the variable to set.
    The value to give a variable.

  • Include Variables

    In addition to the variables in the standard CGI environment, these are available for the echo command, for if and elif, and to any program invoked by the document.
    The current date in Greenwich Mean Time.
    The current date in the local time zone.
    The filename (excluding directories) of the document requested by the user.
    The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document.
    The last modification date of the document requested by the user.

  • Variable Substitution

    Variable substitution is done within quoted strings in most cases where they may reasonably occur as an argument to an SSI directive. This includes the config, exec, flastmod, fsize, include, and set directives, as well as the arguments to conditional operators. You can insert a literal dollar sign into the string using backslash quoting:

    <!--#if expr="$a = \$test" -->

    If a variable reference needs to be substituted in the middle of a character sequence that might otherwise be considered a valid identifier in its own right, it can be disambiguated by enclosing the reference in braces, à la shell substitution:

    <!--#set var="Zed" value="${REMOTE_HOST}_${REQUEST_METHOD}" -->

    This will result in the Zed variable being set to "X_Y" if REMOTE_HOST is "X" and REQUEST_METHOD is "Y".

    EXAMPLE: the below example will print "in foo" if the DOCUMENT_URI is /foo/file.html, "in bar" if it is /bar/file.html and "in neither" otherwise:
    <!--#if expr="\"$DOCUMENT_URI\"= \"/foo/file.html\"" -->
    in foo
    <!--#elif expr="\"$DOCUMENT_URI\" = \"/bar/file.html\"" -->
    in bar
    <!--#else -->
    in neither
    <!--#endif -->

  • Flow Control Elements

    The basic flow control elements are:

    <!--#if expr="test_condition" -->
    <!--#elif expr="test_condition" -->
    <!--#else -->
    <!--#endif -->

    The if element works like an if statement in a programming language. The test condition is evaluated and if the result is true, then the text until the next elif, else. or endif element is included in the output stream.

    The elif or else statements are be used the put text into the output stream if the original test_condition was false. These elements are optional.

    The endif element ends the if element and is required.

    test_condition is one of the following:

    true if string is not empty
    string1 = string2
    string1 != string2
    string1 < string2
    string1 <= string2
    string1 > string2
    string1 >= string2
    Compare string1 with string 2. If string2 has the form /string/ then it is compared as a regular expression. Regular expressions have the same syntax as those found in the Unix egrep command.
    ( test_condition )
    true if test_condition is true
    ! test_condition
    true if test_condition is false
    test_condition1 && test_condition2
    true if both test_condition1 and test_condition2 are true
    test_condition1 || test_condition2
    true if either test_condition1 or test_condition2 is true

    "=" and "!=" bind more tightly than "&&" and "||". "!" binds most tightly. Thus, the following are equivalent:

    <!--#if expr="$a = test1 && $b = test2" -->
    <!--#if expr="($a = test1) && ($b = test2)" -->

    Anything that's not recognized as a variable or an operator is treated as a string. Strings can also be quoted: 'string'. Unquoted strings can't contain whitespace (blanks and tabs) because it is used to separate tokens such as variables. If multiple strings are found in a row, they are concatenated using blanks. So:

         string1    string2  results in string1 string2
        'string1    string2' results in string1    string2