All Posts

Migrating to Cloudflare R2

A quick update: all images and videos on this blog are now sitting on a Cloudflare R2 bucket!

For the past four years, those files were directly added to git and bundled along with the text contents in a Github action build before being deployed to Github pages. I know you weren’t supposed to add non-text files to git, but I didn’t want to think about that back then. When I started the blog, I wanted to write and didn’t care where things were supposed to go. This system worked fine till recently when I tried to add a 400MB video of Thom Yorke’s beautiful singing:

git add takes 10s to run on 400MB file git push takes a minute then get rejected with this message

Turns out Github has a file limit of 100MB!

I gave Git LFS a whirl a few days ago, but then Github sent me this email:

So I finally bit the bullet and migrated to Cloudflare R2, which gives you 10GB for free. I thought this was going to be hard to set up, so I’ve been putting it off for years, but it turns out to be quite simple.

I won’t get into the details of how I did it, but the rough steps that I took were:

  1. Set up a public R2 bucket.
  2. Change my domain name server to Cloudflare so I can use my subdomain for the bucket.
  3. Upload all my images and videos to the bucket.
  4. Write a Hexo plugin to modify the images and videos URL to use my bucket URL.

That’s about it.

// append asset_external_host to assets
hexo.extend.filter.register("after_post_render", function (data) {
  const getAssetURL = (src) => {
    const externalHost = this.config.asset_external_host;
    return externalHost
      ? new URL(`${data.path}${src}`, externalHost).toString()
      : src;
  };

  // IMG
  data.content = data.content.replace(
    /<img[^>]* src=\"([^\"]*)\"[^>]*>/g,
    (_, src) => {
      return `<img src="${getAssetURL(src)}" />`;
    },
  );

  // SOURCE (VIDEO)
  data.content = data.content.replace(
    /<source[^>]* src=\"([^\"]*)\"[^>]*>/g,
    (_, src) => {
      return `<source src="${getAssetURL(src)}" />`;
    },
  );

  return data;
});

^my hexo plugin for appending a custom bucket link to image & video src

Other posts

2026-01-03
I built a public transportation map

I was on holiday with too much free time on my hand and Claude AI had just doubled its usage limits for 7 days.

2024-05-22
Programmer's Block

Oh hey, I didn't know you're still here reading my blog. It's been half a year without any post I know. I've been busy....doing nothing.

2023-12-05
What is border-radius, really?

Have you ever thought, what does 18px or 50% really mean when they get passed to border-radius property?

2023-11-09
Rust Koan: Những Chướng Ngại

Dịch lại một đoạn koan về rust trong lúc cao hứng.

2022-07-11
std::mem::transmute the unsafe magic

Using mem::transmute for struct inheritance in Rust