A brand new weblog for 2024 | Chris Nicholas

It’s been a very long time since I’ve printed a weblog put up, two complete years. A part of the reason being that it took an excessive amount of effort to create posts for my earlier weblog. I wanted higher DX. A couple of nights in the past, feeling impressed after studying articles by Pedro Duarte, Rauno Freiberg, and Lee Robinson, I made a decision it was time to begin over.
So right here’s the rating—I desire a weblog with nice DX that makes it as simple as attainable to create posts. I additionally need to go minimal, so I can get away with a single design on cell and desktop. No faffing round; I need this weblog constructed and printed in 5 days! And lastly, I’m seeking to attempt some new libraries and applied sciences. Proper, let’s dive in.
At work I spend most of my time writing and programming, so dipping my toes into design was a pleasant change. Right here’s a few particulars.
For the header, I used to be aiming for an animated background that mixed an aurora, gentle beams, and a rainbow. I’m fairly happy with the end result, and it is really pure CSS—attempt altering hue-rotate
under to emulate the animation.
.aurora {
filter: hue-rotate(0deg) saturate(7.0) blur(30px);
}
Saturated text
All textual content that overlays the aurora is saturated with its underlying colors—a tiny contact that actually unifies the design. You are able to do this by merely making use of a luminosity
blend mode to the textual content.
My title’s Chris Nicholas
Noise
I’m making use of a tiny quantity of movie grain to the physique
. To me, this makes the web page really feel like one constant piece; as you scroll down, the noise sticks to the content material, considerably much like seeing texture on paper.
.noise {
opacity: 0.018;
}
I wouldn’t advocate noise for many web sites, and it’s very simple to overdo it, however I benefit from the refined filmic impact on my weblog.
Catalyst
I’m utilizing Catalyst, a brand new UI equipment by the Tailwind crew. It’s clear {that a} tonne of thought has gone into making these elements accessible, and pixel good, on each gentle and darkish modes.
Catalyst gives you with a set of recordsdata to obtain into your undertaking, and you may export your elements from these. Heroicons has additionally been up to date with new icons that match neatly into Catalyst.
import { Button } from "../elements/Button";
import { PaperAirplaneIcon } from "@heroicons/react/16/stable";
perform Part() {
return (
<Button kind="submit" colour="rose">
<PaperAirplaneIcon />
Ship message
</Button>
);
}
For those who’d like to customize your elements additional, you’ll be able to edit the downloaded recordsdata immediately. Every file incorporates Headless UI elements with lists of fastidiously annotated courses dispersed all through.
<HeadlessListBoxButton
className={clsx(
"group relative block w-full",
"after:pointer-events-none after:absolute ...",
"data-[disabled]:opacity-50 earlier than:data-[d... "
)}
...
/>
Catalyst is still in alpha, so be warned, breaking changes will most likely be ahead!
TWC
While we’re talking about Tailwind, I’ve used a new library called TWC to save time building reusable components. It takes boilerplate code you’ve written countless times (forwarding refs, adding clsx
, etc.), and makes it a one-liner.
const Card = twc.div`rounded-lg border bg-slate-100 text-white shadow-sm`;
<Card ref={ref} className={["my-6", hidden && "hidden"]} {...props} />;
Next.js
I’ve used Next.js to construct my new weblog, and just about each element is a server element. It feels fairly snappy, I prefer it.
Structure recordsdata
Did you discover that the header animation continues operating while you change pages? That’s as a result of it’s positioned in a Subsequent.js layout file, that means it doesn’t get refreshed on route adjustments.
export default perform Structure({ kids }) {
return (
<>
<HeaderAnimation />
<major>{kids}</major>
</>
);
}
OG picture technology
A significant ache level on my earlier weblog was manually creating every social media picture. These days, you’ll be able to generate OpenGraph images dynamically in Subsequent.js, and it’s little or no effort to get began.
export const runtime = "edge";
export const alt = "...";
export const dimension = { width: 1200, peak: 630 };
export default async perform Picture({ params }) {
return new ImageResponse((
<div fashion={{ show: "flex", colour: "#000" }}>
<div>A brand new weblog for 2024</div>
...
</div>
), { ...dimension });
}
Contentlayer
My weblog makes use of .mdx
recordsdata with customized React elements interspersed all through. I’d heard loads of good issues about Contentlayer, so I gave it a attempt—it’s been a breeze to make use of, and has actually sped up my growth time. It’s really easy to make adjustments to your schema, and the type-safe setup is great.
The way it works
You may generate a Publish
schema, for instance with a title
and date
, after which ask it to load recordsdata from the /posts
folder.
export const Publish = defineDocumentType(() => ({
title: "Publish",
filePathPattern: `/posts/**/*.mdx`,
contentType: "mdx",
fields: {
title: { kind: "string", required: true },
date: { kind: "date", required: true },
},
}));
Subsequent, create your .mdx
file in /posts
.
---
title: A brand new weblog for 2024
date: 2024-01-02
---
It’s been a _long_ time since I’ve publis…
Then merely import your posts, with full type-safety, and render your mdx
content material.
import { allPosts, Publish } from "contentlayer/generated";
import { useMDXComponent } from "next-contentlayer/hooks";
const put up: Publish = allPosts[0];
export default perform Web page() {
const MDXContent = useMDXComponent(put up.physique.code);
return <MDXContent />;
}
I’ve archived all of the posts from my earlier weblog, ctnicholas.dev, because it’d take too lengthy to switch them to the brand new website, although they’re all nonetheless available to read.
My weblog’s a piece in progress, and there is a lot extra I’d like so as to add, for instance:
Nevertheless it’s all too simple to get caught within the “only one extra characteristic…” loop, when a very powerful factor is to get transport! So right here it’s—thanks for studying.