Lluis Simon
Lluis Simon

Reputation: 46

How to Fetch Static Filters & Dynamic Products Efficiently in Next.js?

:)

I'm building a marketplace that displays a paginated list of products, which users can filter. I am using NextJS 14 with the app router. Each product belongs to a category, and each category has a specific set of specifications (e.g., the "Laptop" category includes specifications like RAM and OS, while the "Shirt" category includes specifications like color). For context, here's my model for categories and specifications:

Specifications and categories data model

Since these specifications will not change very often, I wanted to generate a list of filters from these specifications statically. On the other side, I wanted to keep page and filter state in the URL (using nuqs). Thus, I tried generating this route:

At build time, I retrieve all categorySlugs:

export async function generateStaticParams() {
  const categories = await getCategories();
  return categories.map((category) => ({
    slug: category.slug,
  }));
}
export default async function Layout({
  params,
}: {
  params: { categorySlug: string };
}) {
  const category = await getCategoryBySlug(params.categorySlug);
  const filters = await getFiltersByCategorySlug(params.categorySlug);
  ....

Then, I make my page dynamic to get the searchParams in it and fetch products in the server:

export const revalidate = 0;

export default async function Page({
  params,
  searchParams,
}: {
  params: { categorySlug: string };
  searchParams: Promise<{ [key: string]: string | string[] | undefined }>;
}) {
  const paginationParams = await paginationCache.parse(searchParams);
  const filterParams = await filtersCache.parse(searchParams);
  const products = await fetchProducts(params.categorySlug, filterParams.filters, paginationParams.page);
...

However, this approach makes the entire route dynamic, causing filters and products to be fetched on every request, which slows down performance. As a workaround, I moved product fetching to the client side using the TanStack React Query library, but I prefer fetching this data on the server.

My question is: What is the best practice or strategy to achieve static filters with a dynamic list of products, while keeping the state stored in the URL?

Thanks a lot in advance, and please let me know if I can provide further information to clarify!

I tried:

  1. Creating a subroute to fetch dynamic data

This still makes the layout.tsx dynamic.

  1. forcing the layout to be static with 'force-static'

still makes it dynamic fetching data on every request

Upvotes: 0

Views: 28

Answers (0)

Related Questions