最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Next 15 + TS project update returning undefineds - Stack Overflow

programmeradmin1浏览0评论

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:

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?

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/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?

Share Improve this question asked Feb 4 at 20:40 RodhisRodhis 392 silver badges8 bronze badges 5
  • On the HomePage you're not awaiting the getFeaturedPosts inside getStaticProps – Silviu Glavan Commented Feb 4 at 20:56
  • Silviu Glavan, that made no difference. – Rodhis Commented Feb 4 at 21:06
  • I had a look at GitHub, and the folder structure is off. In order to use the "pages router" you need to put your files in a pages folder. so the folder structure will look like this /src/pages/index.tsx, here's the docs: nextjs./docs/pages/getting-started/project-structure – Silviu Glavan Commented Feb 4 at 21:13
  • I'm actually trying to port this project to App Router, and I just read you can't use getStaticProps on App Router... What should I do instead? – Rodhis Commented Feb 4 at 21:17
  • Yes the app router does not have that, take a look at generateStaticParams here : nextjs./docs/app/building-your-application/data-fetching/… – Marianne Commented Feb 4 at 21:49
Add a comment  | 

2 Answers 2

Reset to default 0

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} />
    </>
  );
}

What I assume is you are trying to pass the getFeaturedPosts to the component FeaturedPosts, the issues lies here:

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,
  };
}

pass the function to the component instead

 <FeaturedPosts posts={featuredPosts} />

the other issue could be related to folder structure it should be like app/posts/page.tsx

发布评论

评论列表(0)

  1. 暂无评论