Skip to content

fracture91/ahurle-dev

Repository files navigation

ahurle-dev

Powers the ahurle.dev website and developer blog. Heavily modified fork of Devii.

I wrote a blog post about this project if you want some more context on why it exists.

Feel free to fork this repo for your own website! I know how annoying it is to get everything working nicely if you were to start from scratch instead. All I ask is that you style it a little differently - make it "yours". And remove my blog posts and stuff, of course. It would also be nice if you linked back to me, but it's all MIT licensed so... 🤷‍♂️

Features

  • Modern Next.js, React, TypeScript stack
  • Author blog posts and other pages in MDX, export "front matter" as a JS object validated by zod
  • Syntax highlighting for code blocks in your blog posts
  • Dark mode support with theme-ui
  • All pages get automatic smoke tests from next-page-tester
  • All pages use static generation and the site functions with client-side JS disabled
  • Effortless image optimization with next/image
  • Free analytics from GoatCounter
  • Free hosting from Vercel
  • Free client-side exception reporting from Sentry
  • ESLint, Prettier, Jest, and a CI config for Github Actions - Free!
  • Newsletter signup with TinyLetter
  • Excerpt, Table of Contents, and Reading Time get extracted from each blog post
  • SEO, a11y, RSS, sitemap, page speed are all in pretty good shape

Getting started

  • Install nvm and yarn (perhaps yvm too).
  • Clone/fork this repo and cd into it
nvm use  # see .nvmrc
yarn install
yarn dev

You should now see my site running on http://localhost:3000

M1 Mac Special Instructions

I ran this on node 14.x for a while without problems. At some point it started exploding on yarn install. I was able to get around it like so:

nvm install v15.11.0
nvm use v15.*
vim package.json # change engines -> node to "15.x"

Note that vercel does not support node 15.x or higher yet. It will probably also work if you use Rosetta for Node 14 rather than trying to compile it natively for arm64.


CLI

  • yarn dev - Starts the development server. Equivalent to next dev.
  • yarn build - Creates an optimized, production build of your site. Equivalent to next build. Use yarn start to run this build locally.
  • ANALYZE=true yarn build - Also opens webpack-bundle-analyzer output in your browser
  • yarn export - Exports your site to static files. Equivalent to next export.
  • yarn lint - Run eslint and prettier checks. Use yarn lint:eslint or yarn lint:prettier for specific checks
  • yarn test - Run tests

Creating Your Own Website As a Fork

There are a few basic things you'll want to change right away to make it "your" site:

The constants in this file are pretty self-explanatory. Change the name to match your name, the domain to match yours, etc.

I got lazy here and duplicated some config from globals.ts - change the URL to match your prodUrl, and add any exclusions for e.g. unpublished blog posts.

GoatCounter

If you want to use GoatCounter for site analytics, sign up for an account and replace goatCounterId with your own. If you don't want to use it, you can set goatCounterId to null.

GoatCounterScript and GoatCounterPixel contain some hardcoded checks to make sure you don't accidentally dump your data into my account in case you haven't read these instructions yet. Changing/Removing these is left as an exercise for the reader.

By default, analytics are only enabled in the prod environment, but you can test in dev by commenting out the prod checks.

Sentry

You can use Sentry to catch unhandled exceptions on the client side of your app. Sign up for an account and replace sentryPublicKey and sentryDsn with your own. If you don't want to use it, you can set either constant to null.

Like with GoatCounterPixel, there are some hardcoded checks in SentryLoader that you might want to remove.

By default, sentry only runs in prod and preview mode, but it can run in dev by commenting out the checks. Try calling window.onerror("hello world") to make Sentry log an error.

TinyLetter

The site contains newsletter signup forms thanks to TinyLetter. Sign up for an account and replace tinyLetterUsername with your own, or set it to null to disable the forms.

Snapshots

Once you've changed all this stuff, run yarn test. You'll probably have a bunch of failing snapshots that used to contain my globals. Press u to update the snapshots to contain your globals. Making sure yarn lint still passes is also a good idea.

Github Actions

This project contains a CI config that should run whenever you open/update a PR or push to master. It's a good idea to make sure that's passing now. Here's some documentation to get you started.

You may also need to do some separate setup for the specific actions I'm using - especially bundlewatch - but I don't remember the specifics 🤷‍♂️

Vercel

The easiest way to deploy this app is through Vercel. Sign up for an account and you can have it deploy your repo with a few clicks. You should be able to visit your site at a *.vercel.app domain for now, and later you can point a domain at it like ahurle.dev. Remember to change prodUrl in globals.ts if your domain changes.

If you want to use something else then it's probably not very difficult to switch. Note that I depend on some VERCEL_* environment variables, and next/image requires a server to transform image URLs.

Assets

  • me.jpg: Change this to be an image of you, or delete it if you don't want one
  • favicon.ico, logo.png, and logo.svg: This is the favicon for your site. You'll want to replace these with images of your own creation.
  • The rest of the non-SVG files in /public can probably be deleted

Content

Most of the text on the site lives in /pages. If you aren't familiar with the concept of pages in Next.js, I recommend reading the docs. You will probably also want to change the Footer and Header.

Have fun!

The rest is up to you!


License

Most code © 2021 Andrew Hurle, MIT License

Based on Devii, © 2020 Colin McDonnell, MIT License

imageSizeLoader.js based on image-size-loader, © 2015 Patrick Collins and Boopathi Rajaa, Apache License 2.0

mdxDefaultLayout.js based on a file from silvenon.com, © 2020 Matija Marohnić matija.marohnic@gmail.com (silvenon.com), MIT License

mdxImageMetadata.js based on a file from kylepfromer.com, © 2019 Kyle Pfromer, MIT License

prismStyle.ts based on the darcula theme from react-syntax-highlighter, © 2019 Conor Hastings, MIT License