DEV Community

Cover image for How to Make a Markdown Blog With Next.js

How to Make a Markdown Blog With Next.js

Jose Felix on April 20, 2020

Don't want to code along? See this template on Github with even more features such as SEO, and deploy it instantly to Netlify or Zeit Now. Recentl...
Collapse
 
valkiriann profile image
Ana Enríquez • Edited

Hi Jose !

Thanks a lot for your article. I was following the steps and I got into some issues.

The first one is when you create the post and then write the index.js for the first time. I ran into an error because in the code you search for "date" and not for "updatedAt" for the date of the post.

I fixed that by changing the name of the property in the markdown files but maybe you want to edit the tutorial too.

My second problem is that I am stuck in the part of creating the layout component. I created the file layout.js under a components folder but I dont know how to link it in my index and I am getting an error because Layout is not defined.

I think I am missing a step.

I dont know nothing about react so maybe it is something very easy but I am afraid I cant continue. Could you help me?

Collapse
 
joserfelix profile image
Jose Felix

Hi Ana! Thanks for pointing out about the date. I have fixed it accordingly.

You are missing the layout because you haven't imported it. At the top of your file add:

import Layout from "../components/Layout";

Let me know if it worked. Cheers 😎

Collapse
 
valkiriann profile image
Ana Enríquez

Hi Jose, thanks for your quick reply! I have now finished the tutorial, thanks again for posting it. I have found some more issues but searching in google I was able to resolve it.

  • some more imports where missing in the code samples:

in typography.js was missing the typography const

const typography = new Typography(SutroTheme)

In [slug].js was also missing the Layout import
In the _app.js you imported typeface-lato but that typography was not installed, only the ones for sutro. so I had to install it with npm.

Those were simple things that with a little of inspection to the code and googling how to import in react I was able to solve but I you add it to the tutorial I think it would be perfect !!

thanks again for the guide :).

Thread Thread
 
joserfelix profile image
Jose Felix

I'm glad you liked the tutorial 🙌. Thanks for making the blog post better, I really appreciate it! I have fixed all these accordingly.

Collapse
 
mejanhaque profile image
Muhammad Mejanul Haque • Edited

Anyone who doesn't want to disable preflight in tailwindcss, just add headings, ul, ol etc. styles to your global CSS(ex: h1{@apply text-3xl} ), you can find this on tailwind docs. if you want to use google fonts make sure to add GoogleFont Tag in _document.tsx files. I prefer tailwind default rem, em sizes...which is more responsive.

Thanks for the post....

Collapse
 
joserfelix profile image
Jose Felix • Edited

Thanks for the solution! I also have pondered on a way to substitute Typography; thankfully, I found a Tailwind plugin which does this job! It is called tailwindcss-typography. Soon, I will be updating the repository.

P.S. It is done! Check the repository.

Collapse
 
shmulvad profile image
Søren Hougaard Mulvad

I tried to adapt the last part of your blog (optimizing the images) to my own project. I ran into the following problem though: If the image is cached, img.onLoad won't trigger resulting in the lqip image staying "on top". I solved it the following way, but is there a nice way that doesn't use useRef()?

import React, { useState, useRef, useEffect } from "react";
// ...
const Image = ({ alt, src }) => {
  const imgRef = useRef();

  // ...

  useEffect(() => {
    if (imgRef.current && imgRef.current.complete) {
      setImageLoaded(true);
    }
  }, []);

  return (
    <div className="relative">
      {/* lqip image ... */}
      <img
        ref={imgRef}
        // ...
      />
    </div>
  );
};
Collapse
 
joserfelix profile image
Jose Felix

Hi Søren, thanks for the read! One alternative is to use lazysizes. It is an awesome library that lets you create High performance and SEO friendly lazy loader for images. Check it out. You can also see my implementation in the repository

Collapse
 
esnare profile image
Esnare Maussa • Edited

Hi Jose!

Thanks for the article, I was following along and everything working at my end.

However, I noticed that the links inside the markdown files reload the whole page. For instance, I have a Contact Us page which URL is /contact-us and there is a link to that page in one markdown file. If I click on that link, the whole page is reloaded. In other words, it's the same behaviour as if it was added an a tag rather than the Link tag from next.

Is there any way to swap the a tag for a Link tag from the links coming from the Markdown files?

Thanks in advance!

Collapse
 
joserfelix profile image
Jose Felix

Hi Esnare, thanks for reading my post! I'm glad you like it.

Yes, it is possible to switch the <a/> with <Link/>. However, there is a caveat: using <Link/> for links outside your Next.js page will error out. My recommendation would be to create a <Link/> for the contact page, and an <a/> for everything else.

So, to get started we have to modify React Markdown default <a/>. For that, we have the renderers prop:

<ReactMarkdown
     escapeHtml={false}
     source={content}
     renderers={{            
         link: LinkNode,
     }}
/>

After that, let's create the LinkNode component:

const LinkNode = (props) => {
  // Here is the magic
 // Change to any conditional to match your contact form.
  if (props.href === "/contact-us") {
    return (
      <Link href={props.href} passHref>
        <a>{props.children}</a>
      </Link>
    );
  }

  return <a href={props.href}>{props.children}</a>;
};

That's it! I hope this helped.

Collapse
 
esnare profile image
Esnare Maussa

Thanks for your reply Jose,

That's good stuff, I shall test it now :)

While researching on that issue, I noticed this library called MDX github.com/mdx-js/mdx. Basically, it lets you use react components directly on the markdown files. Here is the integration it with with Next.js: mdxjs.com/getting-started/next, I am going to test this one too :)

Thanks for all mate!

Thread Thread
 
joserfelix profile image
Jose Felix

Awesome!

I have read about MDX and it is really good for creating interactive blog posts. I didn't use it in this tutorial because it is not compatible with most git-based CMS. Some CMS like netlify-cms do support it with a plugin, but for me, it still isn't mature enough.

In the future, I will experiment with it more and see if there is an efficient solution.

Collapse
 
woosungchoi profile image
WoosungChoi

I'm waiting sitemap, SEO and RSS feed!

Collapse
 
prasannagnanaraj profile image
PrasannaGnanaraj

Helpful post . Helped me set up my blog