About Me / This Site🔗
Table of Contents🔗
- About Me / This Site
- RSS Feed
- Mozilla Observatory score (i.e. Security)
- Google PageSpeed score (i.e. Performance)
This site taxes advantage of a lot of Cloudflare's offerings. They are mostly of very high quality, with famously generous free tiers. At a minimum I'm using Cloudflare's DNS, CDN, Pages, Workers, Firewall, and I hope to use their recently announced Email Forwarding feature soon.
Lately, I've preferred to architect my projects (not just this site) using these products, because they're designed in a way that's very loosely coupled. This makes it easy to start off with only what you need to begin rapidly prototyping at first, but allows you to integrate more things later. Also, their documentation is very good, and best of all their forum is fantastic.
Each part will be discussed more in-depth later, but here's a visual summary tracing the request flow:
- Initial request either: a.) Hits DNS AND/OR b.) Goes directly to WAF (i.e firewall)
- Rules are applied in firewall, before passing request to Worker (i.e. serverless)
- Based on
METHOD, worker either a.) Sends request to some backend (e.g. Airtable) OR b.) Fetches the page from Pages, where the static site is hosted.
- Finally, security headers are set on response by the worker, before making it back to client
Requests to my site first hit DNS. In general, knowing a little about DNS is very useful, because you can elegantly route traffic without having to touch the code to your app. For example, I can have https://staging.spenc.es for testing parts of my app, as well as https://spenc.es for what most of the public sees.
One word of caution:
When using Cloudflare DNS +
<SERVICE>, sometimes you will need to set the DNS records through that service. E.g. if you have an website through Cloudflare Pages, and you want to make it accessible on the
wwwsubdomain as well, you might think, "Great, I'll just add a
AAAA) record pointing at the same server that my top-level domain is already pointing at. This will work in a DNS sense... the record will resolve to a valid IP, but your connection will just time out. This is because the integration wasn't setup through the service.
To make an analogy, the phone is ringing, but no one's answering.
wwwis a valid phone number (in our analogy), but the service has not been told it should be taking calls at that number, so it doesn't answer and the request times out.
The next major layer in my architecture is the WAF (web application firewall). Here I can set up filters that apply certain rules, like adding a captcha when someone submits a
POST to my recruiting form. This can help protect certain endpoints without you having to actually introduce any new code in your application.
Workers are Cloudflare's "serverless" offering. Basically, it's a function that you write, according to a simple API, instead of a server that you maintain.
For my personal site, I currently use workers for two things:
- Setting security headers
- Handling form submissions for my recruiting form
A lot of static sites will use something like GitHub pages, but they don't offer a lot of control over one of the main abstractions provided to you in HTTP, which are headers.
The logic I use looks something like this:
- Worker receives request
- Checks Path/Method
GET, fetch content from static page
POST, extract form data, etc...
- Set Headers and return response
You can read more about what headers I use here.
Word of caution
Also, I think a lot of their documentation/examples are not coded in a very realistic way. They're done to communicate the bare essentials of whatever message they need to at that point. I wouldn't however confuse an example you see in the documentation as the canonical way to do something, just because it's there.
This is really just like GitHub pages or anything else that most people are familiar with. It's a service that builds your static page and hosts it. It gets triggered by a push to a GitHub repo, and it supports quite a number of frameworks.
Using Tailwind CSS with Zola🔗
Tailwind use PostCSS to integrate with a build system, which Zola doesn't support since it's a a single binary with not plugin system. The maintainer recommends a makefile, which is more or less what I do, except I use
npm, since I have tailwind as a node dependency anyway.
To make the two work with each other, I run tailwind's standalone build command after Zola's, putting the resulting css in Zola's build output directory (usually
public/). This has worked surprisingly well and I haven't had any issues. Although I have a custom
npm build script that I use for convenience, my build/run command(s) are more or less the following:
Where usually I'm watching my main
tailwind.css file, as well as
--interface 0.0.0.0 is used so I can test my site on my local machine with my actual mobile device.
Testing Mobile From My Local Machine🔗
(i.e. 📱 → 💻)
It's important to test on an actual mobile device. For this, I run squidman on my laptop, and then configure a proxy in my phone's network settings.
- Start squidman, take note of squidman's port and laptop's IP
- Configure proxy on phone, using laptop's IP + squidman's port from previous step
- Navigate to website using laptop's IP + port that my server is running on