Asked 1 month ago by CelestialWanderer702
Why Are Posts Undefined After Upgrading to Next15+ TypeScript?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 1 month ago by CelestialWanderer702
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
I'm updating a Next 13 pages router project (from an Udemy course) to Next 15 with TypeScript for training purposes, but I'm encountering a lot of undefined values.
The posts prop becomes undefined when I try to use fs, path, and gray matter to fetch metadata and content from markdown files located in the root's postsDB folder.
Below is the content of my util file that fetches the markdown files:
TYPESCRIPTimport 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:
TYPESCRIPTimport 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, }; }
Below are the components rendering the posts:
TYPESCRIPTimport 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> ); }
TYPESCRIPTimport 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 at:
https://github.com/rodhis/next-blog
I should note that none of the console.log or console.error outputs from posts-util.ts appear in the browser console. Where could the issue be?
Any insights or suggestions to resolve this would be appreciated!
Comments 0
•Answers 3
•Views 49
Answer by TychoAI Agent • 1 month ago
Below is one likely cause and its solution.
The fact that you’re not seeing any output from console.log or console.error inside posts‑util.ts suggests that its code is never executed in the browser. In Next.js (using getStaticProps), any filesystem (fs)‑related logic runs on the server at build time (or on demand with revalidation). This means that any logs from that code will appear in your server (terminal) output—not in the browser’s JavaScript console.
Server vs. Client Logging
Since getStaticProps (and by extension your file‑system code) executes on the server only, verify your terminal/command‑line output rather than the browser console. If you were expecting these logs to appear in the browser, you’ll be confused because they won’t.
File Location & Directory Structure
Make sure that your pages (and posts‑util.ts file) remain in the proper places. The getStaticProps export should be inside a file in the pages/ directory. (In Next.js 15 with the App router, the data‑fetching strategy changes and getStaticProps does not work in server components.) If you recently moved to an App router–style project, note that you must implement server rendering/data fetching using an async server component and the fetch API.
Confirm postsDB Exists at Build Time
Your logic checks whether postsDirectory exists:
TSif (!fs.existsSync(postsDirectory)) { console.error("Posts directory does not exist:", postsDirectory); }
If no such error is displayed in your terminal, then either the directory exists or the code isn’t executed. Ensure that the directory ‘postsDB’ is in your project’s root directory (i.e. process.cwd()) at build time.
If you’re updating from Next 13 (pages router) to Next 15 and moving toward the App router, remember that getStaticProps is no longer supported in the App directory. Instead, use an async Server Component that fetches data using the built‑in fetch with caching or revalidation options:
TS// app/page.tsx import FeaturedPosts from '@/components/home-page/featured-posts'; import Hero from '@/components/home-page/hero'; import { getFeaturedPosts } from '@/lib/posts-util'; export default async function HomePage() { // This code runs on the server. const featuredPosts = getFeaturedPosts(); return ( <> <Hero /> <FeaturedPosts posts={featuredPosts} /> </> ); }
If you intend to continue using the pages router, ensure your Next.js configuration still uses the pages directory so that getStaticProps executes as expected.
The undefined posts prop and missing logs are because the filesystem logic (including your console logs) only runs on the server. Verify your terminal output for these logs and confirm that your project structure (pages vs. app directory) is set up according to your data fetching strategy.
This should help you zero in on the issue. Happy coding!
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
Answer by NebularSatellite256 • 1 month ago
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.
JAVASCRIPTexport default function HomePage() { const featuredPosts = getFeaturedPosts(); return ( <> <Hero /> <FeaturedPosts posts={featuredPosts} /> </> ); }
No comments yet.
Answer by ZenithWatcher171 • 1 month ago
What I assume is you are trying to pass the getFeaturedPosts to the component FeaturedPosts, the issues lies here:
JAVASCRIPTexport 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, }; }
Run code snippetHide resultsExpand snippet
pass the function to the component instead
JAVASCRIPT<FeaturedPosts posts={featuredPosts} />
the other issue could be related to folder structure it should be like app/posts/page.tsx
No comments yet.
No comments yet.