feat: add Post 2024-03-02-version-3
#2
3 changed files with 44 additions and 36 deletions
|
@ -56,7 +56,8 @@ pre:has(code) {
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.attr-name {
|
||||
.token.attr-name,
|
||||
.token.property {
|
||||
color: #73daca;
|
||||
}
|
||||
|
||||
|
|
|
@ -163,6 +163,7 @@ aside {
|
|||
mark {
|
||||
background-color: var(--color-border);
|
||||
color: var(--color-text);
|
||||
padding-block: var(--spacing-0\.25);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
|
|
|
@ -7,43 +7,46 @@ tags:
|
|||
- rebuild
|
||||
youtube: true
|
||||
---
|
||||
Welcome to version 3.0! This has been my pet project for the better part of a year, with plenty of false starts and scrapped ideas.
|
||||
Welcome to version 3.0! This has been my pet project for the better part of a year, with plenty of false starts and scrapped ideas.
|
||||
|
||||
First off, if what you're after is the source code - [here it is](https://github.com/wonderfulfrog/wonderfulfrog.com). If you'd like to learn more, read on dear reader!
|
||||
|
||||
I’ve had a Figma file ready for months now that outlined my basic design - all I needed to do was build it. The problem was I could not settle on how I wanted to do it.
|
||||
I’ve had a Figma file ready for months now that outlined my basic design - all I needed to do was build it. The problem was I could not settle on how I wanted to do it.
|
||||
|
||||
{% image "https://cdn.wonderfulfrog.com/figma-v3.png", "A screenshot from Figma showing my blog prototype. There are various elements visible like buttons and widgets. A colour scheme using teal.", "Figma screenshot" %}
|
||||
|
||||
{% image "https://cdn.wonderfulfrog.com/figma-v3-lightmode.png", "Another screenshot from Figma showing my blog prototype. This is showing the 'light theme' with a serif title font, monospaced body font, and teal accent colours.", "Astute observers will notice the current version doesn't look a whole lot like the site now!" %}
|
||||
|
||||
Something that always frustrated me was having my content along the code. I sought out a solution for this for months. I tried a whole bunch of headless CMS options like [Sanity](https://www.sanity.io/), [Hygraph](https://hygraph.com/), [Ghost](https://ghost.org/), and even hosting my own [WordPress](https://wordpress.com) (that was an exciting prospect until I discovered their mobile app does not support plugins).
|
||||
|
||||
I was always paranoid that bad actors would clone my git repo and steal my content, so I was so focused on finding a secure, obfuscated method to store content.
|
||||
I was always paranoid that bad actors would clone my git repo and steal my content, so I was so focused on finding a secure, obfuscated method to store content.
|
||||
|
||||
One day I thought to myself “who cares?” and it was like a switch flipped. Bad actors can still copy and paste everything, so having the content off the repo makes little difference. LLMs are exploding and would make it trivial to scrape my site (if they wanted to).
|
||||
One day I thought to myself “who cares?” and it was like a switch flipped. Bad actors can still copy and paste everything, so having the content off the repo makes little difference. LLMs are exploding and would make it trivial to scrape my site (if they wanted to).
|
||||
|
||||
At last, that let me narrow down my options. I’ll just keep the text content in the repo. But I still wanted a way to store images and other large media outside of the repo (more on that later. )
|
||||
|
||||
If the text content can be in the repo, then I can use anything! So let’s stick with [Next.js](https://nextjs.org/)! … actually, let’s not.
|
||||
If the text content can be in the repo, then I can use anything! So let’s stick with [Next.js](https://nextjs.org/)! … actually, let’s not.
|
||||
|
||||
## An Aside on Breaking Changes
|
||||
|
||||
Anyone working in the web dev sphere knows things move fast. Too fast these days - in my opinion. Next.js happens to be one of those libraries. My site hasn’t had any significant updates since 2022, which is approximately 2 years and change at the time of writing. In web years that’s ancient.
|
||||
|
||||
I tried to migrate to the new [app router structure](https://nextjs.org/docs/app) and found myself getting stuck learning about breaking changes in Next.js and breaking changes in React[^1]. I spent way too much time trying to get things working with my tools that I didn’t stop and think that my tools should be working for me.
|
||||
I tried to migrate to the new [app router structure](https://nextjs.org/docs/app) and found myself getting stuck learning about breaking changes in Next.js and breaking changes in React[^1]. I spent way too much time trying to get things working with my tools that I didn’t stop and think that my tools should be working for me.
|
||||
|
||||
I was originally thinking of [Astro](https://astro.build/), but it’s still using React. I’m happy to use React for work but I don’t want to have to deal with its newest idiosyncrasies in my own stuff.
|
||||
|
||||
Simply put modern React confuses the hell out of me. I’m not all in for [“server vs client components”](https://nextjs.org/learn/react-foundations/server-and-client-components). I’m certainly not the only one[^4]. I don't want this post to digress into my thoughts on modern React so I'm going to sidestep that for now. I’m spending time wrapping my head around modern React - because I have to for my job - but for my personal site I'd rather things should be _easy._ I'm tired of having to deal with breaking changes all the time. I longed for the days of PHP where stuff just worked forever. It was time to embrace an old foe: boring technology.
|
||||
Simply put modern React confuses the hell out of me. I’m not all in for [“server vs client components”](https://nextjs.org/learn/react-foundations/server-and-client-components). I’m certainly not the only one[^4]. I don't want this post to digress into my thoughts on modern React so I'm going to sidestep that for now. I’m spending time wrapping my head around modern React - because I have to for my job - but for my personal site I'd rather things should be _easy._ I'm tired of having to deal with breaking changes all the time. I longed for the days of PHP where stuff just worked forever. It was time to embrace an old foe: boring technology.
|
||||
|
||||
Boring technology - to me, anyway - is something that’s been around for a while, probably a few years. It’s stable. It’s been around long enough that someone has asked the basic questions on how to do XYZ on StackOverflow. And something important to me is that it’s also *averse to breaking changes*. It tries its best to avoid them, and if they must then there is a clear migration path and plenty of warning.
|
||||
Boring technology - to me, anyway - is something that’s been around for a while, probably a few years. It’s stable. It’s been around long enough that someone has asked the basic questions on how to do XYZ on StackOverflow. And something important to me is that it’s also *averse to breaking changes*. It tries its best to avoid them, and if they must then there is a clear migration path and plenty of warning.
|
||||
|
||||
My first thought was WordPress. That’s nice boring technology. Battle tested. There are even some web dev folks out there using it as a headless CMS. I ended up not using it because the mobile publishing experience was no good. It didn’t support plugins on the mobile app. I knew I’d want something like [ACF](https://www.advancedcustomfields.com/) at least.
|
||||
My first thought was WordPress. That’s nice boring technology. Battle tested. There are even some web dev folks out there using it as a headless CMS. I ended up not using it because the mobile publishing experience was no good. It didn’t support plugins on the mobile app. I knew I’d want something like [ACF](https://www.advancedcustomfields.com/) at least.
|
||||
|
||||
After a while I remembered a project I’d seen ages ago that I knew a lot of folks were using. It’s called [Eleventy](https://www.11ty.dev/) (or 11ty for short). [There’s a video of the creator trying out a blog using the latest version all the way back to the earliest versions of the project](https://www.youtube.com/watch?v=bPtQmsjXMuo)[^2]. Now that’s what I like to see. Stable. Fast. Let’s do it.
|
||||
After a while I remembered a project I’d seen ages ago that I knew a lot of folks were using. It’s called [Eleventy](https://www.11ty.dev/) (or 11ty for short). [There’s a video of the creator trying out a blog using the latest version all the way back to the earliest versions of the project](https://www.youtube.com/watch?v=bPtQmsjXMuo)[^2]. Now that’s what I like to see. Stable. Fast. Let’s do it.
|
||||
|
||||
{% youtube "bPtQmsjXMuo", "How Stable is Eleventy? Can we run a 5-year old project as-is with Eleventy 2.0?" }
|
||||
{% youtube "bPtQmsjXMuo", "How Stable is Eleventy? Can we run a 5-year old project as-is with Eleventy 2.0?" %}
|
||||
|
||||
So I decided to do what every web dev with a blog does: rebuild their blog from scratch. At least I had some content to play with!
|
||||
|
||||
## Cranking it up to 11(ty)
|
||||
|
||||
Eleventy is a static site generator. It does what probably other popular options like Next.js or Astro do. I chose it because:
|
||||
|
@ -66,9 +69,9 @@ Those are my biggest reasons for choosing it. But it also does some cool stuff l
|
|||
- Is fine with organizing things however you want
|
||||
- Did I mention it’s fast?
|
||||
|
||||
A whole site build from scratch takes 30 seconds, and most of the time is fetching images (for optimization, more on that later).
|
||||
A whole site build from scratch takes 30 seconds, and most of the time is fetching images (for optimization, more on that later).
|
||||
|
||||
I really liked how easy it was for me to organize content my way and tell 11ty how to consume it. It took a fair bit of learning on my part, but once it clicked I felt powerful.
|
||||
I really liked how easy it was for me to organize content my way and tell 11ty how to consume it. It took a fair bit of learning on my part, but once it clicked I felt powerful.
|
||||
|
||||
Something I’d like to mention and emphasize is the tool chain (or lack of). Under the hood, it’s all plain JS. There’s no [Webpack](https://webpack.js.org/), no [Babel](https://babeljs.io/). The only real dependency is [Node 18](https://nodejs.org/en). It uses CommonJS which is pretty old nowadays but again - boring technology! What it means is that I don’t have to worry about things breaking because a dependency changed. Even as I write this with 11ty 3.0 on the horizon - it will still work with CommonJS with the option to opt-in to ESM. There are clear migration steps. Amazing!
|
||||
|
||||
|
@ -78,7 +81,7 @@ Something I’d like to mention and emphasize is the tool chain (or lack of). Un
|
|||
|
||||
I wanted to focus on vanilla CSS as much as possible, and use a little post-processing to tidy things up, add missing prefixes (if needed), and all the boring stuff. Otherwise, let's try using some new features like `:has`!
|
||||
|
||||
A methodology that resonated with me was [CUBE CSS](https://cube.fyi/). CUBE standing for Composition, Utility, Block, and Exception. The site has a great explanation of how that breaks down, but for my own purposes, I interpreted it as:
|
||||
A methodology that resonated with me was [CUBE CSS](https://cube.fyi/). CUBE standing for <mark>Composition, Utility, Block, and Exception</mark>. The site has a great explanation of how that breaks down, but for my own purposes, I interpreted it as:
|
||||
|
||||
- Composition: utility classes that do one thing and one thing well, e.g. a wrapper class for centering a layout and giving it a `max-width`.
|
||||
- Utility: Design tokens and extremely simple utility classes. Very similar to the utility classes that [Tailwind](https://tailwindcss.com/) provides, albeit fewer.
|
||||
|
@ -130,16 +133,16 @@ I then wrote some JavaScript functions to transform these JSON values into CSS v
|
|||
|
||||
```css
|
||||
:root {
|
||||
--primary: 188deg 84% 35%;
|
||||
--color-primary: hsl(--primary);
|
||||
--primary: 188deg 84% 35%;
|
||||
--color-primary: hsl(--primary);
|
||||
}
|
||||
|
||||
.bg-primary {
|
||||
background-color: var(--color-primary);
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -321,11 +324,11 @@ const fetchRecentTracks = async () => {
|
|||
};
|
||||
|
||||
module.exports = async function () {
|
||||
const recentTracks = await fetchRecentTracks();
|
||||
const recentTracks = await fetchRecentTracks();
|
||||
|
||||
return {
|
||||
recentTracks,
|
||||
};
|
||||
return {
|
||||
recentTracks,
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -342,8 +345,8 @@ This was a thorny issue for me. I couldn't decide on how I wanted to manage medi
|
|||
|
||||
As I dug into 11ty, I discovered a truly magical plugin called [`eleventy-img`](https://www.11ty.dev/docs/plugins/image/). It takes an image (either locally or remote), optimizes it, and stores it in the _output_ directory. The image can therefore be put anywhere you like, and with a small bit of shortcode it works like magic. For example:
|
||||
|
||||
```njk
|
||||
{% image "https://path.to.image.jpg" %}
|
||||
```
|
||||
{% raw %}{% image "https://path.to.image.jpg" %}{% endraw %}
|
||||
```
|
||||
|
||||
It's a little bit of extra syntax compared to a Markdown image (and the newest version of `eleventy-img` doesn't even require shortcodes), but it saves so much manual effort of resizing and optimizing images.
|
||||
|
@ -378,18 +381,18 @@ As mentioned, a bunch of `.json` files that have my design tokens in here. That'
|
|||
|
||||
### Plugins
|
||||
|
||||
11ty has a lot of [built-in plugins](https://www.11ty.dev/docs/plugins/), but also makes it easy to define your own. In my case I've defined a customized Markdown processor using `markdown-it`. I added some neat features:
|
||||
11ty has a lot of [built-in plugins](https://www.11ty.dev/docs/plugins/), but also makes it easy to define your own. In my case I've defined a customized Markdown processor using [`markdown-it`](https://github.com/markdown-it/markdown-it). I added some neat features:
|
||||
|
||||
- [Footnotes](https://github.com/markdown-it/markdown-it-footnote)
|
||||
- [Abbreviations](https://github.com/markdown-it/markdown-it-abbr)
|
||||
- [Heading anchors](https://github.com/valeriangalliat/markdown-it-anchor)
|
||||
- [Code highlighting using Prism](https://github.com/jGleitz/markdown-it-prism)
|
||||
|
||||
I'm also using the [@11ty/eleventy-plugin-rss](https://www.11ty.dev/docs/plugins/rss/) plugin to generate my RSS feed. I'm glad to see that 11ty supports RSS feeds out-of-the-box. I always hated that setting up an RSS feed in Next.js felt rather hacky.
|
||||
I'm also using the [`@11ty/eleventy-plugin-rss`](https://www.11ty.dev/docs/plugins/rss/) plugin to generate my RSS feed. I'm glad to see that 11ty supports RSS feeds out-of-the-box. I always hated that setting up an RSS feed in Next.js felt rather hacky.
|
||||
|
||||
### Shortcodes
|
||||
|
||||
[Shortcodes](https://www.11ty.dev/docs/shortcodes/) are cool. They're like custom Markdown but supercharged. I have my aforementioned `image` shortcode, and another for embedding YouTube videos using `lite-youtube`.
|
||||
[Shortcodes](https://www.11ty.dev/docs/shortcodes/) are cool. They're like custom Markdown but supercharged. I have my aforementioned `image` shortcode, and another for embedding YouTube videos using [`lite-youtube`](https://github.com/justinribeiro/lite-youtube).
|
||||
|
||||
### Transforms
|
||||
|
||||
|
@ -418,7 +421,7 @@ My site is hosted on [Netlify](https://netlify.com/). I've used it in the past,
|
|||
|
||||
I use the [`netlify-plugin-cache`](https://github.com/jakejarvis/netlify-plugin-cache) plugin to keep my 11ty cache between builds. It really helps keep the build times down.
|
||||
|
||||
Whenever a change is detected on the `main` branch, a new version is deployed automatically.
|
||||
Whenever a change is detected on the `main` branch, a new version is deployed automatically.
|
||||
|
||||
## Conclusion
|
||||
|
||||
|
@ -444,15 +447,18 @@ Here are some resources I used (likely heavily) while building the site.
|
|||
- [Lea Verou](https://lea.verou.me/) ([view source](https://github.com/LeaVerou/lea.verou.me))
|
||||
|
||||
### Data Cascade
|
||||
- https://www.11ty.dev/docs/data-cascade/
|
||||
- https://benmyers.dev/blog/eleventy-data-cascade/
|
||||
- [The Data Cascade](https://www.11ty.dev/docs/data-cascade/)
|
||||
- [I Finally Understand Eleventy's Data Cascade.](https://benmyers.dev/blog/eleventy-data-cascade/)
|
||||
|
||||
### Setting up an 11ty blog
|
||||
- https://benmyers.dev/blog/eleventy-blogroll/
|
||||
- https://heydonworks.com/article/wordpress-to-eleventy/
|
||||
### 11ty setup and configuration
|
||||
- [Build a Blogroll with Eleventy](https://benmyers.dev/blog/eleventy-blogroll/)
|
||||
- [From Wordpress To Eleventy With Ease](https://heydonworks.com/article/wordpress-to-eleventy/)
|
||||
- [Optimizing Images with the 11ty Image Plugin](https://www.aleksandrhovhannisyan.com/blog/eleventy-image-plugin/)
|
||||
|
||||
### Implementing design tokens
|
||||
- https://heydonworks.com/article/design-tokens-in-eleventy/
|
||||
### 11ty and design
|
||||
- [What Are Design Tokens?](https://css-tricks.com/what-are-design-tokens/)
|
||||
- [Configuring Web Fonts in 11ty with Global Data](https://www.aleksandrhovhannisyan.com/blog/configuring-web-fonts-in-11ty-with-global-data/)
|
||||
- [Easily Use Design Tokens In Eleventy](https://heydonworks.com/article/design-tokens-in-eleventy/)
|
||||
|
||||
[^1]: Search for "nextjs react hydration error" to see what I mean.
|
||||
[^2]: Here is [a post on 11ty.dev](https://www.11ty.dev/blog/stability/) with additional information, if you're curious.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue