This blog is now built with Gatsby, a free and open source static-site generator powered by React and GraphQL. Gatsby provides a framework for building modern, performant, production-ready websites that can be hosted anywhere as static files, with no need for a database or backend server.
Static-site generators are popular for this reason, because they don’t need a backend server, so they are faster and require less maintenance than a website that needs its own database to generate pages server-side for clients. There are quite a few static-site generators out there. This blog was previously built with Jekyll, and I do still appreciate its philosophy, as it simply “does what you tell it to do — no more, no less.”
After overcoming a bit of a learning curve, I had a lot of fun getting started with Gatsby. I began with the
gatsby-starter-blog and borrowed some code from
overreacted.io to handle theming. I then made a new
Navbar using React Hooks and included some new styling.
I did run into an issue while migrating my blog posts from Jekyll. I was using
script tags in the markdown for a blog post, because it worked with Jekyll in order to include a d3.js chart. Gatsby wasn’t allowing the scripts to execute, so I modified the
BlogPostTemplate component to allow injecting scripts specified in the
componentDidMount injects the scripts specified in the frontmatter, after checking that it is an allowed script (otherwise it could just inject any script, so this would be important, e.g., if an attacker was somehow able to modify the json which specifies the scripts to be loaded).
script.async = false makes the browser execute the scripts in the order they are injected into the DOM. The chart in
GDP.js depends on
d3.min.js so they must be executed in order.
It doesn’t make sense to bundle them when they are only needed for one blog post, so this code lazy-loads the scripts as necessary.2 Gatsby can also handle code splitting, but I found the way described above to be effective in this particular use case.
Of course, security measures like this on the frontend client can only do so much, since the browser’s environment can be affected by any number of unknown factors, but it seems that if one is going to create an opening into their code, they should also make sure to secure it.