Blog / Nginx Server-Side Includes
Suppose you have a navigation bar you want to put on every page of your static HTML website. The "obvious" solution is to copy and paste that navbar into every page (or use a templating engine that does that for you). If you aren't using a templating engine, updating that navbar on each individual page will be a pain... unless you use server-side includes.
Server-side includes essentially ask your web server to embed the contents of some file (or more generally, the result of a different HTTP request) into a given file when it is served. (For the C programmers: it's analogous to the #include preprocessor directive.)
This page will discuss how to use server-side includes with the Nginx web server running on Linux. Apache is capable of them as well, but the config files have different syntax.
Enabling Server-Side Includes
First, enable server-side includes for your site with the config file option
"ssi on" like so:
File: /etc/nginx/sites-available/my_site
server {
server_name my_site.com;
root /var/www/my_site.com;
# ... (there may be other stuff here) ...
location / {
# Enable Server-Side Includes for only this site
ssi on;
}
# ... ... ...
}
This example enables server-side includes in any file or subdirectory of this site's root. You can do this globally for Nginx, but I prefer to do it in individual sites' config files to avoid some security risks. This way, only files contained in the directory for this site can be included.
Restart Nginx (systemd users: sudo systemctl restart nginx)
to make the config file changes take effect.
Including a File
Suppose you have a website with 3 pages, page_0.html,
page_1.html, and page_2.html.
You want to include the same navbar (shown below) on all of them.
File: /var/www/my_site.com/page_0.html
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>My Site</title>
</head>
<body>
<div class="navbar">
<ul>
<li><a href="/page_0.html">Page 0</a></li>
<li><a href="/page_1.html">Page 1</a></li>
<li><a href="/page_2.html">Page 2</a></li>
</ul>
</div>
<div class="container">
<h1>Page 0</h1>
<p>This is my cool web page.</p>
</div>
</body>
</html>
Then, you would copy the navbar into its own file, navbar.html.
File: /var/www/my_site.com/navbar.html
<div class="navbar">
<ul>
<li><a href="/page_0.html">Page 0</a></li>
<li><a href="/page_1.html">Page 1</a></li>
<li><a href="/page_2.html">Page 2</a></li>
</ul>
</div>
On each page, where you want the navbar to be inserted, insert a comment with the
#include directive telling Nginx to include the navbar.
File: /var/www/my_site.com/page_0.html
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>My Site</title>
</head>
<body>
<!--#include file="/navbar.html"-->
<div class="container">
<h1>Page 0</h1>
<p>This is my cool web page.</p>
</div>
</body>
</html>
...And that's it. When a user then navigates in his browser to
www.my_site.com/page_0.html, the page served to him will be identical to
the original page_0.html example in this document, because
Nginx replaced the #include comment with the contents of the navbar file.
This way, if you make any changes to navbar.html,
they will instantly show up on any page that includes that file.
You can also change the path to page_0.html and the navbar
will still show up and behave the same.
For best results, make the path to the included file an absolute path,
not a relative path. Trying to ../
into a parent directory will not work. Also, for best results, make sure any
links in the included file are to absolute paths.
Including the Result of a HTTP Request
The file="..." syntax tells Nginx that you want to include a file,
but using virtual="..." instead is a generalization that will
include the output of whatever HTTP request is between the quotation marks.
This is useful for viewing the output of CGI scripts, ex.
<!--#include virtual="/my_script.pl?query=mystring"-->.
Conclusion
Server-side includes are useful for anyone who wants to avoid HTML templating engines or PHP, node, etc. for creating site content. The site title, navbar, and footer you see on this site are all server-side includes.
This article is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.