Creating a simple blog with Nextra and Next.js

This project is the very website you're on! It's a super simplistic website currently, with very little differentiating it from a generic blog, but as of writing all of the technical design is done and style and polish will be arriving later.

Infrastructure

The website is statically generated using a Next.js (opens in a new tab) tool which uses MDX (opens in a new tab), a markdown extension that allows for embedding React components, to generate static HTML. This allows for a very simple and straightforward way to write blog posts, and also allows for a lot of flexibility in the future. Every page on the site is simply described in a markdown file, and the site is generated from that.

The generator is called Nextra (opens in a new tab), which acts as a Next.js theme. It's very quick to install and get started with, though it's still very obviously new and has a lot of rough edges. It's also not very well documented, so I've had to do a lot of digging through the source code to figure out how to do things. I'm sure that it will only get better in the future though, and either way it's a great and easy way to get started with a Next.js site.

The site is hosted on Vercel (opens in a new tab), which is a hosting service that is free for open source projects. It's also very easy to use, it only took me a couple of minutes to set it up and direct my domain to it.

Vercel also allows me to easily edit the website remotely, as I only need access to a git repository maintained on GitHub. I can make changes to the website from anywhere, and they will be automatically deployed to the live site within seconds.

That's however not necessary, as ultimately all Vercel does is render the website and host it. I could just as easily host the website on my own server, or even just render it locally and host it on a static file server. Vercel does make it quite convenient and it's free! It even provides little URLs if you don't own a domain, but I do own one so I'm using that.

As this is both a super user-friendly setup and that it can be hosted for free, why not include a tutorial!

Tutorial

Pre-requisites

Getting started

If you're going to use Vercel (opens in a new tab), you can just click the button below to get started. It will allow you to create a GitHub repository with the "blog" template

Deploy with Vercel (opens in a new tab)

If you're not using Vercel, just create a new repository on GitHub and clone it locally. Then, run the following commands:

npx create-next-app --example blog-starter blog
cd blog
npm install

Now that you have all the dependencies, you're like halfway there! Your project directory will now contain a pages directory, which contains the top level pages of your directory. Those will automatically be added to the top bar of every page. In that directory, you'll also find a posts directory, which contains all of the blog posts. You can add more pages to the top bar by adding more files to the pages directory, and you can add more blog posts by adding more files to the posts directory.

You can also find a couple of .mdx files in those directories, they can be used as templates for your own posts and pages. In case you deleted them though, have this simple header for a blog post:

---
title: This very website
date: 2022-11-22
tags: javascript, webdev, ongoing
---

And here is the default index.mdx file:

---
type: page
title: About
date: 2022-11-21
---

For more customisation, you should check out the theme.config.js file. It contains a lot of configuration options for the site, and you can change the theme, add a custom logo, and more. A couple ones I recommend are:

export default {
  titleSuffix: ' - Your Website Name', // A suffix applied to your page title
  darkMode: true, // Whether or not your user can enable dark mode, do note that the user preference is stored in a cookie, you might want to include a cookie disclaimer!
  footer: (
    <footer>
      <small>
        Social links: <br />
        /* ... */
      </small>
      <br />
      <small>
        <time>{YEAR}</time> © Your Name
        <a href="/feed.xml">RSS</a>
      </small>
      <style jsx>{`
        footer {
          margin-top: 8rem;
        }
        a {
          float: right;
        }
      `}</style>
    </footer>
  ),
}
 

Did I mention that this template comes with RSS support? It does! You can find the RSS feed at /feed.xml, and you can add it to your favourite RSS reader.

You can also upload custom files directly in the public directory, and they will be available at the root of the website. With this you can host images, fonts and custom css to use on the site.

Finally, you can add some custom error pages to help make your website look more professional. Nextra comes in handy once again, you can just create a 404.mdx file in the pages directory, and it will automatically be used as the 404 page. You can also create a 500.mdx file, which will be used as the 500 page.

You do have to set their type to tag though, to avoid them being treated as blog posts or navigation pages:

---
type: tag
title: 404 - Page not found
---

And remember, you can test your website locally by running npm run dev in the project directory! It even auto-refreshes when you edit a file, allowing for a live preview of your changes.

Deploying

If you're using Vercel (opens in a new tab), you can just push your changes to the GitHub repository you created earlier, and Vercel will automatically deploy the website for you. You can also connect your domain to the website, and it will automatically be configured for you.

If you want to use something else, these commands will build the website and put it in the out directory:

npm run build
npm run export

You can then host the website on any static file server, including something free like GitHub Pages.

If you also want to automatically deploy your website, I would use a simple bash script that runs the above commands and then copies the out folder to a target remote server:

#!/bin/bash
 
npm run build
npm run export
 
rsync -avz --delete out/ user@host:/path/to/remote/folder

Though rsync directly is usually a little dirty, you can certainly figure out a cleaner solution for your specific scenario. For instance, you could use a git repository on the remote server and push to it instead of using rsync.

Conclusion

So that's for Nextra! I'm quite frankly impressed with the framework, it's incredibly easy to use and very lightweight. You can set it up in minutes and have a perfectly usable and might I say user friendly website. It's far from perfect though, and its developpers do not consider it to be production ready. Either way, I'd recommend you give it a go! It's a solid way to build a quick and clean website with little effort and programming knowledge, while still being entirely free and open-source.