Skip to main content

Read MD files

  • Read MD files from local folder to display them as HTML files
  • NextJS + gray-matter

Code​

import { BottomNav } from "@/app/home/bottom-nav";
import { primaryText, secondaryText } from "@/app/utils/styles";
import fs from "fs";
import matter from "gray-matter";
import { useRouter } from "next/dist/client/router";
import Head from "next/head";
import Link from "next/link";
import path from "path";
import ReactMarkdown from "react-markdown";
import rehypeRaw from "rehype-raw";
import gfm from "remark-gfm";
import "./blog.css";
import { NavWithImage } from "./top-nav-no-user";

export default function Post({ post, otherPaths }) {
const router = useRouter();

if (router.isFallback) {
return <div>Loading...</div>;
}

return (
<>
<NavWithImage />
<div
className={`text-md min-h-screen text-left text-black ${secondaryText.className} blog`}
>
<Head>
<title>{post.title}</title>
<meta
name="description"
content="Golden Visa. Mindset & Strategies for Entrepreneurship, Global Citizenship, and the Nomadic Lifestyle. Learn How to Become a Digital Nomad"
/>
<meta
name="keywords"
content={`normal to nomad book, digital nomad book, nomad book, digital nomad, digital nomad visa, digital nomad jobs, spain digital nomad visa, what is a digital nomad, portugal digital nomad visa, digital nomad institute, digital nomad visa spain, free resources digital nomad institute, how to become a digital nomad, travel hack, travel hack flights, travel hack pro, travel tips, international travel tips, travel tips for italy`}
/>
<meta property="og:type" content="website" />
<meta property="og:title" content={post.title + " by Golden Visa"} />
<meta property="og:description" content={`${post.title}`} />
<meta
property="og:url"
content="https://goldenvisa.melchortatlonghari.com/"
/>
<meta name="twitter:creator" content="@meltatlonghari" />
</Head>
<div className="flex flex-col justify-center bg-neutral-200 py-2 md:flex-row">
<div className="w-full px-2 md:w-1/2">
<h1
className={`pt-2 text-4xl font-bold md:pt-10 md:text-6xl ${primaryText.className}`}
>
{post.title}
</h1>
<h2 className="text-sm text-gray-500 md:text-xl">
Melchor Tatlonghari
</h2>

<ReactMarkdown remarkPlugins={[gfm]} rehypePlugins={[rehypeRaw]}>
{post.content}
</ReactMarkdown>
</div>
<div className="w-full pl-10 md:w-1/4">
<h2 className="mb-1 mt-1 text-lg font-bold">Other Blogs</h2>
<ul className="list-disc">
{otherPaths.map((path) => {
return (
<li className="text-blue-500 hover:underline" key={path.slug}>
<Link
href={`/book-reviews/${path.slug}`}
className="text-base"
>
{path.data?.title}
</Link>
</li>
);
})}
</ul>
</div>
</div>
</div>
<BottomNav />
</>
);
}

export async function getStaticPaths() {
const files = fs.readdirSync(path.join(process.cwd(), "book-reviews"));
const paths = files.map((filename) => ({
params: {
slug: filename.replace(".md", ""),
},
}));

return {
paths,
fallback: true,
};
}

export async function getStaticProps({ params: { slug } }) {
const markdownWithMetadata = fs
.readFileSync(path.join("book-reviews", slug + ".md"))
.toString();
const { data, content } = matter(markdownWithMetadata);
const post = { slug, ...data, content };

const files = fs.readdirSync(path.join(process.cwd(), "book-reviews"));
const otherPaths = files.map((filename) => {
const markdownWithMetadata = fs
.readFileSync(path.join("book-reviews", filename))
.toString();
const { data } = matter(markdownWithMetadata);
return {
slug: filename.replace(".md", ""),
data: data,
};
});

return {
props: {
post,
otherPaths,
},
};
}