Celebrating Site Launch

Published: December 29, 2022

It’s alive 🥳

Finally decided to redo my site, as the last time it was made was my junior year of high school 😬

Random Detour

When I was looking at my old site version from 2017 I noticed that I had a massive security vulnerability, allowing RCE.

if ($type == "bot") {
  $call = "~/www/reteps.tk/go/kahoot-auto " . $_GET['gamepin'] . " " . $_GET['username'] . " ";
  echo($call);
  ob_flush();
}
I’m an idiot

Anyways, I decided to try Svelte for making it, how hard can learning an entirely new web framework for my site be, ya know? Well Svelte + TailwindCSS was amazing, and I will share just a little bit of details about how it was made.

Development Process

First, I created a draft of my site in Figma. The Lo-fi Wireframe Kit helped me prototype extremely quickly.

My site’s Figma

Firstly, I setup a barebones blog using this great guide Build a static Markdown blog from scratch. Then I setup a Github Actions pipeline to deploy it statically onto GH Pages, using a great Github Action by @AndrewLester.

For the blog, I ended up using the Github Colors theme for code, plus some plugins to hyperlink headers, add LaTeX support, and add direct HTML attribute setting.

I was able to get this up and running fairly quickly, only ~2 days of coding. My most annoying bug was the blog posts themselves having a width larger than the screen width, which I fixed with prose-a:break-words prose-code:break-words + overriding the width, which wasn’t too bad (it took me 4 hours):

  .prose {
    max-width: min(100vw, 65ch);
  }

Switching from medium

Since mediumexporter wasn’t working for me, and it looks like an extremely recent break, I used medium-to-hugo with a small patch to download my medium posts and convert them to markdown.

Time Machine

I added a basic time machine feature hidden in the footer of my site. I embed my old sites as iframes, and dynamically fetch all directories with a small function:

export const fetchTimeMachineYears = () => {
  const snapshots = import.meta.glob("../../../static/20[0-9][0-9]/index.html");
  const years = Object.keys(snapshots).map((path) => path.match(/20[0-9][0-9]/)![0])
  // sort years
  years.sort((a, b) => parseInt(a) - parseInt(b))
  return years
}
Glob all past years, and sort.

You can check it out here. I also added a draggable header so that it doesn’t block your view.

SEO

I wrote a small snippet of code to pull out text from my blog posts and use it as the description in SEO.

const remarkInferDescriptionMeta = () => (
  (tree, file) => {
    let description = ''
    visit(tree, 'paragraph', (node) => {
      if (description.length > 160) return
      description += toString(node) + ' '
    })

    description = description.slice(0, 160) + '...'

    file.data.fm.description = description
  }
)
Full Source here

I am using Svelte Sitemap and pushing updates to the Google Search Console with a Github Action.

Optimizations

I used vite-imagetools to optimize my images. I also added an aria-label to every link based on the text content of the tag:

<script>
  export let href
  let self
  $: ariaLabel = $$restProps['aria-label'] || self?.innerText || href
  // ...
</script>
<a href={href} bind:this={self} aria-label={ariaLabel} {...$$restProps}>

This lets me get super snappy loadtimes, and a >90 lighthouse score! ## Future Improvements

This section may just ~disappear~ but I still need to:

  • Add a bunch more styling for my blog
  • Add some cool theme / flavor to the site
  • Fill in more content on the showcase
  • Get a job
  • Stop going to bed at 3am
  • Predicting other people reading too closely into my random blog posts

Let's stay in touch.

/ © 2024 Pete Stenger /
Source