DEV Community

TJ Fogarty
TJ Fogarty

Posted on • Originally published at tj.ie

2 2

A Signal in the Static (moving to a static site)

About a year ago I set out to rebuild my site, and being reared on PHP I opted to go for Craft CMS while it was in beta. I figured it'd be interesting to learn it while it was still in development, and maybe create my own plugins.

Haha. Jokes. I did not. I tried, though, but never really needed anything extra.

I was also using Laravel Forge to automatically deploy whenever I pushed any changes to the master branch. To this day it's still a nice approach, but there's a lot of moving parts. I have a repo, a server that needs to be looked after (like when I updated PHP and broke everything), a database that needs to be backed up, and a CMS with some plugins that need to be kept up to date. Granted, I could not have touched it after day 1 and it would still work just the same, but that's not me. If it ain't broke, go fix it.

That's where the allure of a static site generator comes in. As far as the site goes, everything is in one place. Content lives in Markdown files which makes things pretty portable. I landed on using Hugo after seeing some recommendations for it, and in about a day I had my entire site copied over, including CSS and JS. To copy the content I took advantage of the Element API plugin for Craft to get a JSON object of all my posts. The config file for the plugin looked like this:

<?php

use craft\elements\Entry;
use craft\helpers\UrlHelper;

return [
  'endpoints' => [
    'posts.json' => [
      'elementType' => Entry::class,
      'criteria' => ['section' => 'posts'],
      'transformer' => function(Entry $entry) {
        return [
          'title' => $entry->title,
          'url' => $entry->url,
          'date_published' => $entry->postDate->format(\DateTime::ATOM),
          'slug' => $entry->slug,
          'body' => $entry->postContent,
          'categories' => $entry->categories->all()
        ];
      },
    ]
  ]
];
Enter fullscreen mode Exit fullscreen mode

So when it hit https://my-site.com/posts.json it returned everything I needed. I saved this to a file to quickly generate markdown versions like so:

const posts = require('./data.json')
const fs = require('fs')

function buildCategory({ title }) {
  return `- ${title}`
}

function buildFrontMatter(post) {
  return `---
title: "${post.title.replace(/"/g, '\'')}"
date: ${post.date_published}
draft: false
categories: \n${post.categories.map(buildCategory).join(`\n`)}
---`
}

posts.data.forEach(post => {
  let content = `${buildFrontMatter(post)}\n${post.body}`

  fs.writeFile(`../path/to/final/content/posts/${post.slug}.md`, content, err => {
    if(err) {
      return console.log(err);
    }

    console.log("The file was saved!");
  }); 
})
Enter fullscreen mode Exit fullscreen mode

I needed to run sudo node index.js on that as it needed to create files, but I didn't have to touch the generated markdown files once they were in the right folder.

Once that was done, I skipped on over to Netlify and hooked it up. I needed to do some configuration before everything would work. Mainly this was down to my assets living in a theme which was in a subfolder. To let Netlify know about it, I had to create a new package.json in the root with a build command that did the following:

[build]
publish = "public"
command = "hugo --minify && npm run build"
Enter fullscreen mode Exit fullscreen mode

Then the build command in my root package.json dug into the folder it needed and ran some more commands:

"scripts": {
  "build": "cd ./themes/nua && npm install && npm run production"
}
Enter fullscreen mode Exit fullscreen mode

After that, it was smooth sailing. Limerick just won the All-Ireland senior hurling final so I'm gonna grab a beer. That makes two victories today. Cheers, agus Luimneach Abú!!!

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more