Skip to content
Swizec Teller - a geek with a hatswizec.com

Building a small CMS with NextJS, pt2 – CodeWithSwiz

CodeWithSwiz is a twice-a-week live show. Like a podcast with video and fun hacking. Focused on experiments. Join live Wednesdays and Sundays

Continuing our NextJS app where we left off on Sunday, in this episode we made good progress:

  • added title slugification
  • copypasta instructions to create an article
  • extracted social card API into a custom hook
  • added hero to frontmatter
  • aaaalmost extracted my custom Markdown machinery out of techletter.app

You can see it live at swiz-cms.vercel.app. I used it to publish this today 🤘

Slugs and article creation 🍝

This is a baby CMS and relies on humans to do the work. Means you I can start using this before it's finished and start saving time and effort.

You're the computer, the CMS is your script.

import slugify from "slugify"
export const CLICopyPasta = ({ title }) => {
// creates the slug, hooray libraries
const slug = slugify(title).toLowerCase()
return (
<pre>{`
cd ~/Documents/websites/swizec.com
mkdir src/pages/blog/${slug}
mkdir src/pages/blog/${slug}/img
touch src/pages/blog/${slug}/index.mdx
`}</pre>
)
}

Yep, simple component. Open source slugify makes our slug and we write the instructions. Once is better than always.

Copypasta instructions for article creation

You can find someone on Fiverrr or Upwork to do these steps for you. Costs $10/week compared to Contentful which is $400/mo.

🤔

Custom hook for social cards

A frustration I wanted to solve was adding social cards as hero images to article frontmatter. Fiddly manual process. Error prone as heck.

Hero link shows up in frontmatter
Hero link shows up in frontmatter

There's 2 ways you can do this:

  1. Hoist social card fetching out of <SocialCardImage> to top component and push state down through props
  2. Create a reusable hook that internally avoids double fetching

Following my Wormhole state management principle, reusable hook is the way to go.

// components/SocialCardImage
export function useSocialCardQuery(title) {
return useQuery(["social-card", title], fetchSocialCard)
}

Doesn't look like much but therein lies magic. 🧙‍♂️

React Query dedupes API calls with the same name. Our hook ensures we use the same name and fetch function everywhere.

You can now pepper useSocialCardQuery anywhere in your app. It's always going to have the latest state and avoid refetching, if it knows the result.

Turn an old project into a library

This part proved tricky. We tried to extract the markdown machinery from techletter.app into a shared library.

techletter.app machinery in action

Extraction itself wasn't that hard:

  • create new project
  • yarn init to create package.json
  • add microbundle for packaging
  • copy files from old project
  • fix relative paths in imports
  • add index.js file that re-exports the public interface

Run microbundle and see it dies on image imports. It's meant for pure TypeScript and JavaScript projects.

We use images for loading gifs ...

Switch to parcel and packaging started working. A matter of changing config in package.json

"source": "src/index.js",
"scripts": {
"dev": "microbundle watch",
"build": "microbundle"
},
👇
"scripts": {
"dev": "parcel src/index.js",
"build": "parcel build src/index.js"
},

Yes no-config bundlers are that easy. Until you get into the weeds and try to be fancy that is.

Unfortunately it didn't work. global undefined whatever the heck that means 🤨

But I think I've got a solution, join me on Monday 6:30pm Pacific.

Favorite NextJS feature so far?

Initial quick setup was great and those error messages are divine. Beautifully designed, safe as heck, and fast.

An error message in NextJS
An error message in NextJS

With client-side bugs you get a blurred-out view of your app behind the error. Useful, no, cool as heck, yeah!

And your browser almost always reconnects to the development server even after a restart.

Cheers,
~Swizec

Did you enjoy this article?

Published on September 3rd, 2020 in CodeWithSwiz, Livecoding, Technical

Learned something new?
Want to become a high value JavaScript expert?

Here's how it works 👇

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

Start with an interactive cheatsheet 📖

Then get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career.

"Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

~ Ashish Kumar

Join over 10,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. ✌️

Have a burning question that you think I can answer? I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own?  Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first 💰 on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️