I'm trying to update a next 13 pages router project to next 15 + typescript just for training purposes, but I'm getting a lot of undefineds.
This project is somewhat famous from an Udemy Course. I'm getting the posts prop as undefined when trying to use fs, path and gray matter to get metadata and text from an markdown file inside root/postsDB.
This is the util file with the functions that fetch the md files:
posts-util.ts
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
const postsDirectory = path.join(process.cwd(), 'postsDB');
console.log("Posts directory path:", postsDirectory);
if (!fs.existsSync(postsDirectory)) {
console.error("Posts directory does not exist:", postsDirectory);
}
function getPostData(fileName: string) {
const filePath = path.join(postsDirectory, fileName);
const fileContent = fs.readFileSync(filePath, 'utf-8');
const { data, content } = matter(fileContent);
const postSlug = fileName.replace(/\.md$/, '');
const postData = {
slug: postSlug,
date: data.date,
isFeatured: data.isFeatured || false,
...data,
content,
};
return postData;
}
export function getAllPosts() {
const postFiles = fs.readdirSync(postsDirectory);
console.log("Post files:", postFiles);
const allPosts = postFiles.map(postFile => {
return getPostData(postFile);
});
console.log("All posts:", allPosts);
const sortedPosts = allPosts.sort((postA, postB) => (postA.date > postB.date ? -1 : 1));
return sortedPosts;
}
export function getFeaturedPosts() {
const allPosts = getAllPosts();
console.log("All posts in getFeaturedPosts:", allPosts);
const featuredPosts = allPosts.filter(post => post.isFeatured);
console.log("Featured posts:", featuredPosts);
return featuredPosts;
}
This is the index.tsx (HomePage) file
import FeaturedPosts from "@/components/home-page/featured-posts";
import Hero from "@/components/home-page/hero";
import { Post } from "@/interfaces/Post";
import { getFeaturedPosts } from "@/lib/posts-util";
interface HomePageProps {
posts: Post[];
}
export default function HomePage({ posts }: HomePageProps) {
console.log("HomePage posts:", posts);
return (
<>
<Hero />
<FeaturedPosts posts={posts} />
</>
);
}
export async function getStaticProps() {
console.log("getStaticProps called");
const featuredPosts = getFeaturedPosts();
console.log("Featured posts in getStaticProps:", featuredPosts); // Debugging line
return {
props: {
posts: featuredPosts,
},
revalidate: 1800,
};
}
And these are components that render the posts.
posts-grid.tsx
import PostItem from "./post-item";
import { Post } from "@/interfaces/Post";
import styles from "@/styles/posts-grid.module.css";
interface PostsGridProps {
posts: Post[];
}
export default function PostsGrid({ posts = [] }: PostsGridProps) {
return (
<ul className={styles.grid}>
{posts.map(post => (
<PostItem key={post.slug} post={post} />
))}
</ul>
);
}
featured-posts.tsx
import PostsGrid from "../posts/posts-grid";
import { Post } from "@/interfaces/Post";
import styles from "@/styles/featured-posts.module.css";
interface FeaturedPostsProps {
posts: Post[];
}
export default function FeaturedPosts({ posts }: FeaturedPostsProps) {
console.log("FeaturedPosts posts:", posts);
return (
<section className={styles.latest}>
<h2>Featured Posts</h2>
<PostsGrid posts={posts} />
</section>
);
}
The full project can be found here:
https://github.com/rodhis/next-blog
I think it's important to say that no console.log and console.error from posts-util.ts are appearing on the console!
Can anyone say what's wrong?
Using App Router you can't use getStaticProps. You have 2 ways:
1- directly use server-side operations
2- access via API and fetch()
I used the first one and it worked.
export default function HomePage() {
const featuredPosts = getFeaturedPosts();
return (
<>
<Hero />
<FeaturedPosts posts={featuredPosts} />
</>
);
}