logo
Published on

Revamping this site into a Next.js site

Authors
  • avatar
    Name
    Mae
    Twitter

Intro

Using Next.js and Github Actions I've once again revamped this website to better fit my needs. The existing Drupal site was more than I needed and having to constantly maintain it was a pain.

I was looking for static site generators and came across Next.js. After finding a suitable template I was able to convert my existing HTML blog pages that I wanted to keep into MDX format using Github Copilot. The only other component is Github Actions. Which builds the site, and automatically deploys it to my hosted webserver using rsync. This is a much simpler setup than the previous Drupal site and I'm happy with the results. The only challenge I have is automatic file management but I haven't found it to be too annoying.

Page Authorship

The full process for authoring another page is:

  1. Pull down my repository

  2. Add assets like images to the public directory

  3. Create a new MDX file in the data/blog directory

    The format, more or less, is a header similar to the below

    ---
    title: Revamping this site into a Next.js site
    date: '2025-01-05'
    tags: ['meta']
    draft: false
    images: []
    summary: 
    ---
    
  4. Push the changes to Github

  5. Github Actions builds the site statically. Including the search functionality.

  6. Github Actions connects to my server over SSH using a SSH Private/Public key and uploads the files efficiently.

Challenges

My hosting provider uses Apache compatible .htaccess file to control the behaviour. The output of next.js creates files with .html endings but I want it without the extension.

After a little work I found the following worked

# Redirect URLs without extensions to .html
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/?$ $1.html [L]

In order to maintain this file I also needed to add it to my repo. Then in the postbuild.mjs that copies it into the output directory.

  // Copy .htaccess file to the root directory
  const htaccessSrc = path.join(process.cwd(), '.htaccess')
  const htaccessDest = path.join(outputFolder, '.htaccess')
  await fs.copyFile(htaccessSrc, htaccessDest)

Also I added the following SSH steps to the default action instead of the Github Pages example that came with the template:

name: Deploy to my site

on:
  push:
    branches: main

[...]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      # Checkout code
      - uses: actions/checkout@v4

[...]

      # Set up SSH
      - name: Set up SSH
        uses: webfactory/ssh-agent@v0.9
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

        # Copy the known_hosts file from the repository to ~/.ssh/known_hosts
      - name: Copy known_hosts file
        run: |
          mkdir -p ~/.ssh
          cp ./known_hosts ~/.ssh/known_hosts
          chmod 644 ~/.ssh/known_hosts

      # Sync files to remote server using rsync
      - name: Sync files to server
        run: |
          rsync -avz -e 'ssh -p <port>' --delete --exclude='.well-known' ./out/ <user>@<host>:/home/<user>/public_html/

Future Work

I plan to add to my project page to demonstrate some of my work. I'd also like to customize the template, including styles. However, these days minimalism is popular.