Building a static website (part 1)
01-AUG-2025, updated 13-AUG-2025
In a former life, I worked as a Software Engineer and Applications Architect for a large enterprise software company. A major part of my role was to write and maintain technical documentation for the various development teams that I worked with. Almost all of that documentation was written using HTML, originally handwritten and uploaded as part of an internal website that I looked after. Later on, for various reasons, I began to generate the HTML from text files, but otherwise the basic structure remained the same.
The point of mentioning all this is that I have also on and off attempted to maintain a personal website and have done so using similar methods. In both cases, the website is intended to be static, with little or no JavaScript. This is quite deliberate and I may explore the reasons for this during this series of blog posts.
The reason I am writing this and subsequent blog posts is to try and document what it takes to design and build a static website from scratch, using a number of just basic tools, such as text files and bash scripts, running under Linux environment. I want to talk about the various design decisions that need to be taken and how this translates into reality.
Note that I would not consider this to be a tutorial that anyone would follow exactly, because the great majority of people would likely want to take a different approach to building a website, whether it be static or otherwise. There are of course loads of options, including something like Publii for a static website or even WordPress for a very comprehensive solution. However, I quite enjoy the whole process of "handrolling", so that's what I'm going to do and document that process in the meantime. I shall of course shamelessly take inspiration from the various websites and tools that are out there.
One important reason that this series is being published as a series of blog posts, is that it allows the reader to see the evolution of the website and web page design, from basic to more fully formed.
Building the Minimum Viable Product
In the world of software engineering, there is the concept of the MVP (Minimum Viable Product), which summarises the approach in software development where you try to launch a new application as quickly as possible by releasing something that contains the minimum set of features that would make it useful and then iterating from there. I think that building this website and the blog post that goes along with it should be handled in a similar way. In other words, I should begin by thinking about what is required at a minimum to publish some sort of homepage that links to the earliest version of the blog post, otherwise I would end up completely designing the entire site before I could actually show anything. To that end, I think we need to consider the following steps:
- Obtaining web space to actually host the site.
- Designing the overall website structure.
- How to write the basic HTML required for the website.
- What is the minimum CSS that we should start with.
- Authoring the first HTML page that makes up this blog post.
Let's consider these in order.
Obtaining web space to actually host the site
This is vitally important of course, but is probably the least relevant for this specific blog post, because there are clearly plenty of ways that this can be done and trying to explain whether one should use something like a VPS (Virtual Private Server) or maybe self host is somewhat beyond the scope of this article. Therefore, I will just explain that personally, I have a server machine that sits inside my local network that I will be using to test the website internally, until it is time to finally publish the results.
Designing the overall website structure
A static website requires some kind of underlying structure that will reflect what it is being used for and my site is no exception to that. By structure, I literally mean the directory structure that will then translate to the same structure on the web server. My main consideration is to keep the structure relatively flat and straight forward, so I don't want to have a deep directory structure. Avoiding this makes a number of things easier.
Let's start with the HTML root directory, which for the purposes of this article, I will refer to via the environment variable SAXBYNET_HTML. On a web server, that might be something like "/var/www/html", or a suitable directory in your development machine (which is the case for me). Therefore, we could use the following commands to create the necessary directories:
cd $SAXBYNET_HTML
mkdir -p stylesheets images icons
It should hopefully be fairly evident what those directories are going to be used for. I will of course come back to cover these things in much more detail later on.
After this, we also have to think about the structure of the site that will actually hold HTML pages such as the blog post that I am currently writing. In my case, I want to create directories that reflect the broad categories of things that I am interested in. However, for now, I will just be creating a "blog" directory that contains the very blog post you are reading now. I will eventually come back later to add more directories.
mkdir -p blog/projects
The "projects" directory requires a little more explanation. This directory will contain a series of text files that are intended to document important information about each web page that is created under a particular subject area. The idea behind this will be covered in more detail later on.
Each subject area directory (such as "blog"), then contains a number of subdirectories, one for each article (or series of related articles) that are being written. As a specific example, this particular blog post is contained within a directory, named after its subject matter, i.e. "building_a_static_website". Under that directory and all the others, there will be an "index.html" file. There will also be an "images" subdirectory, containing all the images specific to that article.
A further design decisions that I took when considering the directory structure is that I haven't bothered to divide individual articles by further subdivisions such as year or even year/month, which is common in large, frequently updated websites. My expectation is that, as I maintain the website personally, I will not be making updates frequently enough for this to be worthwhile.
Project files and directory structure
Earlier, I mentioned that each subject area has a "projects" subdirectory, containing text files documenting important information about each of the articles being written. I wanted to explore this a little more, as this is an important part of how articles are written and maintained. In the workflow for creating a new article, creating an associated project file is the first step.
Taking the specific example of this blog post, we begin by creating a text file that has the same name as the directory that will contain the article and its associated files. In this case, that will be: "building_a_static_website.txt". The file then contains various commands and comments, the former which can then be cut and pasted into the terminal window being used for development. For example, some of the lines that we will have in the case of this blog post are:
export PROJ_DIR_NAME=building_a_static_website export PROJ_FULL_PATH=$SAXBYNET_HTML/blog/$PROJ_DIR_NAME export EDIT_IMAGES=$HOME/Development/www/saxbynet.com/images/blog/$PROJ_DIR_NAME mkdir -p $PROJ_FULL_PATH/images cd $PROJ_FULL_PATH
Once we have set up the environment and executed the commands, we will have created all of the necessary directories for us to actually begin writing the blog post itself.
Note that this is a text file, rather than a bash script or similar, because it contains all sorts of other commands that cannot just be executed all at once. There might be a better way of dealing with this, but I have found just using cut and paste to be the way forward for this specific circumstance. We will return to more details of what is contained in a typical project file as it becomes relevant.
As a recap, having gone through the previous sections, we end up with a directory structure that looks like the following:
├── blog │ ├── building_a_static_website │ │ └── images │ └── projects ├── icons ├── images └── stylesheets
With this basic directory structure in place, we can now turn to actually writing our first HTML pages.
How to write the basic HTML required for the website
Before we can actually write our first page, we should consider how to go about this. This is of course a potentially enormous subject area, but it is well outside the scope of this blog post to teach the basics of HTML itself. Hopefully, anyone reading this post will already realise that HTML is the absolute bedrock of how websites are created. A quick search turns up plenty of tutorials, for example: HTML Tutorial, HTML for Beginners the Easy Way and Structuring content with HTML — Learn web development. There are of course plenty of others, so head to those resources if that is needed.
Instead of that, assuming that the reader and myself are already know how to write HTML, what are some of the approaches that we might take to writing it and introducing how I decided to do it myself. It seems to me that there are roughly the following choices:
- Using some kind of text editor to directly write HTML.
- Using some kind of GUI editor that outputs HTML.
- Generating HTML from popular text based formats such as Markdown or AsciiDoc.
- Something else…
Well, I suppose that something else could be the latest generation of HTML AI generators, which along with generative AI in general, appears likely to continue revolutionising coding in general, but right now, I don't want anything to do with that dark wizardry, preferring to understand what I'm doing.
Using a text editor. There are certainly good reasons why writing HTML directly in a text editor might be a good idea. The main one in my opinion would be the absolute level of control that you get: you can decide exactly what HTML should be included, what tags and so on and, well everything. That's exactly what I did back in the day. The flipside is of course that you are also responsible for writing everything and although many modern code editors can help out with providing everything from templates to making sure your tags are closed properly, writing HTML by hand can be really hard, even if the underlying HTML itself is not particularly difficult to learn. I personally found it very awkward even back when I wrote programs in C. These days, I really do not want to do that and for various reasons, I find it difficult to type. I mean, who wants to type all those awkward angle brackets, constantly pressing and releasing the shift key!
Using a GUI HTML editor. I have in the past and still do use Seamonkey as a GUI HTML composer and editor. I also often use the Seamonkey browser component to view the webpages I am developing. The HTML composer/editor is a functional if fairly basic application, that can nonetheless be used for building webpages. There are also a long list of other editors available, with varying degrees of capability. Note the personally, I have not used any of the other applications that are out there, so I'm not in a position to comment on their efficacy. However, I only use something like Seamonkey for creating ad hoc webpages, or were it proves to be really really handy to have a GUI style editor for an occasional purpose. For the specific case of building this website, I'm not using that or any other current HTML editor.
Generating HTML from text based formats such as Markdown or AsciiDoc. There is much to be said the using something like this and I'm sure that many people do exactly that. Markdown support is particularly prevalent in many editors and notetaking apps, so a lot of people know the basic syntax and it is of course designed to closely match the way people used to format strictly text based things like emails, in order to show formatting, using various ASCII characters. AsciiDoc is similar. Personally, I do like the concept, because the type of website that I am developing contains a lot of basic text, with the usual headings and so on, which is something that works very well with this type of approach. I might well have used one of these approaches if I didn't have reasons to go in a slightly different direction.
Something else. Perhaps it will come as no surprise that I use a "something else" approach, which I will briefly describe here, starting with the background.
As I mentioned towards the start of this blog post, I used to write technical design documentation for my former employer and that was written in HTML. At first, I wrote that HTML directly in vim/vi. Later, I got to the point of setting up various macros that allowed me to easily enter things like starting and ending paragraph tags and so on. However, this was still a real pain and I began to think that surely it wouldn't be too difficult to write what I wanted in a text file and use a sed script to convert basic markup into HTML, so that's exactly what I did. At this point, I didn't even know that something like Markdown or AsciiDoc existed, so I started doing it my way and eventually decided to call it "Dragon Documentation Format". That is what I continue to use today and will be using for this static website development. I will go into some more detail on this at another time, but the important thing to remember is that I write text based files and use scripts to generate HTML.
Despite the basic concept being exactly the same as Markdown or AsciiDoc, I am continuing to use my own format, because I understand it completely and I have total flexibility to support anything I need to and some of that may become apparent as we go through this blog post series.
What is the minimum CSS that we should start with
I suppose one answer to this question is "nothing". After all, HTML can stand on its own and every device or browser has its own basic styles. However, it would be an unusual website that doesn't have any CSS and as I intend to explore this, I feel as though it is worth beginning with at least the most basic stylesheet and then as we go along, that can be expanded as necessary.
Certainly, one set of styles that appears to be worth setting is for the relative size of headings. That is because, because I am using the basics of HTML Semantic Elements, the relative size of headings can be affected by how those headings are nested within such semantic markup. Without appropriate CSS, that can leave heading sizes looking odd. Note that "Default styles for h1 elements are changing", which if I understand correctly will remedy this, but there are plenty of browsers out there that will not have this change yet.
With this in mind, I am including a stylesheet that includes the following:
body { background-color: white; color: black; font-size: 100%; } h1 { font-size: 2rem; } h2 { font-size: 1.6rem; } h3 { font-size: 1.4rem; }
Authoring the first HTML page that makes up this blog post
Having gone through the list of decisions about how the basic website is designed and having reached the point where we can meaningfully write our first HTML page and be able to publish it, there are some further things to bear in mind before being able to bring this first blog post to a close.
First of all, as I have explained already, I have my own text based format to allow the generation of HTML pages and the reader can view the source code for this blog post. It is just a straightforward text file without any special file extension. Note that those very long lines are entirely deliberate, but I will come back to that at another time.
In terms of the HTML, it is very straightforward, but it might be worth pointing out a few things, particularly from the beginning of the document, which currently is:
<!DOCTYPE html> <html lang=en> <head> <meta charset="UTF-8"/> <title>Building a static website (part 1)</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/> <link rel="STYLESHEET" href="building_a_static_website_01.css" type="text/css" title=screen media="all"> </head>
One thing I will point out directly at the moment is that, although normally you would expect the stylesheet to be taken from the "stylesheets" directory under the HTML root, for the purposes of these blog posts, I am using a stylesheet in the current directory, named to coincide with the blog post source text file name, but with the appropriate extension. That is so I can demonstrate how the look of the generated HTML changes as we build up the CSS.
When the generated HTML is uploaded to the web server, the precise way it appears depends on the specific device or browser that is used, as we have largely left everything so it will be rendered with the user's default, which would generally be a browser default CSS.
That is it for the moment. Look out for the next instalment of this series soon.
Note: the second part of this series: Building a static website (part 2: Introduction to images) is now available.