Refactor blog into Node.js. Session 1

Cover Image for Refactor blog into Node.js. Session 1
Sergej Brazdeikis
Sergej Brazdeikis

Why?

I have the blog, for which I rarely write, and no I do not need to reskin in with something new. On twitter folks do it every year and it is a trend.

After watching Next.js conf 2021 I was sold to try it out. Like I do not need to worry compressing images. Ever? Automatic removal of not used CSS? I'm sold!

Just to mention, I do not care that much, that it is done with React.js, for me it is opportunity to level up my knowlesdge of what is possible good tooling in 2021.

Let's go!

Useful links

Official tutorials is great place to start

Next.js tutorial page

After tutorials, the grate place to start is on Next.js GitHub - use their generator.

Next.js examples website

Like this:

Execute create-next-app with npm or Yarn to bootstrap the example:

npx create-next-app --example blog-starter blog-starter-app

or

yarn create next-app --example blog-starter blog-starter-app

Generate images

Changes I done straight away

And the start looks good so far. Love the folder and components structure, and there is no insane depth there. Good job to folks who created this example.

And this is a great start.

Things I started to change straight away.

Images from Markdown to Nextjs

I have some images in mardown context and I need that to display as NextJs Image component, I followed this blogpost originally:

Using NextJS and Next/Image with MDX Markdown Processing by George Michael

And I ended up with custom solution, which is probably worth short blogpost.

import ReactMarkdown from "react-markdown" import remarkGfm from 'remark-gfm' import Image from "next/image" import markdownStyles from "./markdown-styles.module.css" const renderers = { image: image => { return <Image src={image.src} alt={image.alt} height="200" width="355" /> }, paragraph: (paragraph) => { const { node } = paragraph; if (node.children[0].type === "image") { const image = node.children[0]; return <Image src={image.url} alt={image.alt} height="200" width="355" />; } return <p>{paragraph.children}</p>; }, } export default function PostBody({ content }) { return ( <div className="max-w-2xl mx-auto"> <ReactMarkdown className={markdownStyles["markdown"]} children={content} renderers={renderers} remarkPlugins={[remarkGfm]} /> </div> ) }

React-markdown component started to recommend to use components instead: https://github.com/remarkjs/react-markdown/blob/main/changelog.md#change-renderers-to-components

Keep in mind NextJs Image component needs width and height. So to parse custom mardown like this:

![Next.js tutorial page](/assets/blog/blog-nextjs-day1/Screenshot%202021-11-16%20at%2018.00.17.png "1007x990")

code is following:

import ReactMarkdown from "react-markdown" import Image from "next/image" import markdownStyles from "./markdown-styles.module.css" const components = { img: image => { const defaultSize = [4, 3] const [width, height] = typeof image.title === "string" && /^\d*x\d*$/.test(image.title) ? image.title.split("x").map((n) => parseInt(n)) : defaultSize; return <Image src={image.src} alt={image.alt} width={width} height={height} /> }, } export default function PostBody({ content }) { return ( <div className="max-w-2xl mx-auto"> <ReactMarkdown className={markdownStyles["markdown"]} children={content} components={components} /> </div> ) }

Relation with slugs

In this generated example, slug must match file name. I dissagree, and I will try to change it. Please share if you have already something.

Things I loved and enjoy a lot

  • RSS Generator
  • It is easy to extend current example
  • Again - Next.js Image compression is awesome!
  • I start to value Next.js docs more and more. Easy to read, fast to find info - great tool.
  • Folder and components structure, and there is no insane depth there. Good job to folks who created this example.

Tree structure

Todos for the other sessions

Sergej Brazdeikis
Sergej Brazdeikis