diff --git a/src/app/(site)/app/components/feed/index.tsx b/src/app/(site)/app/components/feed/index.tsx
index c9e812f..c33a748 100644
--- a/src/app/(site)/app/components/feed/index.tsx
+++ b/src/app/(site)/app/components/feed/index.tsx
@@ -1,43 +1,85 @@
-import { getSuapabaseServerComponent } from "@/supabase/models/index.models";
+"use client";
+
 import { Heading } from "@/components/ui/typography/heading";
-import { PostsGrid } from "@/components/feature/posts-grid";
-import { Suspense } from "react";
-import { Skeleton } from "@/components/ui/skeleton";
+import { useEffect, useState } from "react";
+import { useSupabase } from "@/hooks/use-supabase";
+import { Database } from "@/supabase/types";
+import { PostsGrid } from "@/components/feature/posts-grid/posts-grid.component";
+import { PostsGridSkeleton } from "@/components/feature/posts-grid/components/posts-grid-skeleton";
+
+export function Feed() {
+  const { supabase } = useSupabase();
+
+  const [posts, setPosts] = useState<
+    Database["public"]["Tables"]["posts"]["Row"][]
+  >([]);
+
+  const [error, setError] = useState<boolean>(false);
+
+  const [isLoading, setIsLoading] = useState<boolean>(true);
+  const [isFetching, setIsFetching] = useState<boolean>(false);
+
+  const [lastPostIndex, setLastPostIndex] = useState<number>(1);
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    try {
+      setIsLoading(true);
+      setIsFetching(true);
+
+      supabase
+        .from("posts")
+        .select("*")
+        .order("id", { ascending: false })
+        .limit(32)
+        .range(lastPostIndex, lastPostIndex + 32)
+        .abortSignal(controller.signal)
+        .then(({ data: posts, error }) => {
+          if (error) return;
+
+          if (!posts) return;
+
+          setPosts((prev) => [...prev, ...posts]);
+        });
+    } catch (error: unknown) {
+      if ((error as Error).name === "AbortError") return;
+
+      setError(true);
+    } finally {
+      setIsLoading(false);
+      setIsFetching(false);
+    }
 
-export async function Feed() {
-  const supabase = await getSuapabaseServerComponent();
+    return () => {
+      controller.abort();
+    };
 
-  const { data: posts, error } = await supabase
-    .from("posts")
-    .select("*")
-    .order("id", { ascending: false })
-    .limit(24);
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [lastPostIndex]);
 
-  const doesPostsExist = posts && posts.length > 0 && !error;
+  function handleScroll() {
+    setLastPostIndex((prev) => prev + 32);
+  }
 
   return (
-    <>
-      {doesPostsExist ? (
-        <main className="w-full h-full px-2">
-          <Suspense
-            fallback={
-              <ul className="break-inside-avoid gap-2 px-2 [column-count:3] md:[column-count:3]">
-                {Array(16)
-                  .fill(" ")
-                  .map((_, i) => (
-                    <Skeleton key={i} className="w-full h-96 mb-2" />
-                  ))}
-              </ul>
-            }
-          >
-            <PostsGrid posts={posts} />
-          </Suspense>
-        </main>
-      ) : (
-        <article className="flex items-center justify-center w-full max-h-96 py-16 text-center border-y border-neutral-300">
-          <Heading level={7}>Something wen wrong, reload the page</Heading>
-        </article>
+    <main className="w-full h-full flex flex-col gap-2">
+      {isLoading && <PostsGridSkeleton cuantity={32} />}
+      {!isLoading && !isFetching && (
+        <>
+          {!error ? (
+            <div>
+              <PostsGrid posts={posts} onFetchNewPosts={handleScroll} />
+            </div>
+          ) : (
+            <article className="flex items-center justify-center w-full max-h-96 py-32 text-center border-y border-neutral-300">
+              <Heading level={10}>
+                Something wen wrong, please reload the page
+              </Heading>
+            </article>
+          )}
+        </>
       )}
-    </>
+    </main>
   );
 }
diff --git a/src/app/(site)/app/layout.tsx b/src/app/(site)/app/layout.tsx
index 0593fc6..2c82e52 100644
--- a/src/app/(site)/app/layout.tsx
+++ b/src/app/(site)/app/layout.tsx
@@ -13,7 +13,7 @@ export default function AppLayout({ children }: { children: ReactNode }) {
         <div className="md:hidden w-full flex fixed left-0 bottom-0 z-50">
           <MobileNavMenu />
         </div>
-        <div className="h-full w-full min-h-screen border-x border-neutral-300 dark:border-cm-lighter-gray">
+        <div className="h-full px-2 w-full min-h-screen border-x border-neutral-300 dark:border-cm-lighter-gray">
           {children}
         </div>
         <SyncTheme />
diff --git a/src/app/(site)/app/page.tsx b/src/app/(site)/app/page.tsx
index 870165c..270338d 100644
--- a/src/app/(site)/app/page.tsx
+++ b/src/app/(site)/app/page.tsx
@@ -21,22 +21,8 @@ export default function AppPage() {
 
 function DesktopLayout() {
   return (
-    <main className="w-full h-full flex flex-col justify-start py-2">
-      <Suspense
-        fallback={
-          <ul className="w-full flex flex-wrap gap-2">
-            {Array(8)
-              .fill("")
-              .map((_, i) => (
-                <li key={i}>
-                  <Skeleton className="w-full bg-red-500 rounded-md h-[500px]" />
-                </li>
-              ))}
-          </ul>
-        }
-      >
-        <Feed />
-      </Suspense>
+    <main className="w-full h-full flex flex-col justify-start">
+      <Feed />
     </main>
   );
 }
diff --git a/src/app/(site)/app/post/[postid]/components/post/components/options/index.tsx b/src/app/(site)/app/post/[postid]/components/post/components/options/index.tsx
index c36b1fc..f4c24e1 100644
--- a/src/app/(site)/app/post/[postid]/components/post/components/options/index.tsx
+++ b/src/app/(site)/app/post/[postid]/components/post/components/options/index.tsx
@@ -45,7 +45,6 @@ export function PostOptions({
               return router.push("/app"); // Navigate to '/app' if no history
             }
           }
-          router.refresh();
         } catch (e) {
           console.log(e);
         }
diff --git a/src/app/(site)/app/post/[postid]/components/post/index.tsx b/src/app/(site)/app/post/[postid]/components/post/index.tsx
index e594e6e..b09c154 100644
--- a/src/app/(site)/app/post/[postid]/components/post/index.tsx
+++ b/src/app/(site)/app/post/[postid]/components/post/index.tsx
@@ -22,48 +22,47 @@ export async function Post({
     .single();
 
   return (
-    <article className="w-full h-full flex lg:gap-4 gap-2 flex-col-reverse lg:flex-row-reverse items-start justify-end bg-neutral-200 dark:bg-neutral-900 overflow-hidden">
-      <header className="flex items-center justify-between w-96">
-        <section className="w-full flex flex-col items-start justify-center gap-4">
-          <PostOptions
-            post_id={post.id}
-            doesUserOwnPost={doesUserOwnPost}
-            image_url={post.asset_url}
-          />
-          <h3 className="w-full text-neutral-800 dark:text-neutral-300 font-bold text-2xl">
-            {title}
-          </h3>
-          {postOwnerProfile && (
-            <Link
-              href={`/app/profile/${postOwnerProfile.username}`}
-              className="w-full"
-            >
-              <section className="flex flex-none gap-4 w-full items-center justify-start">
-                {postOwnerProfile.avatar_url ? (
-                  <LazyImage
-                    src={postOwnerProfile.avatar_url}
-                    alt={post.title}
-                    className="w-12 h-12 rounded-full object-cover object-center flex-0"
-                    skeletonClassName="w-12 h-12 rounded-full"
-                    width={48}
-                    height={48}
-                  />
-                ) : (
-                  <div className="h-12 w-12 rounded-full bg-neutral-300" />
-                )}
-                <h3 className="text-neutral-800 dark:text-neutral-300 font-semibold text-xl">
-                  {postOwnerProfile.name}
-                </h3>
-              </section>
-            </Link>
-          )}
-        </section>
+    <article className="w-full h-full flex flex-col-reverse gap-2 items-start justify-end bg-neutral-200 dark:bg-neutral-900">
+      <header className="flex flex-col items-start justify-center gap-2 w-max xl:min-w-64 min-w-full">
+        <h3 className="w-full text-neutral-800 dark:text-neutral-300 font-bold text-2xl">
+          {title}
+        </h3>
+        {postOwnerProfile && (
+          <Link
+            href={`/app/profile/${postOwnerProfile.username}`}
+            className="w-full"
+          >
+            <section className="flex gap-2 w-full justify-start items-center">
+              {postOwnerProfile.avatar_url ? (
+                <LazyImage
+                  src={postOwnerProfile.avatar_url}
+                  alt={post.title}
+                  className="w-12 h-12 rounded-full object-cover object-center flex-0"
+                  skeletonClassName="w-12 h-12 rounded-full"
+                  width={48}
+                  height={48}
+                />
+              ) : (
+                <div className="h-12 w-12 rounded-full bg-neutral-300" />
+              )}
+              <h3 className="text-neutral-800 dark:text-neutral-300 font-semibold text-xl">
+                {postOwnerProfile.name}
+              </h3>
+            </section>
+          </Link>
+        )}
+        <PostOptions
+          post_id={post.id}
+          doesUserOwnPost={doesUserOwnPost}
+          image_url={post.asset_url}
+        />
       </header>
       <LazyImage
         src={asset_url}
         alt={title}
-        className="w-full h-full max-h-[100vh] lg:max-h-[80vh] object-cover object-center rounded-md"
-        skeletonClassName="w-full"
+        className="w-full h-full max-h-[80vh] object-cover object-center rounded-md"
+        skeletonClassName="w-full h-96 rounded-md"
+        containerClassname="w-full"
         skeletonBgColor={post.asset_color || undefined}
       />
     </article>
diff --git a/src/app/(site)/app/post/[postid]/components/recent-posts/index.ts b/src/app/(site)/app/post/[postid]/components/recent-posts/index.ts
new file mode 100644
index 0000000..04da9a5
--- /dev/null
+++ b/src/app/(site)/app/post/[postid]/components/recent-posts/index.ts
@@ -0,0 +1 @@
+export * from "./recent-pots.component";
diff --git a/src/app/(site)/app/post/[postid]/components/recent-posts/recent-pots.component.tsx b/src/app/(site)/app/post/[postid]/components/recent-posts/recent-pots.component.tsx
new file mode 100644
index 0000000..9902630
--- /dev/null
+++ b/src/app/(site)/app/post/[postid]/components/recent-posts/recent-pots.component.tsx
@@ -0,0 +1,93 @@
+"use client";
+
+import { PostsGridSkeleton } from "@/components/feature/posts-grid/components/posts-grid-skeleton";
+import { PostsGrid } from "@/components/feature/posts-grid/posts-grid.component";
+import { Heading } from "@/components/ui/typography/heading";
+import { useSupabase } from "@/hooks/use-supabase";
+import { Database } from "@/supabase/types";
+import { useEffect, useState } from "react";
+
+export function RecentPosts({
+  excludedPostId,
+}: {
+  excludedPostId: Database["public"]["Tables"]["posts"]["Row"]["id"];
+}) {
+  const [posts, setPosts] = useState<
+    Database["public"]["Tables"]["posts"]["Row"][]
+  >([]);
+
+  const [isLoading, setIsLoading] = useState<boolean>(true);
+  const [isFetching, setIsFetching] = useState<boolean>(false);
+
+  const [lastPostIndex, setLastPostIndex] = useState<number>(1);
+  const [error, setError] = useState<boolean>(false);
+
+  const { supabase } = useSupabase();
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    try {
+      setIsLoading(true);
+      setIsFetching(true);
+
+      supabase
+        .from("posts")
+        .select("*")
+        .order("created_at", { ascending: false })
+        .limit(32)
+        .range(lastPostIndex, lastPostIndex + 32)
+        .abortSignal(controller.signal)
+        .then(({ data: posts, error }) => {
+          if (error) return;
+
+          if (!posts) return;
+
+          setPosts((prev) => [
+            ...prev,
+            ...posts.filter((post) => post.id !== excludedPostId),
+          ]);
+        });
+    } catch (error: unknown) {
+      if ((error as Error).name === "AbortError") return;
+
+      setError(true);
+    } finally {
+      setIsLoading(false);
+      setIsFetching(false);
+    }
+
+    return () => {
+      controller.abort();
+    };
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [lastPostIndex]);
+
+  function handleScroll() {
+    if (isLoading || isFetching) return;
+
+    setLastPostIndex((prev) => prev + 32);
+  }
+
+  return (
+    <section>
+      {isLoading && <PostsGridSkeleton cuantity={32} />}
+      {!isLoading && !isFetching && (
+        <>
+          {!error ? (
+            <div>
+              <PostsGrid posts={posts} onFetchNewPosts={handleScroll} />
+            </div>
+          ) : (
+            <article className="flex items-center justify-center w-full max-h-96 py-32 text-center border-y border-neutral-300">
+              <Heading level={10}>
+                Something wen wrong, please reload the page
+              </Heading>
+            </article>
+          )}
+        </>
+      )}
+    </section>
+  );
+}
diff --git a/src/app/(site)/app/post/[postid]/page.tsx b/src/app/(site)/app/post/[postid]/page.tsx
index b35b0d1..898380d 100644
--- a/src/app/(site)/app/post/[postid]/page.tsx
+++ b/src/app/(site)/app/post/[postid]/page.tsx
@@ -1,9 +1,8 @@
 import { BackwardsNav } from "@/components/feature/nav/backwards";
 import { Heading } from "@/components/ui/typography/heading";
 import { getSuapabaseServerComponent } from "@/supabase/models/index.models";
-import { PostsGrid } from "@/components/feature/posts-grid";
-import { Database } from "@/supabase/types";
 import { Post } from "./components/post";
+import { RecentPosts } from "./components/recent-posts";
 
 export default async function PostPage({
   params: { postid },
@@ -28,15 +27,15 @@ export default async function PostPage({
   );
 
   return (
-    <div className="flex flex-col gap-2 px-2 pb-10">
-      <nav className="w-full py-2 flex items-center gap-4 border-b border-neutral-300 dark:border-cm-lighter-gray">
+    <div className="flex flex-col py-2 gap-2 pb-10">
+      <nav className="w-full flex items-center gap-4 pb-2 border-b border-neutral-300 dark:border-cm-lighter-gray">
         <BackwardsNav catchHref="/app" />
         <Heading level={9}>Back</Heading>
       </nav>
       {postData && !postError ? (
-        <section className="p-y2 flex flex-col gap-2">
+        <section className="flex flex-col gap-2">
           <Post post={postData} doesUserOwnPost={doesUserOwnPost} />
-          <RecentPosts excludePost={postData} />
+          <RecentPosts excludedPostId={postData.id} />
         </section>
       ) : (
         <Error404Box />
@@ -45,31 +44,6 @@ export default async function PostPage({
   );
 }
 
-async function RecentPosts({
-  excludePost,
-}: {
-  excludePost: Database["public"]["Tables"]["posts"]["Row"];
-}) {
-  const supabase = await getSuapabaseServerComponent();
-
-  const { data: posts, error } = await supabase
-    .from("posts")
-    .select("*")
-    .order("created_at", { ascending: false })
-    .limit(9);
-
-  if (!posts || posts.length === 0) return;
-
-  const filteredPosts = posts.filter((post) => post.id !== excludePost.id);
-  return (
-    <>
-      {!error &&
-        filteredPosts.length !== undefined &&
-        filteredPosts.length > 0 && <PostsGrid posts={filteredPosts} />}
-    </>
-  );
-}
-
 function Error404Box() {
   return (
     <div className="w-full flex flex-col gap-2 items-center justify-center py-32 border-y border-neutral-300 dark:border-cm-lighter-gray">
diff --git a/src/app/(site)/app/profile/[username]/components/user-posts/index.ts b/src/app/(site)/app/profile/[username]/components/user-posts/index.ts
new file mode 100644
index 0000000..b5e137b
--- /dev/null
+++ b/src/app/(site)/app/profile/[username]/components/user-posts/index.ts
@@ -0,0 +1 @@
+export * from "./user-posts.component";
diff --git a/src/app/(site)/app/profile/[username]/components/user-posts/user-posts.component.tsx b/src/app/(site)/app/profile/[username]/components/user-posts/user-posts.component.tsx
new file mode 100644
index 0000000..d2e0caf
--- /dev/null
+++ b/src/app/(site)/app/profile/[username]/components/user-posts/user-posts.component.tsx
@@ -0,0 +1,92 @@
+"use client";
+
+import { PostsGridSkeleton } from "@/components/feature/posts-grid/components/posts-grid-skeleton";
+import { PostsGrid } from "@/components/feature/posts-grid/posts-grid.component";
+import { Heading } from "@/components/ui/typography/heading";
+import { useSupabase } from "@/hooks/use-supabase";
+import { Database } from "@/supabase/types";
+import { useEffect, useState } from "react";
+
+export function UserPosts({ profileId }: { profileId: string }) {
+  const { supabase } = useSupabase();
+
+  const [posts, setPosts] = useState<
+    Database["public"]["Tables"]["posts"]["Row"][]
+  >([]);
+
+  const [error, setError] = useState<boolean>(false);
+
+  const [isLoading, setIsLoading] = useState<boolean>(true);
+  const [isFetching, setIsFetching] = useState<boolean>(false);
+
+  const [lastPostIndex, setLastPostIndex] = useState<number>(1);
+
+  const [userHasNoMorePosts, setUserHasNoMorePosts] = useState<boolean>(false);
+
+  useEffect(() => {
+    if (userHasNoMorePosts) return;
+
+    const controller = new AbortController();
+
+    try {
+      setIsLoading(true);
+      setIsFetching(true);
+
+      supabase
+        .from("posts")
+        .select("*")
+        .eq("profile_id", profileId)
+        .order("id", { ascending: false })
+        .limit(32)
+        .range(lastPostIndex, lastPostIndex + 32)
+        .abortSignal(controller.signal)
+        .then(({ data: posts, error }) => {
+          if (error) return;
+
+          if (!posts) return;
+
+          if (posts.length === 0) setUserHasNoMorePosts(true);
+
+          setPosts((prev) => [...prev, ...posts]);
+        });
+    } catch (error: unknown) {
+      if ((error as Error).name === "AbortError") return;
+
+      setError(true);
+    } finally {
+      setIsLoading(false);
+      setIsFetching(false);
+    }
+
+    return () => {
+      controller.abort();
+    };
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [lastPostIndex]);
+
+  function handleScroll() {
+    setLastPostIndex((prev) => prev + 32);
+  }
+
+  return (
+    <main className="w-full h-full flex flex-col gap-2">
+      {isLoading && <PostsGridSkeleton cuantity={32} />}
+      {!isLoading && !isFetching && (
+        <>
+          {!error ? (
+            <div>
+              <PostsGrid posts={posts} onFetchNewPosts={handleScroll} />
+            </div>
+          ) : (
+            <article className="flex items-center justify-center w-full max-h-96 py-32 text-center border-y border-neutral-300">
+              <Heading level={10}>
+                Something wen wrong, please reload the page
+              </Heading>
+            </article>
+          )}
+        </>
+      )}
+    </main>
+  );
+}
diff --git a/src/app/(site)/app/profile/[username]/page.tsx b/src/app/(site)/app/profile/[username]/page.tsx
index 7d549aa..b8ac5a9 100644
--- a/src/app/(site)/app/profile/[username]/page.tsx
+++ b/src/app/(site)/app/profile/[username]/page.tsx
@@ -1,13 +1,14 @@
+import { CalendarIcon, LinkIcon, MapPinIcon } from "lucide-react";
+import Link from "next/link";
+import { Suspense } from "react";
+
 import { LazyImage } from "@/components/feature/lazy-image";
 import { BackwardsNav } from "@/components/feature/nav/backwards";
-import { PostsGrid } from "@/components/feature/posts-grid";
 import { Skeleton } from "@/components/ui/skeleton";
 import { Heading } from "@/components/ui/typography/heading";
 import { getSuapabaseServerComponent } from "@/supabase/models/index.models";
 import { Database } from "@/supabase/types";
-import { CalendarIcon, LinkIcon, MapPinIcon } from "lucide-react";
-import Link from "next/link";
-import { Suspense } from "react";
+import { UserPosts } from "./components/user-posts";
 
 export default function ProfilePage({
   params: { username },
@@ -36,122 +37,112 @@ async function UserProfile({ username }: { username: string }) {
     data: { user: user },
   } = await supabase.auth.getUser();
 
-  const { data: userPosts } = await supabase
-    .from("posts")
-    .select("*")
-    .eq("user_id", userProfile?.user_id || "")
-    .order("created_at", { ascending: false })
-    .limit(24);
+  return (
+    <div className="w-full h-full">
+      {doesUserProfileExist && userProfile ? (
+        <Profile profile={userProfile} currentUserId={user?.id || ""} />
+      ) : (
+        <UserProfileNotFound />
+      )}
+    </div>
+  );
+}
 
-  function Profile({
-    data,
-    userId,
-    userPosts,
-  }: {
-    data: Database["public"]["Tables"]["profiles"]["Row"];
-    userId: Database["public"]["Tables"]["users"]["Row"]["id"];
-    userPosts: Database["public"]["Tables"]["posts"]["Row"][];
-  }) {
-    const dateWhenUserJoined = data.created_at
-      ? new Date(data.created_at).getFullYear()
-      : null;
+function UserProfileNotFound() {
+  return <>404</>;
+}
 
-    return (
-      <div className="flex flex-col gap-4 pt-4">
-        <nav className="w-full flex gap-2 px-2">
-          <BackwardsNav catchHref="/app" />
-          <div className="w-full flex items-center justify-center px-2">
-            <Heading level={9}>{data?.name}</Heading>
-          </div>
-        </nav>
-        <header>
-          <div className="w-full relative mb-16">
+function Profile({
+  profile,
+  currentUserId,
+}: {
+  profile: Database["public"]["Tables"]["profiles"]["Row"];
+  currentUserId: Database["public"]["Tables"]["users"]["Row"]["id"];
+}) {
+  const dateWhenUserJoined = profile.created_at
+    ? new Date(profile.created_at).getFullYear()
+    : null;
+
+  return (
+    <div className="flex flex-col gap-4 pt-4">
+      <nav className="w-full flex gap-2 px-2">
+        <BackwardsNav catchHref="/app" />
+        <div className="w-full flex items-center justify-center px-2">
+          <Heading level={9}>{profile?.name}</Heading>
+        </div>
+      </nav>
+      <header>
+        <div className="w-full relative mb-16">
+          <div className="h-56 w-full">
             <LazyImage
-              src={data?.banner_url ?? ""}
+              src={profile?.banner_url ?? ""}
               className="w-full h-56 object-cover object-center"
               skeletonClassName="w-full h-56"
-              alt={data.name || data.username || ""}
+              alt={profile.name || profile.username || ""}
+            />
+          </div>
+          <div className="w-32 h-32 rounded-full overflow-hidden absolute -bottom-[25%] left-8 border-[2px] border-neutral-50 dark:border-cm-darker-gray">
+            <LazyImage
+              src={profile?.avatar_url ?? ""}
+              className="w-full h-full object-cover object-center"
+              skeletonClassName="w-full h-full"
+              alt={profile.name || profile.username || ""}
             />
-            <div className="w-32 h-32 rounded-full overflow-hidden absolute -bottom-[25%] left-8 border-[2px] border-neutral-50 dark:border-cm-darker-gray">
-              <LazyImage
-                src={data?.avatar_url ?? ""}
-                className="w-full h-full object-cover object-center"
-                skeletonClassName="w-full h-full"
-                alt={data.name || data.username || ""}
-              />
-            </div>
           </div>
-          <article className="flex flex-col gap-2 px-4">
-            <section className="flex justify-between items-center">
-              <div className="flex flex-col justify-between">
-                <Heading level={9}>{data?.name}</Heading>
-                <span className="text-neutral-500">@{data?.username}</span>
+        </div>
+        <article className="flex flex-col gap-2 px-4">
+          <section className="flex justify-between items-center flex-wrap">
+            <div className="flex flex-col justify-between">
+              <Heading level={9}>{profile?.name}</Heading>
+              <span className="text-neutral-500">
+                @{profile?.username ?? "_"}
+              </span>
+            </div>
+            {currentUserId === profile.user_id && (
+              <Link
+                href="/app/settings/section/profile"
+                className="bg-neutral-700 px-6 py-2 rounded-sm text-neutral-300"
+              >
+                Edit Profile
+              </Link>
+            )}
+          </section>
+          {profile?.description && (
+            <p className="w-3/4 text-pretty text-neutral-900 dark:text-neutral-200">
+              {profile.description}
+            </p>
+          )}
+          <section className="flex gap-4 flex-wrap">
+            {profile?.location && (
+              <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
+                <MapPinIcon className="w-4 h-4" />
+                <span>{profile.location}</span>
               </div>
-              {userId === data.user_id && (
-                <Link
-                  href="/app/settings/section/profile"
-                  className="bg-neutral-700 px-6 py-2 rounded-sm text-neutral-300"
+            )}
+            {profile?.website && (
+              <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
+                <LinkIcon className="w-4 h-4" />
+                <a
+                  href={profile.website}
+                  className="text-blue-500 hover:underline"
+                  target="_blank"
                 >
-                  Edit Profile
-                </Link>
-              )}
-            </section>
-            {data?.description && (
-              <p className="w-3/4 text-pretty text-neutral-900 dark:text-neutral-200">
-                {data.description}
-              </p>
+                  {profile.website}
+                </a>
+              </div>
             )}
-            <section className="flex gap-4">
-              {data?.location && (
-                <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
-                  <MapPinIcon className="w-4 h-4" />
-                  <span>{data.location}</span>
-                </div>
-              )}
-              {data?.website && (
-                <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
-                  <LinkIcon className="w-4 h-4" />
-                  <a
-                    href={data.website}
-                    className="text-blue-500 hover:underline"
-                    target="_blank"
-                  >
-                    {data.website}
-                  </a>
-                </div>
-              )}
-              {dateWhenUserJoined && (
-                <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
-                  <CalendarIcon className="w-4 h-4" />
-                  <span>joined in {dateWhenUserJoined}</span>
-                </div>
-              )}
-            </section>
-          </article>
-        </header>
-        {userPosts?.length > 0 && (
-          <div className="px-4">
-            <PostsGrid posts={userPosts} />
-          </div>
-        )}
+            {dateWhenUserJoined && (
+              <div className="flex justify-center items-center gap-2 text-neutral-600 dark:text-neutral-400">
+                <CalendarIcon className="w-4 h-4" />
+                <span>joined in {dateWhenUserJoined}</span>
+              </div>
+            )}
+          </section>
+        </article>
+      </header>
+      <div className="px-2">
+        <UserPosts profileId={profile.id} />
       </div>
-    );
-  }
-  function UserProfileNotFound() {
-    return <>404</>;
-  }
-
-  return (
-    <div className="w-full h-full">
-      {doesUserProfileExist && userProfile ? (
-        <Profile
-          data={userProfile}
-          userId={user?.id || ""}
-          userPosts={userPosts || []}
-        />
-      ) : (
-        <UserProfileNotFound />
-      )}
     </div>
   );
 }
diff --git a/src/app/(site)/app/search/components/SearchForm/SearchForm.tsx b/src/app/(site)/app/search/components/SearchForm/SearchForm.tsx
index c361d8d..a9666e4 100644
--- a/src/app/(site)/app/search/components/SearchForm/SearchForm.tsx
+++ b/src/app/(site)/app/search/components/SearchForm/SearchForm.tsx
@@ -1,46 +1,46 @@
-'use client'
-import { Input } from "@/components/ui/input"
-import { useForm } from "react-hook-form"
-import { useSearchForm } from "./hooks/useSearchForm"
+"use client";
+import { Input } from "@/components/ui/input";
+import { useForm } from "react-hook-form";
+import { useSearchForm } from "./hooks/useSearchForm";
 
 const formInputs = {
-    search: 'search'
-}
+  search: "search",
+};
 
-export type formType = typeof formInputs
+export type formType = typeof formInputs;
 
 interface SearchFormProps {
-    defaultSearchValue: string
+  defaultSearchValue: string;
 }
 
-export const SearchForm: React.FC<SearchFormProps> = ({ defaultSearchValue }) => {
-    const {
-        register
-    } = useForm<formType>()
+export const SearchForm: React.FC<SearchFormProps> = ({
+  defaultSearchValue,
+}) => {
+  const { register } = useForm<formType>();
 
-    const { changeSearchValue } = useSearchForm(defaultSearchValue)
+  const { changeSearchValue } = useSearchForm(defaultSearchValue);
 
-    const handleOnChangeToSearch = (event: React.ChangeEvent<HTMLInputElement>) => {
-        const newValue = event.currentTarget.value
-        changeSearchValue(newValue)
-    }
+  const handleOnChangeToSearch = (
+    event: React.ChangeEvent<HTMLInputElement>,
+  ) => {
+    const newValue = event.currentTarget.value;
+    changeSearchValue(newValue);
+  };
 
-    return (
-        <search>
-                <Input
-                    onInput={handleOnChangeToSearch}
-                    name={formInputs.search}
-                    register={register}
-                    validationScheme={{
-                        required: { value: true, message: "email is required" },
-                    }}
-                    type="text"
-                    id="search-input"
-                    label="Search"
-                    placeholder="cats, dogs ..."
-                    error={undefined}
-                    defaultValue={defaultSearchValue}
-                />
-        </search>
-    )
-}
\ No newline at end of file
+  return (
+    <search>
+      <Input
+        onInput={handleOnChangeToSearch}
+        name={formInputs.search}
+        register={register}
+        validationScheme={{}}
+        type="text"
+        id="search-input"
+        label="Search"
+        placeholder="cats, dogs ..."
+        error={undefined}
+        defaultValue={defaultSearchValue}
+      />
+    </search>
+  );
+};
diff --git a/src/app/(site)/app/search/components/SearchForm/hooks/useSearchForm.ts b/src/app/(site)/app/search/components/SearchForm/hooks/useSearchForm.ts
index 7adc47d..f9909be 100644
--- a/src/app/(site)/app/search/components/SearchForm/hooks/useSearchForm.ts
+++ b/src/app/(site)/app/search/components/SearchForm/hooks/useSearchForm.ts
@@ -1,27 +1,25 @@
-'use client'
-import { useDebounce } from "@/hooks/use-debounce"
-import { useRouting } from "@/hooks/useRouting"
-import { useEffect, useState } from "react"
+"use client";
+import { useDebounce } from "@/hooks/use-debounce";
+import { useRouting } from "@/hooks/useRouting";
+import { useEffect, useState } from "react";
 
 export const useSearchForm = (defaultSearchValue: string) => {
-    const [searchValue, setSearchValue] = useState<string>(defaultSearchValue)
-    const { debouncedValue } = useDebounce(searchValue)
-    const { goTo } = useRouting()
+  const [searchValue, setSearchValue] = useState<string>(defaultSearchValue);
+  const { debouncedValue } = useDebounce(searchValue, 500);
+  const { goTo } = useRouting();
 
-    useEffect(() => {
-        const currentURL = new URL(location.origin + location.pathname)
+  useEffect(() => {
+    const currentURL = new URL(location.origin + location.pathname);
 
-        if (debouncedValue !== '') {
-            currentURL.searchParams.set('search_query', debouncedValue)
-        }
+    currentURL.searchParams.set("search_query", debouncedValue);
 
-        goTo(currentURL.toString())
-        // eslint-disable-next-line react-hooks/exhaustive-deps
-    }, [debouncedValue])
+    goTo(currentURL.toString());
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [debouncedValue]);
 
-    const changeSearchValue = (value: string) => {
-        setSearchValue(value)
-    }
+  const changeSearchValue = (value: string) => {
+    setSearchValue(value);
+  };
 
-    return { valueToSearch: debouncedValue, changeSearchValue }
-}
\ No newline at end of file
+  return { valueToSearch: debouncedValue, changeSearchValue };
+};
diff --git a/src/app/(site)/app/search/components/searched-posts-grid/index.ts b/src/app/(site)/app/search/components/searched-posts-grid/index.ts
new file mode 100644
index 0000000..6c37b1c
--- /dev/null
+++ b/src/app/(site)/app/search/components/searched-posts-grid/index.ts
@@ -0,0 +1 @@
+export * from "./searched-posts-grid.component";
diff --git a/src/app/(site)/app/search/components/searched-posts-grid/searched-posts-grid.component.tsx b/src/app/(site)/app/search/components/searched-posts-grid/searched-posts-grid.component.tsx
new file mode 100644
index 0000000..b65d39f
--- /dev/null
+++ b/src/app/(site)/app/search/components/searched-posts-grid/searched-posts-grid.component.tsx
@@ -0,0 +1,121 @@
+"use client";
+
+import { PostsGridSkeleton } from "@/components/feature/posts-grid/components/posts-grid-skeleton";
+import { PostsGrid } from "@/components/feature/posts-grid/posts-grid.component";
+import { Heading } from "@/components/ui/typography/heading";
+import { useSupabase } from "@/hooks/use-supabase";
+import { Database } from "@/supabase/types";
+import { useEffect, useState } from "react";
+
+export function SearchedPostsGrid({ searchValue }: { searchValue: string }) {
+  const { supabase } = useSupabase();
+
+  const [posts, setPosts] = useState<
+    Database["public"]["Tables"]["posts"]["Row"][]
+  >([]);
+
+  const [error, setError] = useState<boolean>(false);
+
+  const [isLoading, setIsLoading] = useState<boolean>(true);
+  const [isFetching, setIsFetching] = useState<boolean>(false);
+
+  const [lastPostIndex, setLastPostIndex] = useState<number>(1);
+
+  const [notFound, setNotFound] = useState<boolean>(false);
+
+  function getAndSetPosts({ signal }: { signal: AbortSignal }) {
+    try {
+      setIsLoading(true);
+      setIsFetching(true);
+
+      setNotFound(false);
+
+      supabase
+        .from("posts")
+        .select("*")
+        .like("title", `%${searchValue}%`)
+        .order("created_at", { ascending: false })
+        .range(lastPostIndex, lastPostIndex + 32)
+        .abortSignal(signal)
+        .limit(32)
+        .then(({ data: posts, error }) => {
+          if (error) return;
+
+          if (!posts) return;
+
+          if (posts.length === 0) {
+            setNotFound(true);
+            return;
+          }
+          setNotFound(false);
+
+          setPosts((prev) => [...prev, ...posts]);
+        });
+    } catch (error: unknown) {
+      if ((error as Error).name === "AbortError") return;
+
+      setError(true);
+    } finally {
+      setIsLoading(false);
+      setIsFetching(false);
+    }
+  }
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    getAndSetPosts({ signal: controller.signal });
+
+    return () => {
+      controller.abort();
+    };
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [lastPostIndex]);
+
+  useEffect(() => {
+    const controller = new AbortController();
+
+    if (isLoading || isFetching) return;
+
+    setLastPostIndex(1);
+
+    setPosts([]);
+
+    getAndSetPosts({ signal: controller.signal });
+
+    return () => {
+      controller.abort();
+    };
+  }, [searchValue]);
+
+  function handleScroll() {
+    setLastPostIndex((prev) => prev + 32);
+  }
+
+  return (
+    <main className="w-full h-full flex flex-col gap-2">
+      {isLoading && <PostsGridSkeleton cuantity={32} />}
+      {!isLoading && !isFetching && (
+        <>
+          {!error ? (
+            <div>
+              <PostsGrid posts={posts} onFetchNewPosts={handleScroll} />
+            </div>
+          ) : (
+            <article className="flex items-center justify-center w-full max-h-96 py-32 text-center">
+              <Heading level={10}>
+                Something wen wrong, please reload the page
+              </Heading>
+            </article>
+          )}
+        </>
+      )}
+      {notFound && posts.length === 0 && (
+        <article className="flex items-center justify-center w-full max-h-96 py-32 text-center">
+          <Heading level={10}>404 not found</Heading>
+        </article>
+      )}
+    </main>
+  );
+}
diff --git a/src/app/(site)/app/search/page.tsx b/src/app/(site)/app/search/page.tsx
index 354cf9d..e068359 100644
--- a/src/app/(site)/app/search/page.tsx
+++ b/src/app/(site)/app/search/page.tsx
@@ -1,8 +1,5 @@
-import { getSuapabaseServerComponent } from "@/supabase/models/index.models";
 import { SearchForm } from "./components/SearchForm/SearchForm";
-import { PostsGrid } from "@/components/feature/posts-grid";
-import { Suspense } from "react";
-import { Skeleton } from "@/components/ui/skeleton";
+import { SearchedPostsGrid } from "./components/searched-posts-grid";
 
 interface SearchParams {
   search_query?: string;
@@ -13,37 +10,12 @@ interface Props {
 }
 
 const SearchPage: React.FC<Props> = async ({ searchParams }) => {
-  const supabase = await getSuapabaseServerComponent();
-  const searchValue = searchParams?.search_query ?? "";
-
-  const { data: posts } = await supabase
-    .from("posts")
-    .select("*")
-    .ilike("title", `%${searchValue}%`)
-    .order("created_at", { ascending: false })
-    .limit(24);
-
+  const searchValue = searchParams.search_query ?? "painting";
   return (
     <div className="w-full h-full flex min-h-screen">
       <div className="flex flex-col gap-2 w-full h-full min-h-screen p-2">
         <SearchForm defaultSearchValue={searchValue} />
-        <div>
-          {posts?.length !== undefined && posts?.length > 0 && (
-            <Suspense
-              fallback={
-                <ul className="break-inside-avoid gap-2 [column-count:3] md:[column-count:3]">
-                  {Array(16)
-                    .fill(" ")
-                    .map((_, i) => (
-                      <Skeleton key={i} className="w-full h-96 mb-2" />
-                    ))}
-                </ul>
-              }
-            >
-              <PostsGrid posts={posts} />
-            </Suspense>
-          )}
-        </div>
+        <SearchedPostsGrid key={searchValue} searchValue={searchValue} />
       </div>
     </div>
   );
diff --git a/src/components/feature/lazy-image/index.tsx b/src/components/feature/lazy-image/index.tsx
index 7f2657f..5bab7b4 100644
--- a/src/components/feature/lazy-image/index.tsx
+++ b/src/components/feature/lazy-image/index.tsx
@@ -2,7 +2,18 @@
 
 import { Skeleton } from "@/components/ui/skeleton";
 import { ImageOff } from "lucide-react";
-import { useEffect, useRef, useState } from "react";
+import { type HTMLAttributes, useEffect, useRef, useState } from "react";
+
+type TProps = {
+  src: string;
+  alt: string;
+  className?: string;
+  height?: number;
+  width?: number;
+  containerClassname?: HTMLAttributes<HTMLDivElement>["className"];
+  skeletonClassName?: string;
+  skeletonBgColor?: string;
+};
 
 export function LazyImage({
   src,
@@ -12,15 +23,8 @@ export function LazyImage({
   height,
   skeletonClassName = "",
   skeletonBgColor = "",
-}: {
-  src: string;
-  alt: string;
-  className?: string;
-  height?: number;
-  width?: number;
-  skeletonClassName?: string;
-  skeletonBgColor?: string;
-}) {
+  containerClassname = "",
+}: TProps) {
   const [loading, setLoading] = useState<boolean>(true);
   const [error, setError] = useState<boolean>(false);
 
@@ -46,7 +50,7 @@ export function LazyImage({
   }, []);
 
   return (
-    <div className={`flex flex-col relative`}>
+    <div className={`relative ${containerClassname}`}>
       <div className="relative">
         {!error && (
           <img
@@ -60,13 +64,8 @@ export function LazyImage({
         )}
         {loading && !error && (
           <Skeleton
-            className={[
-              "absolute top-0 left-0 w-full h-full",
-              skeletonClassName,
-            ].join(" ")}
+            className={["absolute top-0 left-0", skeletonClassName].join(" ")}
             style={{
-              height: "100%",
-              width: "100%",
               maxWidth: width,
               maxHeight: height,
               backgroundColor: skeletonBgColor,
diff --git a/src/components/feature/posts-grid/components/post/index.tsx b/src/components/feature/posts-grid/components/post/index.tsx
deleted file mode 100644
index c1a4c34..0000000
--- a/src/components/feature/posts-grid/components/post/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./post.component";
diff --git a/src/components/feature/posts-grid/components/posts-grid-container/index.ts b/src/components/feature/posts-grid/components/posts-grid-container/index.ts
new file mode 100644
index 0000000..99e7d72
--- /dev/null
+++ b/src/components/feature/posts-grid/components/posts-grid-container/index.ts
@@ -0,0 +1 @@
+export * from "./posts-grid-container.component";
diff --git a/src/components/feature/posts-grid/components/posts-grid-container/posts-grid-container.component.tsx b/src/components/feature/posts-grid/components/posts-grid-container/posts-grid-container.component.tsx
new file mode 100644
index 0000000..4276768
--- /dev/null
+++ b/src/components/feature/posts-grid/components/posts-grid-container/posts-grid-container.component.tsx
@@ -0,0 +1,23 @@
+import { forwardRef } from "react";
+
+type TProps = {
+  children: React.ReactNode;
+};
+
+type TRef = HTMLUListElement;
+
+// eslint-disable-next-line react/display-name
+const PostsGridContainer = forwardRef<TRef, TProps>(({ children }, ref) => {
+  return (
+    <ul
+      className="break-inside-avoid gap-2 lg:[column-count:3] [column-count:2] w-full"
+      ref={ref}
+    >
+      {children}
+    </ul>
+  );
+});
+
+PostsGridContainer.displayName = "PostsGridContainer";
+
+export { PostsGridContainer };
diff --git a/src/components/feature/posts-grid/components/posts-grid-row/index.ts b/src/components/feature/posts-grid/components/posts-grid-row/index.ts
new file mode 100644
index 0000000..2e870e8
--- /dev/null
+++ b/src/components/feature/posts-grid/components/posts-grid-row/index.ts
@@ -0,0 +1 @@
+export * from "./posts-grid-row.component";
diff --git a/src/components/feature/posts-grid/components/post/post.component.tsx b/src/components/feature/posts-grid/components/posts-grid-row/posts-grid-row.component.tsx
similarity index 88%
rename from src/components/feature/posts-grid/components/post/post.component.tsx
rename to src/components/feature/posts-grid/components/posts-grid-row/posts-grid-row.component.tsx
index a5101e3..a920fea 100644
--- a/src/components/feature/posts-grid/components/post/post.component.tsx
+++ b/src/components/feature/posts-grid/components/posts-grid-row/posts-grid-row.component.tsx
@@ -1,9 +1,9 @@
 "use client";
 
+import Link from "next/link";
 import { LazyImage } from "@/components/feature/lazy-image";
 import { ClientRouting } from "@/models/routing/client";
 import { Database } from "@/supabase/types";
-import Link from "next/link";
 
 export function PostsGridRow({
   post,
@@ -14,7 +14,7 @@ export function PostsGridRow({
 }) {
   const imageHeight = (post.asset_height * columnWidth) / post.asset_width;
   return (
-    <li key={post.id} className={`flex w-full h-full pt-2`}>
+    <li className={`flex w-full h-full pt-2`}>
       <Link
         href={ClientRouting.post().page(JSON.stringify(post.id) || "")}
         className="w-full"
@@ -23,7 +23,7 @@ export function PostsGridRow({
           src={post.asset_url}
           alt={post.title}
           className="flex w-full h-auto rounded-md object-cover object-center"
-          skeletonClassName="w-full rounded-md"
+          skeletonClassName="w-full h-full rounded-md"
           height={imageHeight}
           width={columnWidth}
           skeletonBgColor={post.asset_color || undefined}
diff --git a/src/components/feature/posts-grid/components/posts-grid-skeleton/index.ts b/src/components/feature/posts-grid/components/posts-grid-skeleton/index.ts
new file mode 100644
index 0000000..c034279
--- /dev/null
+++ b/src/components/feature/posts-grid/components/posts-grid-skeleton/index.ts
@@ -0,0 +1 @@
+export * from "./posts-grid-skeleton.component";
diff --git a/src/components/feature/posts-grid/components/posts-grid-skeleton/posts-grid-skeleton.component.tsx b/src/components/feature/posts-grid/components/posts-grid-skeleton/posts-grid-skeleton.component.tsx
new file mode 100644
index 0000000..50ab527
--- /dev/null
+++ b/src/components/feature/posts-grid/components/posts-grid-skeleton/posts-grid-skeleton.component.tsx
@@ -0,0 +1,14 @@
+import { Skeleton } from "@/components/ui/skeleton";
+import { PostsGridContainer } from "../posts-grid-container";
+
+export function PostsGridSkeleton({ cuantity = 16 }: { cuantity?: number }) {
+  return (
+    <PostsGridContainer>
+      {Array(cuantity)
+        .fill(" ")
+        .map((_, i) => (
+          <Skeleton key={i} className="w-full h-96 mb-2 rounded-sm" />
+        ))}
+    </PostsGridContainer>
+  );
+}
diff --git a/src/components/feature/posts-grid/index.ts b/src/components/feature/posts-grid/index.ts
new file mode 100644
index 0000000..d670f2d
--- /dev/null
+++ b/src/components/feature/posts-grid/index.ts
@@ -0,0 +1 @@
+export * from "./posts-grid.component";
diff --git a/src/components/feature/posts-grid/index.tsx b/src/components/feature/posts-grid/index.tsx
deleted file mode 100644
index 87b5b78..0000000
--- a/src/components/feature/posts-grid/index.tsx
+++ /dev/null
@@ -1,3 +0,0 @@
-import { PostsGrid } from "./posts-grid.component";
-
-export { PostsGrid };
diff --git a/src/components/feature/posts-grid/posts-grid.component.tsx b/src/components/feature/posts-grid/posts-grid.component.tsx
index dafd7f7..4ba9fe5 100644
--- a/src/components/feature/posts-grid/posts-grid.component.tsx
+++ b/src/components/feature/posts-grid/posts-grid.component.tsx
@@ -1,10 +1,15 @@
-"use client";
-
-import { useEffect, useRef, useState } from "react";
-import { PostsGridRow } from "./components/post";
+import { useCallback, useEffect, useRef, useState } from "react";
 import { TPostsGridItem } from "./posts-grid.models";
+import { PostsGridRow } from "./components/posts-grid-row";
+import { PostsGridContainer } from "./components/posts-grid-container";
 
-export function PostsGrid({ posts }: { posts: TPostsGridItem[] }) {
+export function PostsGrid({
+  posts,
+  onFetchNewPosts,
+}: {
+  posts: TPostsGridItem[];
+  onFetchNewPosts: () => void;
+}) {
   const [columnWidth, setColumnWidth] = useState<number | null>(null);
 
   const containerRef = useRef<HTMLUListElement>(null);
@@ -17,7 +22,6 @@ export function PostsGrid({ posts }: { posts: TPostsGridItem[] }) {
       if (containerWidth <= 0 || !containerWidth) return;
 
       const columnCount = window.innerWidth > 1024 ? 3 : 2;
-      console.log(window.innerWidth);
       setColumnWidth((containerWidth - 8 * 2) / columnCount);
     }
 
@@ -27,20 +31,53 @@ export function PostsGrid({ posts }: { posts: TPostsGridItem[] }) {
 
     return () => window.removeEventListener("resize", calculateColumnWidth);
   }, []);
+
+  const [lastElementRef, setLastElementRef] = useState<HTMLDivElement | null>(
+    null,
+  );
+
+  const lastItemRef = useCallback((node: HTMLDivElement) => {
+    if (!node) return;
+
+    setLastElementRef(node);
+  }, []);
+
+  useEffect(() => {
+    if (!lastElementRef || typeof window === "undefined") return;
+
+    const observerOptions: IntersectionObserverInit = {
+      root: null,
+      rootMargin: `${window.innerHeight * 2}px`,
+      threshold: 1.0,
+    };
+
+    const observer = new IntersectionObserver(onFetchNewPosts, observerOptions);
+
+    observer.observe(lastElementRef);
+
+    return () => {
+      observer.unobserve(lastElementRef);
+    };
+
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [lastElementRef]);
+
   return (
-    <ul
-      className="break-inside-avoid gap-2 px-2 lg:[column-count:3] [column-count:2]"
-      ref={containerRef}
-    >
-      {posts.length > 0 &&
-        containerRef.current &&
-        posts.map((post) => (
-          <PostsGridRow
-            columnWidth={columnWidth && !isNaN(columnWidth) ? columnWidth : 400}
-            key={post.id}
-            post={post}
-          />
-        ))}
-    </ul>
+    <PostsGridContainer ref={containerRef}>
+      {posts.length > 0 && containerRef.current && (
+        <>
+          {posts.map((post, i) => (
+            <PostsGridRow
+              columnWidth={
+                columnWidth && !isNaN(columnWidth) ? columnWidth : 400
+              }
+              key={i}
+              post={post}
+            />
+          ))}
+          <div ref={lastItemRef} className="h-96 w-full" />
+        </>
+      )}
+    </PostsGridContainer>
   );
 }