Next.js Discord

Discord Forum

Issue with [slug]

Unanswered
Philippine Crocodile posted this in #help-forum
Open in Discord
Philippine CrocodileOP
Hello,

I'm creating a simple blog using NextJS and MDX. For the routing, I have app/posts/[slug]/page.tsx that gets the post from the slug.

I have a post that is on the /posts/test-article route and locally it works. But, when I host my website on Vercel, it don't work.

How can I fix it? I tried to create a page without [slug] and it worked.

My code: https://github.com/ItsMeViipeR/nextlevel-tech

50 Replies

Philippine CrocodileOP
Here's the function

export const getPosts = async () => {
  const files = await fs.readdir(postsDirectory);
  const fileNames = files.filter((file) => file.endsWith(".mdx"));

  const posts: Post[] = [];

  for await (const fileName of fileNames) {
    const fullPath = path.join(postsDirectory, fileName);
    const fileContents = await fs.readFile(fullPath, "utf-8");
    const frontmatter = matter(fileContents);

    const safeData = PostSchema.safeParse(frontmatter.data);

    if (!safeData.success) {
      console.error(safeData.error.errors);
      continue;
    }

    if (!safeData.data.published && process.env.NODE_ENV !== "development")
      continue;

    posts.push({
      ...safeData.data,
      slug: fileName.replace(/^\d+-/, "").replace(".mdx", ""),
      content: frontmatter.content,
    });
  }

  return posts;
};

export const getPost = async (slug: string) => {
  const posts = await getPosts();
  return posts.find((post) => post.slug === slug);
};
Philippine CrocodileOP
I can't try it for now, I'll tell you when I can, which result I get
Philippine CrocodileOP
Without using these functions, it works with slug
Philippine CrocodileOP
I found the error, the error is in the Mdx component

import { MDXRemote } from "next-mdx-remote-client/rsc";
import { MDX_COMPONENTS } from "./mdx-components";
import { rehypePlugin } from "./mdx-plugin";
import { Suspense } from "react";

export const Mdx = ({ children }: { children: string }) => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <MDXRemote
        source={children}
        options={{ mdxOptions: { rehypePlugins: rehypePlugin } }}
        components={MDX_COMPONENTS}
      />
    </Suspense>
  );
};

import { MdxYouTube } from "./MdxYouTube";

export const MDX_COMPONENTS = {
  YouTube: MdxYouTube,
};

import { YouTubeEmbed } from "@next/third-parties/google";

export const MdxYouTube = ({
  id,
  description,
}: {
  id: string;
  description?: string;
}) => {
  return (
    <div>
      <YouTubeEmbed videoid={id} />
      <p className="text-xs text-muted-foreground">{description}</p>
    </div>
  );
};
The post in mdx
Philippine CrocodileOP
because I tried without calling the mdx component and it worked on vercel but not with the mdx component
the mdx component seems to call something that is not correct imo
@B33fb0n3 why do you think it's the mdx component?
Philippine CrocodileOP
so I found that but I don't know what can cause this issue
@Philippine Crocodile so I found that but I don't know what can cause this issue
I think it's more this line
const fileContents = await fs.readFile(fullPath, "utf-8");

that causes the timeout. I guess the reading is just to slow (or serving is to slow) and then the function times out.

Can you create some logging how long what kind of part from your app takes? With some console.logs and they contain a time. Maybe substract these times to calculate a relative time instead of an absolute time...
Philippine CrocodileOP
I don't think so because the title appears but the content don't appear
I added a Suspense to show the page without make the page crash
My Suspense don't prevent the crash lol
@Philippine Crocodile My Suspense don't prevent the crash lol
Can you share the error from your server console?

Also can you do this:
Can you create some logging how long what kind of part from your app takes? With some console.logs and they contain a time. Maybe substract these times to calculate a relative time instead of an absolute time...
Philippine CrocodileOP
Where do you want me to put the logs? before what and after what?
@B33fb0n3 before and after this line: https://github.com/ItsMeViipeR/nextlevel-tech/blob/main/app/posts/%5Bslug%5D/page.tsx#L7
Philippine CrocodileOP
I can't see the logs because i'm in a client component
@B33fb0n3 then check your server logs
Philippine CrocodileOP
@Philippine Crocodile Click to see attachment
can you show how you implemented the calculation of the time?
Philippine CrocodileOP
With performance.now()
Philippine CrocodileOP
@B33fb0n3 is it good?
@Philippine Crocodile With `performance.now()`
can you share the full code how you implemented the calculation of the time?
@B33fb0n3 can you share the full code how you implemented the calculation of the time?
Philippine CrocodileOP
const startTime = performance.now();
const post = await getPost(props.params.slug);
const endTime = performance.now();
console.log(`getPostDuration: ${endTime - startTime}ms`);
@B33fb0n3 thanks for sharing. Can you share the error from your server console? https://discord.com/channels/752553802359505017/1290001687414575231/1290238342297817132 (<----- click this)
Philippine CrocodileOP
all I have in the logs is this
@Philippine Crocodile all I have in the logs is this
now start your server and open the dev tools (F12). Then click on "performance". Then click this little icon on the top left (see attached). Wait a moment. Now check the results and take a look at which part is the biggest (see attached for an example). Now go into that part of your page and check why it takes so long to load
@Philippine Crocodile Click to see attachment
it looks like the content of the page takes to long to load and like that the timeout happens. That can happen thought the LCP (Largest Contentful Paint) an image that will be loaded or also the content itself (or both). So make sure to server your content thought a CDN. Do that for you content as well as your image
@Philippine Crocodile a suspense with a loading component isn't enough?
no and it will never, because the stuff the browser need to download will stay the same. With or without suspense
@B33fb0n3 no and it will never, because the stuff the browser need to download will stay the same. With or without suspense
Philippine CrocodileOP
so can you send me an example code with my code for what you're telling me about?

import { MDXRemote } from "next-mdx-remote-client/rsc";
import { MDX_COMPONENTS } from "./mdx-components";
import { rehypePlugin } from "./mdx-plugin";
import { Suspense } from "react";

export const Mdx = ({ children }: { children: string }) => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <MDXRemote
        source={children}
        options={{ mdxOptions: { rehypePlugins: rehypePlugin } }}
        components={MDX_COMPONENTS}
      />
    </Suspense>
  );
};
@Philippine Crocodile I don't really understand what you want me to do
I want you to make sure to serve your content thought a CDN. Do that for you content, as well as your images
@Philippine Crocodile the files that are in ./content?
the files that you are trying to load, yes
@B33fb0n3 the files that you are trying to load, yes
Philippine CrocodileOP
the files are loaded 'cause on /posts i can access to the names and descriptions
@Philippine Crocodile the files are loaded 'cause on `/posts` i can access to the names and descriptions
Yea, but you need to serve them correctly via a CDN.
Philippine CrocodileOP
how can I get files from cdn?
@Philippine Crocodile how can I get files from cdn?
you can select any CDN service you like and enter your origin url there. Then you get a CDN url. With that CDN Url you can get your files. For example like:
https://yourcdn.com/yourpicture.png
https://yourcdn.com/yourcontent.mdx
https://yourcdn.com/yourvideo.mp4
@Philippine Crocodile it'll work for my mdx posts?
it will work for every file
Philippine CrocodileOP
okay thanks I'll try it at home
Philippine CrocodileOP
I don’t really understand why using a cdn to store my posts will fix the issue because the issue don’t come from the post but from the mdx parsing
@Philippine Crocodile I don’t really understand why using a cdn to store my posts will fix the issue because the issue don’t come from the post but from the mdx parsing
This thread takes me so much energy. I guess you got everything that you need. Just to let you know: I won’t answer this thread anymore