Bye-bye Weeds! Digital Gardening with Astro & MDX.

A presentation at daily dev — Island Architecture - The Monthly Dev #35 in November 2023 in by Kathleen McMahon

Slide 1

Slide 1

Bye-bye Weeds! Digital gardening with Astro and MDX — Kathleen McMahon — daily.dev

● Welcome everyone! I’m Kathleen McMahon and I’m here today to talk about Bye-bye Weeds! Digital Gardening with Astro and MDX.

● Before we begin, let’s get some details out of the way.

Slide 2

Slide 2

Thank you organizers — daily.dev

First, I want to give a huge thank you to the thisDot team for inviting me to speak at this event!

Slide 3

Slide 3

https://noti.st/resource11

My presentation will be posted on Notist, that’s https://noti.st/resource11, after my talk. I’ll also post the full URL on Twitter sometime after my presentation

Slide 4

Slide 4

@resource11 Twitter | Instagram | GitHub

You can follow me at. Resource11 on Twitter, GitHub, and Instagram.

Let’s back up so I can introduce myself a bit better…

Slide 5

Slide 5

Kathleen McMahon | Engineer • Designer • Speaker

So I’m an engineer and a designer and I like to speak about things…

Slide 6

Slide 6

Cyclocross! [image] various pictures of me racing cyclocross

I’m an occasional cyclocross racer,

Slide 7

Slide 7

image: Me on a cyclocross bike, in Spam, Ninja Turtle, Nerds candy box, Medusa costumes

In costume of course.

Slide 8

Slide 8

image: a wide-screen view of the colorful lamps and lighting strips adorning my home office desk and bookcases

Lover of lights

Slide 9

Slide 9

image: A wide-planked boardwalk — with soft sand and sea grass surrounding its weathered wooden railing — leads toward the calm ocean during a cloudy afternoon low tide

Beach goer.

Slide 10

Slide 10

image: A montage of sand dollars of various sizes and colors, next to a tiny and medium sand dollar in the palm of my hand.

Sand dollar collector.

Slide 11

Slide 11

image: Thor, resting on the windowsill of my kitchen window, enjoying the warm summer breeze and sunshine on his soft beige fur and dreamy blue eyes.

Lover of my cats Thor…

Slide 12

Slide 12

image: Otis — my silky black haus panther — nestled between my purple bed pillows, gazing at me with calm golden eyes.

…and Otis.

Slide 13

Slide 13

image: A gathering of green aventurine, sodalite, rose quarts towers, and quarts diamond on the kitchen table

I’m a Crystal collector…

Slide 14

Slide 14

image: Otis, the black wonder cat, steps into the frame of my crystal collection

…and I photograph them, but Otis…

Slide 15

Slide 15

image: Otis' paws walk through my crystal arrangement on the kitchen table

…interferes often…

Slide 16

Slide 16

image: grouping of citrine, amethyst, and celestite glowing in the sun-washed windowsill

…with opinions…

Slide 17

Slide 17

image: Otis — sassy black cat — sits exactly on top of all my windowsill crystals, seeking attention.

…about my attention. Thanks, Otis

Slide 18

Slide 18

image: In pure art director fashion, Thor sits distinctly on one windowsill sand dollar. Ready to provide his ultimate design judgement.

Thor does the same.

Slide 19

Slide 19

image: Thor looks up from the windowsill to the camera with a very satisfied look. His blue eyes gaze hypnotically my way as his pink nose points upward, whiskers pridefully twitching.

He’s very satisfied with himself.

Slide 20

Slide 20

image: Otis looking very cute as he lays upside down on my bed, gazing at me.

Who could resist them, though?

I’ve worked on a few design systems like…

Slide 21

Slide 21

O’Reilly Media

Slide 22

Slide 22

LaunchDarkly

Slide 23

Slide 23

Northwestern Mutual

Slide 24

Slide 24

Design Systems are ALWAYS the hotness [image]: Person in inflatable dinosaur costume flips into a raft floating on a pond and claps with glee.

And I love Design Systems! it’s exciting work! Especially if you like…

Slide 25

Slide 25

image: Woman attempting to arrange 10 squirming kittens in a straight line, with varied success

…herding kittens. Always fun, with many moving parts. Part of Design System work includes trying out different software stacks and choosing the best tool for your system, like Gatsby.

Slide 26

Slide 26

Image: Gatsby and MDX logo

Speaking of Gatsby and MDX, they’re what I chose to build my Digital Garden site…

Slide 27

Slide 27

Image: KathleenMcMahon.dev homepage

kathleenmcmahon.dev back in 2020…

Slide 28

Slide 28

A digital what?

So… what is a digital garden?

Slide 29

Slide 29

What is a digital garden? [image]: Small potted plant next to a rake with caption, My blog is a digital garden, not a blog

This blog post by Joel Hooks, and this phrase makes sense to me: “What makes a garden is interesting. It’s personal. Things are organized and orderly, but with a touch of chaos around the edges.”

Slide 30

Slide 30

Image: Gatsby and MDX logo

I latched on to the idea of creating a digital garden and using Gatsby and MDX as my stack for a few reasons…

One because I tend to love trying…

Slide 31

Slide 31

image: ALL THE THINGS Hyperbole and a Half

All the things! All the latest software, but at the same time…

Slide 32

Slide 32

Perfection is the enemy of done

I struggle with making progress over seeking perfection, and if I’m not careful, lean towards making…

Slide 33

Slide 33

image: A Lexus with a big red bow juxtaposed next to a tiny kitten wearing a red bow. That floofy boi is baby Thor.

“Big Lexus bows” vs. “Tiny kitten bows”. Wow can I hyper-focus on the details, make that perfectly crafted piece of software before shipping. That’s heck on velocity, though.

The digital garden format keeps me in the kitten bow mindset. This way, progress happens, and blog posts get written. New things get shipped.

Slide 34

Slide 34

There be weeds [image]: Two fluffy dandelion weeds in a green field

Fast forward a few years and… a few talk listing and package updates later… I noticed that my Digital Garden got… weedy. And Gatsby had versioned up to 5.3, while my site was on 2.3

I considering an upgrade and asked an industry colleague familiar with Gatsby how painful this upgrade would be. Of course I already knew the answer. 3 major versions. Ouch. But! After asking, and hearing the expected — yes it’ll be a pain — the advice leaned towards the obvious.

“If it’s using JavaScript, it requires regular maintenance” (OK…) which turned into a suggestion to use Squarespace, since it didn’t require maintenance.

[image]: UnSplash — masaaki-komori—0M1TKzvr3Y-unsplash

Slide 35

Slide 35

JavaScript is hard

And that kinda sounded like JavaScript’s hard… and maybe you’re out of your league…

Slide 36

Slide 36

JavaScript is hard …maybe you should build a Squarespace site?

“…maybe you should create a Squarespace site?”

Slide 37

Slide 37

image: Judy Hopps from Zootopia, shakes her head in disgust

Did you just say something was hard? Hello… spite driven development. By golly I would upgrade this app three versions up. Squarespace my butt.

Slide 38

Slide 38

10 hours later…

Slide 39

Slide 39

image: Judy Hopps from Zootopia, shakes her head in disgust

Still shaking my head about that Squarespace suggestion.

Slide 40

Slide 40

image: Shrimp and lime jello mold, plated with apple slices

Ten hours later, after a Netflix binge and upgrade session…I come up for air. I’ve fixed all the new GraphQL changes and was wrestling with the Gatsby image API, and now I’m questioning life choices…

It was like combining jello with shellfish; deciding to go all in was a bad decision.

Slide 41

Slide 41

"if you want a static site, why are you using a whole JavaScript framework to render it?"

I thought “I have a four-page static site. Why am I using a JavaScript framework to render four static pages in a blog, and…

Slide 42

Slide 42

Why use JSX to create HTML when you could just… use HTML?

Why am I using JSX to create HTML when I could just use HTML?”

Granted, I work on Design Systems. I love creating component APIs, and love using React, so I’m the last person to say just throw it all out, but there are times where you need a four-page site without throwing all this JavaScript at it just to render something that’s small, lean, performant, and just doesn’t need to be a SPA, it needs to be a multi-page app.

Slide 43

Slide 43

Why use JSX to create HTML when you could just… use HTML? ● …a four-page site without throwing all this JavaScript at it just to render something that’s small, lean, performant, and just doesn’t need to be a SPA, it needs to be a multi-page app.

Slide 44

Slide 44

I don't need a suite of combine machines. [image]: Large agricultural harvesting machines in a vast golden field

And the Gatsby of 2020 isn’t the same as it is today. That hot static site generator everyone wanted to use has evolved into this suite of industrial farming equipment.

[image] UnSplash — darla-hueske-SD18qQeXEg8

Slide 45

Slide 45

A hoe and rake will do. [image] Small rake, pronged fork and clippers in a modest garden

I don’t need a combine machine when a hoe and rake will do for my needs.

[image] UnSplash — diana-light-342WASC0aSQ

Slide 46

Slide 46

Weed out the Complexity [image]: Gloved hand digging weeds out of a garden

It was time to weed out the complexity, and choose a new framework

One that will compile right down to HTML CSS and only serve the minimal amount of JavaScript if I need it.

[image] UnSplash — ales-krivec-6UtxyuTdpQU

Slide 47

Slide 47

image: Astro.build homepage

So I looked around — and because there’s a bunch out there and… oh hai Astro… let’s take a look at you.

Slide 48

Slide 48

Why Astro?

Why did I choose Astro?

SolidJS Support

I can try out different UI frameworks in Astro without going all-in

I can bring in components from my other app and convert them one at a time without have to completely convert every component over at a time (some here are React, some are Solid, I’m using pragmas)

Content-focused - fetch from a CMS or work locally with type-safe Markdown or MDX (which is the reason I want it)

Content collections

Type safety

Slide 49

Slide 49

Why Astro? [image] Astro documentation page

Why did I choose Astro?

Astro was designed for building content-rich websites. And I zeroed in on blogs, portfolios… I don’t need a logged-in dashboard, or complex native app interactions that NextJS would give me, so this seems like a safe bet.

Slide 50

Slide 50

MDX support

MDX support. I can add my MDX pages and move on.

Slide 51

Slide 51

PostCSS support

It supports PostCSS by default, so my current CSS setup will port over without much fuss.

Slide 52

Slide 52

Astro Islands

Astro Islands. These are interactive UI components on the page that render in isolation using partial/selective hydration

Slide 53

Slide 53

Convert some components or all components

So I can import my React components from my Gatsby project. I can choose to convert them to Astro components over time, or leave them as React components.

Slide 54

Slide 54

I can try out different UI frameworks in Astro

I can try out different frameworks, like SolidJS, and Vue, without fully committing to a framework.

And share state between them.

Slide 55

Slide 55

MPA Architecture

That’s pretty cool. Astro also uses MPA and server-side rendering vs a client-side Single-page app, so it’s performant.

Slide 56

Slide 56

Leaner configs

And the configs are much leaner. Check this out.

Slide 57

Slide 57

image: side-by-side comparison — gatsby-config.js 😀 astro.config.mjs 😀

Here the Gatsby’s config on the left versus Astros config on the right

Slide 58

Slide 58

image: side-by-side comparison — gatsby-config.js 😀 astro.config.mjs 😀

In the Astro config we have the site deploy url, markdown, integrations, image and build configs. All in a small list….

Slide 59

Slide 59

image: side-by-side comparison — gatsby-config.js 😀 astro.config.mjs 😀

And the Gatsby config has all these PostCSS imports… configs… site metadata…

Slide 60

Slide 60

image: side-by-side comparison — gatsby-config.js 😶 astro.config.mjs 😀

Plugins…

Slide 61

Slide 61

image: side-by-side comparison — gatsby-config.js 🤔 astro.config.mjs 😀

More plugins…

Slide 62

Slide 62

image: side-by-side comparison — gatsby-config.js 😐 astro.config.mjs 😀

MORE plugins…

Slide 63

Slide 63

image: side-by-side comparison — gatsby-config.js 😑 astro.config.mjs 😀

…to resolve…

Slide 64

Slide 64

image: side-by-side comparison — gatsby-config.js 😐 astro.config.mjs 😀

The config keeps going…

Slide 65

Slide 65

image: side-by-side comparison — gatsby-config.js 🫤 astro.config.mjs 😀

And… Going.

Slide 66

Slide 66

image: side-by-side comparison — gatsby-config.js 😬 astro.config.mjs 😀

And. Going.

Slide 67

Slide 67

image: side-by-side comparison — gatsby-config.js 😳 astro.config.mjs 😀

And. Going.

Slide 68

Slide 68

image: side-by-side comparison — gatsby-node.js 🫣 astro.config.mjs 😀

Here’s the Gatsby.node file for creating nodes because I didn’t want to have my blog posts under the source folder, so I could be really fancy and smart.

Slide 69

Slide 69

image: side-by-side comparison — gatsby-node.js 🙄 astro.config.mjs 😀

Look and me go… and add unnecessary complexity!

I had to create all these nodes and do GraphQL queries to make the absolute paths to create the posts. YAY,,,

Slide 70

Slide 70

image: side-by-side comparison — gatsby-browser.js 🙃 astro.config.mjs 😀

And a Gatsby browser file with this WrapRoot element so I could wrap styled components and pass them into MDX all at once for usage

Slide 71

Slide 71

Till the soil [image] Person digging with a spade into the soil

Once I ported my components over to an Astro project there were some differences

[image] UnSplash — jonathan-kemper-f6RoUmj4iiM

Slide 72

Slide 72

From React children to Astro slots

Slide 73

Slide 73

image: side-by-side comparison — layout.js Layout.astro

Slide 74

Slide 74

image: side-by-side comparison — layout.js Layout.astro

Here’s the Gatsby layout page on the left versus the Astro layout page on the right

In the layout.js file, we’re importing React components and a CSS modules file.

In the Layout.astro file, the components are now astro components, and we’re using a CSS file and the Astro pageTitle prop.

Slide 75

Slide 75

image: side-by-side comparison — layout.js Layout.astro

In the Gatsby layout, we’d use classnames and the useExtraClasses utility for style concatenation

Slide 76

Slide 76

image: side-by-side comparison — layout.js Layout.astro

And in the Gatsby layout we use the children prop, where in the Astro layout we now use slot

Slide 77

Slide 77

Add mulch [image]: Hands holding soil

Now that the layout is set, time to mulch some content.

[image] UnSplash —gabriel-jimenez-jin4W1HqgL

Slide 78

Slide 78

From GraphQL to Content Collections

First, ditch those GraphQL queries, and add in Astro’s Content Collections

Content collections are the best way to manage and author content in any Astro project. Collections help to organize your documents, validate your frontmatter, and provide automatic TypeScript type-safety for all of your content.

Slide 79

Slide 79

image: GraphQL indexQuery

In Gatsby, I had this one query to grab images from a local folder. Literally 6 images.

Slide 80

Slide 80

image: GraphQL aboutQuery

This other one to grab images for my about page

Slide 81

Slide 81

image: GraphQL writeQuery

Queries for my write page, and a query for my MDX posts to parse all the data into readable format. That’s a lot for a small site.

Slide 82

Slide 82

image: Astro config.ts

In comparison, Astro’s Content Collections Added in: astro@2.0.0 is much simpler.

It allows you to organize your documents, validate frontmatter, and provide content schema type-safety.

Slide 83

Slide 83

Dynamically generating routes

Along with content collections, you can dynamically generate routes…

Slide 84

Slide 84

image: […slug].astro file

By creating this […slug].astro file and use the getCollection function from astro:content and getStaticPaths functions to parse your data and pop it in your pages/posts folder.

The getCollection function will grab your blog data, and combined with the getStaticPaths function, it will map data for each of your posts.

No more finagling post files. No more Gatsby CreatePage nonsense.

Slide 85

Slide 85

Type-safe MDX with Zod.

The other great thing about content collections is Type safety in your MDX with Zod

Slide 86

Slide 86

Zod… say what?

So what is Zod anyway?

Slide 87

Slide 87

Zod TypeScript-first schema validation with static type inference

The official definition is: TypeScript-first schema validation with static type inference. What that means is: Zod uses TS to create schemas to help you validate your data.

Slide 88

Slide 88

Plant new starters [image] hand planting starters in soil

Now that your content is defined and validated, time to plant new starters. We need to pull in some Images.

Slide 89

Slide 89

< Image />

Let’s use the new Images API

Slide 90

Slide 90

image:assets

New Image assets was released as stable in Astro 3.0 replaces the original @astrojs/image integration

Slide 91

Slide 91

image: <Image /> example file

This API the allows you to import any any image from the src/assets folder, and if when you pop it in the source and add the required alt attribute… yay a11y!…

Slide 92

Slide 92

image: <img /> example file

Astro generates this optimized images with the following attributes in the DOM for you

Slide 93

Slide 93

Stubborn Link Icon conversions

Oh boy… icons. This was fun… And time-consuming

Slide 94

Slide 94

From Gatsby-links to Astro links

First there was the whole Gatsby link conundrum

Slide 95

Slide 95

From ReactFontawesome to astro-iconify

Slide 96

Slide 96

image: side-by-side comparison — Link.jsx Link.astro

I had a Link component, and wanted to leverage React Font Awesome for the a11y svg icon benefits, and got stuck for a week

No matter what, Icon would break, couldn’t integrate the component

Ended up refactoring to Link astro component and using astro-iconify and customizing icon svg imports, optimizing for a11y

Slide 97

Slide 97

What I’ve learned

To wrap up… here’s what I’ve learned from converting my site to Astro.

Slide 98

Slide 98

Big Lexus bows vs. Tiny kitten bows

Naturally, there was tension between Big Lexus bows and kitten bows as I migrated my site to Astro

Slide 99

Slide 99

Schemas are tricky. So are dynamic imports… with images.

Schemas are tricky. So are dynamic imports… with images.

Slide 100

Slide 100

CSS load order is no joke.

_[…slug].css files load first because

Markdown layout files load first because

Base.css files load because

We’re so clever with our main.css file yo and

Now we’re overwriting something in our base styles

Because we’re every-layout clever

https://every-layout.dev/layouts/stack/

Also, astro files don’t like CSS modules

Slide 101

Slide 101

Clean up file cruft, or your Netlify deploys will fail

Netlify will pick up any stray YAML files during your build, and if they don’t follow your schema… uh, oh.

Slide 102

Slide 102

ViewTransitions are buggy in Astro 3.0.12

ViewTransitions are buggy in Astro 3.0.12

Slide 103

Slide 103

ViewTransitions are better in Astro 3.6.1

Slide 104

Slide 104

Demo

Slide 105

Slide 105

Everything Everywhere at Once

Everything Everywhere at once… whew it was a challenge.

Slide 106

Slide 106

What components are still port over (yet)

Slide 107

Slide 107

Card

Complex card

Slide 108

Slide 108

Custom MDX components

Custom MDX components… in particular…

Slide 109

Slide 109

custom CodeBlock with react-live/ DisplayBox

react-live doesn’t play well with custom components… yet

Slide 110

Slide 110

Thank you Astro team @Bryceguy @Sarah @Elian @Sarah11918 @Erika @Tony-Sull @Kevin @Yan @Otterlord

I want to give a huge shout out to a few people of the Astro core team and community that worked with me through my site conversion. Thank you, you are amazing!

Slide 111

Slide 111

Thank you.

Slide 112

Slide 112

image: Otis standing in front of a large group of sand dollars arranged on the sun-washed kitchen table

Slide 113

Slide 113

@resource11 Twitter | Instagram | GitHub

Slide 114

Slide 114

image: Otis standing in front of a large group of sand dollars arranged on the sun-washed kitchen table, reaches his paw out to grab the camera