TanStackT
TanStack14mo ago
1 reply
constitutional-coral

How to create multiple routes with createFileLazyRoute e.g. / and /page/$page & <Suspense>

My goal is a single component that handles / and /page/$page

I tried the following, but when I save it it removes the (page/$page?) from the createLazyFileRoute... I'd prefer to not have to create a separate lazy route if at all possible

import PostCard from "@/components/PostCard";
import { Post } from "@/types/Post";

import { createLazyFileRoute, useParams } from "@tanstack/react-router";
import { useSuspenseQuery } from "@tanstack/react-query";
import Pagination from "@/components/Pagination";
import { Suspense } from "react";
import PostSkeleton from "@/components/PostSkeleton";

export const Route = createLazyFileRoute("/(page/$page?)")({
  component: () => (
    <Suspense fallback={<PostSkeleton />}>
      <Index />
    </Suspense>
  ),
});

function Index() {
  const { page = "1" } = useParams({ from: "/page/$page" });
  const getPosts = async (page: number) => {
    const response = await fetch(
      `https://jsonplaceholder.typicode.com/posts?_page=${page}&_limit=9`
    );
    const posts = await response.json();

    return {
      posts,
      totalPages: response.headers.get("x-total-count"),
    };
  };

  const { data: posts } = useSuspenseQuery<{
    posts: Post[];
    totalPages: string | null;
  }>({
    queryKey: ["posts", page],
    queryFn: () => getPosts(parseInt(page.toString(), 10)),
  });

  return (
    <>
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {posts.posts.map((post: Post) => (
          <PostCard key={post.id} post={post} />
        ))}
      </div>
      {posts.totalPages && (
        <div className="flex justify-center items-center my-10">
          <Pagination
            totalPages={parseInt(posts.totalPages)}
            currentPage={parseInt(page.toString() || "1")}
          />
        </div>
      )}
    </>
  );
}
Was this page helpful?