This is my personal website, oliverjam.es. It's where I experiment with some fun stuff and write blog posts. It is almost certainly over-engineered for the task of turning Markdown into HTML.
If you'd like to run a copy of my site for yourself for some reason...
cd
into the directorynpm install
to install all dependenciesnpm run dev
to start the dev serverThe website itself is a collection of static HTML, CSS and JS files. There's no server or anything dynamic. These files are generated at build time by Eleventy, a static site generator. If you haven't encountered it before Tatiana Mac has a fantastic intro to Eleventy (and static site generators in general).
Eleventy turns any templates in src/
into HTML pages. This includes all the markdown files in the src/blog/
directory. If you have built the site you can check the _site/
directory to see the final structure.
The site is hosted on Netlify. Every time I push to GitHub Netlify automatically rebuilds all the pages and redeploys.
I also have a GitHub Action (configured in .github/workflows/main.yml
) that automatically deploys the site every night (at midnight). This ensures everything is reasonably up-to-date (and doesn't cost anything since Eleventy is so fast I'm nowhere near my monthly allowance of free build minutes on Netlify).
Whilst Eleventy supports a whole bunch of nice templating languages out of the box, I decided to make things hard for myself by writing a custom Svelte extension. This allows me to write my pages as Svelte components, complete with scoped CSS in the same file. This also allows me to abstract reusable components into src/_includes/components/
You can see the code for the custom extension in config/plugin-svelte/
. The general idea is that when Eleventy encounters a .svelte
file it defers to this plugin to generate the HTML for the page. The plugin require
s the Svelte component, runs it, then returns the resulting HTML and CSS.
I currently don't have a way to "hydrate" Svelte pages so their JS runs client-side too. This means if I need client-side JS I have to manually include a script tag.
In order to get nice image previews when my posts are linked on social media sites I need to include OpenGraph images. I have a couple of horribly hacky scripts in the sh/
directory for this. sh/screenshots.js
takes a URL and uses Puppeteer (a "headless" Chrome browser) to open the page, delete everything but the big title, then take a screenshot. sh/generateOG.js
loops through all the blog posts and takes a screenshot of each, saving them in src/assets/media/og-image/
. Currently I have to remember to run this manually whenever I write a new post (which isn't that often).
I could not justify invading my visitors' privacy with something as heavy as Google Analytics, so I built my own very rudimentary analytics. I pretty much never look at the data, but it's nice to know it's there. You can read more about how it works in the (surprisingly popular) analytics blog post.