next.jsnextjs-dynamic-routing

nextjs 14 app router render dynamic data on /blog page


I am creating a blog using next.js 14 App router. where I am facing issue rendering index page dynamically. here is my code

app/blog/page.tsx

import BlogItem from "@/components/Blog/BlogItem";
import GhostAPI from "@/lib/ghost";


async function getPosts() {
  return await GhostAPI.posts
      .browse({
          limit: "all",
          include: "tags,authors",
          filter: 'status:published'
      })
      .catch(err => {
          console.error("GHOST ERROR", err);
      });
}


const BlogPage = async () => {
  const posts = await getPosts();
  return (
    <>
        <div className="mx-auto my-10 max-w-c-1280 px-4 md:px-8 xl:px-0">
          <div className="grid grid-cols-1 gap-7.5 md:grid-cols-2 lg:grid-cols-3 xl:gap-10">
            {posts.map((post, key) => (
              <BlogItem key={key} post={post} />
            ))}
          </div>
        </div>
    </>
  );
};

export default BlogPage;

this works correctly, it can list the blog post from the ghost cms api, but the problem is when I update the title of the post or publishes new post on ghost cms I need to rebuild the project in order to see the changes or new post respectively.

I studied the that revalidate can revalidate data every 60 second.

export const revalidate = 60

but I think there should be better way to render the dynamic data on server component dynamically.


Solution

  • If you want your page to be dynamic, add export const dynamic = "force-dynamic" at the top, like so:

    export const dynamic = "force-dynamic";
    
    import BlogItem from "@/components/Blog/BlogItem";
    import GhostAPI from "@/lib/ghost";
    
    
    async function getPosts() {
      return await GhostAPI.posts
          .browse({
              limit: "all",
              include: "tags,authors",
              filter: 'status:published'
          })
          .catch(err => {
              console.error("GHOST ERROR", err);
          });
    }
    
    
    const BlogPage = async () => {
      const posts = await getPosts();
      return (
        <>
            <div className="mx-auto my-10 max-w-c-1280 px-4 md:px-8 xl:px-0">
              <div className="grid grid-cols-1 gap-7.5 md:grid-cols-2 lg:grid-cols-3 xl:gap-10">
                {posts.map((post, key) => (
                  <BlogItem key={key} post={post} />
                ))}
              </div>
            </div>
        </>
      );
    };
    
    export default BlogPage;