How can I import mdx file staticly in App Router?
Answered
Cornish Rex posted this in #help-forum
Cornish RexOP
I have mdx files in my writings/_posts directory. When I'm using like this nextjs creating server rendered pages. How can I change it to static generation.
And then i'm using readMdxFile function in my slug.
import { compileMDX } from "next-mdx-remote/rsc";
import path from "path";
import { readFile, access, readdir } from "fs/promises";
import { notFound } from "next/navigation";
const POSTS_FOLDER = path.join(process.cwd(), "app/writings/_posts");
async function readPostFile(slug: string) {
const filePath = path.resolve(path.join(POSTS_FOLDER, '${slug}.mdx'));
try {
await access(filePath);
} catch (err) {
return null;
}
const fileContent = await readFile(filePath, { encoding: "utf8" });
return fileContent;
}
export default async function getMdxDatas({
params,
}: {
params: { slug: string };
}) {
const markdown = await readPostFile(params.slug);
if (!markdown) {
notFound();
}
const { content, frontmatter } = await compileMDX<{ title: string,date:Date }>({
source: markdown,
options: { parseFrontmatter: true },
});
// do something with frontmatter, like set metadata or whatever
return {
content,
frontmatter,
nextLink: "nextLink",
previousLink: "previousLink",
};
}
// get all slugs title and summary
export const getFiles = async () => {
const files = path.resolve(POSTS_FOLDER);
const fileNames = await readdir(files);
const data = await Promise.all(
fileNames.map(async (fileName) => {
const filePath = path.resolve(POSTS_FOLDER, fileName);
const fileContent = await readFile(filePath, { encoding: "utf8" });
const { frontmatter } = await compileMDX<{
title: string;
summary: string;
date: string;
image: string;
slug: string;
}>({
source: fileContent,
options: { parseFrontmatter: true },
});
return {
title: frontmatter.title,
summary: frontmatter.summary,
date: frontmatter.date,
image: frontmatter.image,
slug: fileName.replace(".mdx", ""),
};
})
);
return data;
};
export const getFilesWithCount = async (count: number) => {
const files = path.resolve(POSTS_FOLDER);
const fileNames = await readdir(files);
const data = await Promise.all(
fileNames.map(async (fileName) => {
const filePath = path.resolve(POSTS_FOLDER, fileName);
const fileContent = await readFile(filePath, { encoding: "utf8" });
const { frontmatter } = await compileMDX<{
title: string;
summary: string;
date: string;
image: string;
slug: string;
}>({
source: fileContent,
options: { parseFrontmatter: true },
});
return {
title: frontmatter.title,
summary: frontmatter.summary,
date: frontmatter.date,
image: frontmatter.image,
slug: fileName.replace(".mdx", ""),
};
})
);
return data.slice(0, count);
}
And then i'm using readMdxFile function in my slug.
import getMdxDatas from "@/lib/readMdxFile";
export default async function PostPage({
params,
}: {
params: { slug: string };
}) {
const { content, frontmatter, nextLink, previousLink } = await getMdxDatas({
params,
});
return (
<>
{content}
</>
);
}
Answered by not-milo.tsx
My bad. The link is this one then: https://nextjs.org/docs/app/api-reference/functions/generate-static-params
You have to use
As for the data that goes in them you can keep fetching it as you're doing right now.
You have to use
generateStaticParams
to tell Next what slugs to generate at build time.As for the data that goes in them you can keep fetching it as you're doing right now.
8 Replies
You should be using
See: https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation#static-generation-with-data
Btw, I highly recommend switching to the new app router if you want to future-proof your website.
getStaticProps
and getStaticPaths
to tell Next what data and pages to generate at build time. Without them it will default to SSR cause it has no knowledge of what slugs might be passed to your post page.See: https://nextjs.org/docs/pages/building-your-application/rendering/static-site-generation#static-generation-with-data
Btw, I highly recommend switching to the new app router if you want to future-proof your website.
Cornish RexOP
Thanks for your reply, actually I'm using app router, and I want to generate static pages from my local mdx files.
I'm using next-mdx-remote when I'm importing mdx files
My bad. The link is this one then: https://nextjs.org/docs/app/api-reference/functions/generate-static-params
You have to use
As for the data that goes in them you can keep fetching it as you're doing right now.
You have to use
generateStaticParams
to tell Next what slugs to generate at build time.As for the data that goes in them you can keep fetching it as you're doing right now.
Answer
Cornish RexOP
Thanks a lot, I will try this ðŸ™ðŸ»
Cornish RexOP
It's worked for my writings page but I didn't figure out how can I use ssg for my homepage. https://nextjs-forum.com/post/1214572991242051594
Great! Just a note tho, cross posting goes against the rules of the server
Tonkinese
You can always try one of their exports... I think it's something like forceStatic=true, but you should definitely look that up, but at the same time that's not really the best approach if there's a legit reason they can't generate the site statically.