How to Make a Damn Website

March 25, 2024

A lot of people want to make a website but don’t know where to start or they get stuck. That’s in part because our perception of what websites should be has changed so dramatically over the last 20 years.


The “Hard” Way

It’s easy to forget how simple a website can be. A website can be just one page. It doesn’t even need CSS. You don’t need a content management system like Wordpress. All you have to do is write some HTML and drag that file to a server over FTP.

For years now, people have tried to convince us that this is the “hard” way of making a website, but in reality, it may be the easiest.

It doesn’t have to be super complicated. However, with this post, I will assume you’ve written at least some HTML and CSS before, and that you know how to upload files to a server. If you’ve never done these things, it may seem like I’m skipping over some things. I am.


Baby’s First HTML

Let me begin with what I think you shouldn’t start with. Don’t shop around for a CMS. Don’t even design or outline your website. Don’t buy a domain or hosting yet. Don’t set up a GitHub repository; I don’t care how fast you can make one.

Instead, just write your first blog post. The very first thing I did was open TextEdit and write my first post with HTML, ye olde way. Not with Markdown. Not with Nova or BBEdit or another code editor. Just TextEdit (in plain text). Try it, even if just this once. It’s kinda refreshing. You can go back to using a code editor later.

Here’s what a draft of this blog post looks like:

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>How to Make a Damn Website</title>
	</head>
	<body>

		<h1><a href="how-to-make-a-damn-website.html">How to Make a Damn Website</a></h1>
		<p>A lot of people want to make a website but don’t know where to start or they get stuck.</p>

	</body>
</html>

This is honestly all you need. It’s kind of charming.

Make sure you rely exclusively on HTML elements for your formatting. Your page should render clearly with raw HTML. Do not let yourself get distracted by writing CSS. Don’t even imagine the CSS you’ll use later. Don’t write in IDs or classes yet. Do yourself a favor and don’t make a single div element.

Just write the post in the plainest HTML. And don’t you dare write a “Hello World” post or a “Lorem Ipsum” post. Write an actual blog post. If you want, make it about why you’re making a website.

Writing this way helps you stay focused on writing for the web. The most important thing here is shipping something. You can (and should) update your site later. Now, name the HTML file something sensible, like the post name.

how-to-make-a-damn-website.html

Finished? Great. If you have a domain and hosting, make a new folder on your server called blog and upload your first post in there. Don’t worry about index pages yet. You have only one post, there’s not much to index. We’ll get there.

If you don’t have a domain or hosting yet, now’s the time to buckle down and do that. Unfortunately, I don’t have good advice for you here. Just know that it’s going to be stupid and tedious and bad and unfun. That’s just the way this is.

Try not to let it deter you. Once you have the ability to upload files to an FTP server, you’ve reached the “set it and forget it” phase.

Direct your web browser to the HTML file you uploaded. Wow! There it is. A real, actual page on the web! You shipped it. Congratulations. Times New Roman, black on white. Hyperlinks that are blue and underlined. Useful. Classic.

Look at your unstyled HTML page and appreciate it for what it is. Always remember, this is all a website has to be. Good websites can be reduced to this and still work.

A broken escalator is just stairs. Even if it’s a little less convenient, it remains functional. This is important.

If you get this far, I want you to know this is truly the hardest part. Some people will ignore what I’ve said. They will spend significant time designing a website, hunting around for a good CMS, doing a wide variety of busywork, neglecting the part where they write actual content for their site. But if you shipped a single blog post, you have a website, and they don’t.

A website is nothing without content. You can spend months preparing to make a website, tacking up what I’m sure was intended to be a “temporary” page telling people that you’re “working on a new website,” but it will inevitably become a permanent reminder that you haven’t done it yet. So focus on what matters, and ship one blog post. Do the rest later.


Really Simple Syndication

You may think CSS is the next logical step, or maybe an index page, but I don’t think so. It takes only a few minutes to hand-write an XML file, and once it’s done, people will be able to read your blog via an RSS reader.

On your site, you’re in control of publishing now. When you post to your blog, part of the process is syndicating it to those who want to stay updated. If you provide an RSS feed, people can follow it. If you don’t, they can’t.

While the best time to make an RSS feed was 20 years ago, the second best time is now.

It should be noted that most people who have an RSS feed are probably not making it manually, so you won’t find a lot of documentation out there for doing it this way. But it’s not too hard. And once you make a habit, it’ll be a totally reasonable component of your publishing flow.

Here’s what my XML file looks like (without any entries):

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>

		<title>LMNT</title>
		<link>https://lmnt.me/</link>
		<description>Louie Mantia’s weblog.</description>
		<language>en-us</language>
		<atom:link href="https://lmnt.me/feed.xml" rel="self" type="application/rss+xml" />

	</channel>
</rss>

The elements inside the channel element are for your feed as a whole (title, link, description, language, and atom:link). After the ones about your feed’s metadata, we can add a blog post to the XML file, which will look like this:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>LMNT</title>
		<link>https://lmnt.me/</link>
		<description>Louie Mantia’s weblog.</description>
		<language>en-us</language>
		<atom:link href="https://lmnt.me/feed.xml" rel="self" type="application/rss+xml" />

		<item>
			<title>How to Make a Damn Website</title>
			<pubDate>Mon, 25 Mar 2024 09:05:00 GMT</pubDate>
			<guid>https://lmnt.me/blog/how-to-make-a-damn-website.html</guid>
			<link>https://lmnt.me/blog/how-to-make-a-damn-website.html</link>
			<description><![CDATA[

				<h1><a href="how-to-make-a-damn-website.html">How to Make a Damn Website</a></h1>
				<p>A lot of people want to make a website but don’t know where to start or they get stuck.</p>

			]]></description>
		</item>

	</channel>
</rss>

The item element represents an entry, and goes inside the channel element as well. There are a few self-explanatory elements for the post metadata (title, pubDate, guid, and link), but the content inside the description element can be the same HTML from your actual post. Handy!

Writing your first post with HTML and understanding how it looks “unstyled” really works in your favor here, because RSS readers use their own stylesheets. How they render pages will not be too different from how a raw HTML page is rendered in your browser. If you make your own stylesheet too early, you may neglect how the raw HTML could be parsed in an RSS reader.

For the pubDate, you can use GMT time. Ask Siri what time it is in Reykjavik, and enter that. You can use your local time zone instead, but be sure it’s formatted correctly. Also, note that it needs to be 24-hour time.

If you have images or other media in your post, be sure to use the absolute URL to a resource rather than a relative one. Relative URLs are fine for content that only lives on your site, but when you syndicate via RSS, that content loads outside of your website. Absolute URLs are better for content inside your blog posts, especially in the XML.

Once you’ve got your first post in the XML file, upload it to the root folder of your website. If you don’t already have an RSS reader, get one. I recommend NetNewsWire. Go to the XML file in your browser, and it should automatically open in your RSS reader and let you subscribe.

There it is! Your blog post is on the web and now also available via RSS! You can share that link now.

Now would be a good time to reference your RSS feed in your HTML. You’ll want to do this on all pages going forward, too. It helps browsers and plugins detect that there’s an RSS feed for people to subscribe to.

<link rel="alternate" type="application/rss+xml" title="LMNT" href="https://lmnt.me/feed.xml" />

When you add a new item (a new blog post), put it above the previous one in your XML file. Keep in mind that your XML file will be updated periodically from devices that subscribe to it. RSS readers will be downloading this file when updating, so keep an eye on the file size. It probably won’t ever be that big, because it’s just text, but it’s customary to keep only a certain amount of recent entries in the XML file, or a certain time period. But there’s no rule here.

The guid should really be a unique string, and while a URL may be unique, it also may change. The “right” way would be to generate a unique string for each post, but there’s not a super user-friendly way of doing that, which might be the reason many people use the URL.

Changing the guid (unique identifier) for your posts will make an RSS reader think it’s a different entry, resulting in a post being marked “unread.” Now you’re thinking about the file structure of your website, aren’t you? It’s probably fine if you change your file structure once or twice (I did), but it might be worth updating your URL structure in a link element only for new posts, and redirecting old URLs to new ones with your .htaccess file.


Indexing…

Alright, we can make index pages now. This is going to be super easy, because you don’t have a lot to index yet.

At the root, you want a link to the blog directory, and at the blog directory, you want a link to your first post. Put titles on each page, maybe a link back to the home page from your blog index. If you want, write a little description of your site on the root index.

Keep using basic HTML! Titles can be h1, and descriptions can be p. Keep it simple.

Once you got those uploaded, you got three pages and an RSS feed. You’re doing great!


Developing Blogging Habits

I recommend writing a couple more posts next. Try using some HTML elements that you didn’t use in the first post, maybe an hr element. Fancy! ol and ul. Maybe some img, video, and audio elements.

In addition to being more posts for your blog, these will also help prioritize which elements need styling, providing you with a few sample pages to check while you write CSS.

Upload the posts as you write them, one after the next, adding them to your XML file. Don’t forget to update your index pages, too. Always check your links and your feed.


One Style at a Time

Before you get ahead of yourself with layout, I recommend first styling the basic HTML elements you already defined in your first few posts: h1, h2, h3, hr, p, strong, em, ol, ul. Define the body font and width, text sizes, and colors.

Like the rest of your site, stylesheets are mutable. Expect them to change with your website. Incremental updates are what makes this whole process work. Ship tiny updates to your CSS. You can upload your stylesheet in a second. Heck, work directly on the server if you want. I do that.


Then Keep Doing It

If you’ve done all this, then you’ve cleared the hurdle. Now you get to just keep doing the fun stuff. Write more blog posts. Make more web pages. It’s your website, you can make pages for anything you want. You can style them however you want. You can update people via RSS whenever you make something new.

Manually making a website like this may seem silly to engineers who would rather build or rely on systems that automate this stuff. But it doesn’t seem like there’s actually a whole lot that needs automation, does it?

A lot of modern solutions may not save time as much as they introduce complexity and reliance on more tools than you need. This whole process is not that complex.

It’s not doing this manually that’s hard.

The hard part is just shipping.

If you ❤ like this