Help with filtering blogs by category in Next.js using Groq
9 replies
Last updated: Jun 28, 2022
D
hey all, Im stuck on this issue please help me to solve this. So I have multiple categories in Blogs. So I want to print Blogs related to the category. On the
Currently Id is 1b65f627-7d10-4a35-9062-41e9245ff272 and Localhost Url is
http://localhost:3000/blog/category/first-category .
categorypage But It's not working. and how I add two params in getStaticProps. the slug param is working good but How do I add $Id. Blogs are filtering via Id but how add it on the frontend. On
GROQPlayground all the blogs are filtering fine. But I'm stuck how I filter on frontend. How I pass $id
/** * Makes Next.js aware of all the slugs it can expect at this route */ export async function getStaticPaths() { const allCategoryQuery = groq` *[_type == "blogCategory" && defined(slug.current)][].slug.current `; const pages = await getClient().fetch(allCategoryQuery); return { paths: pages.map((slug) => `/blog/category/${slug}`), fallback: true, }; } export async function getStaticProps({ params, preview = false }) { const query = groq` *[_type == "blogCategory" && slug.current == $slug]{ _id,title,description,slug,image, "blogCategory": *[_type=='article' && blogCategories[]._ref == "1b65f627-7d10-4a35-9062-41e9245ff272"] } `; const queryParams = { slug: params.slug }; console.log(queryParams, 'queryParams'); const data = await getClient(preview).fetch(query, queryParams); // Helper function to reduce all returned documents down to just one const page = filterDataToSingleItem(data, preview); return { props: { preview, siteSettings: await fetchGlobalSettings(), allCategories: await sanity.fetch(groq` *[_type == "blogCategory" && !(_id in path('drafts.**'))] {...}`), data: { page, query, queryParams, }, }, }; }
http://localhost:3000/blog/category/first-category .
const BlogView = (props) => { const { data, preview, siteSettings = {}, allCategories } = props; const { data: previewData } = usePreviewSubscription(data?.query, { params: data?.queryParams ?? {}, initialData: data?.page, enabled: preview, }); // Client-side uses the same query, so we may need to filter it down again const page = filterDataToSingleItem(previewData, preview); if (!page) return null; return ( <Layout siteSettingData={siteSettings}> {page && page.blogCategory.map((item, i) => ( <BlogItem data={item} key={item._id || i} /> ))} </Layout> ); }; export default BlogView;
Jun 27, 2022, 12:26 PM
K
There are quite a few things to unpack here. First of all, your
Regarding
Then, I’m not sure you should be reducing all your data to a single entry. Ultimately you want a collection or blog posts for that category, don’t you?
getStaticPathsdoes not return the right data. It should return an array of object with a
paramsproperty, not actual paths as strings. Something like this:
[ { params: { slug: 'category-1' } }, { params: { slug: 'category-2' } }, { params: { slug: 'category-3' } }, ]
getStaticProps, I think you’re making your life too difficult. You receive a category slug from the parameter. All you want are all the posts whose category has this slug. Without knowing your schema, I would say something like this:
*[ _type == "article" && $slug in blogCategories[]->slug.current]
Jun 27, 2022, 12:32 PM
D
Is there any way to add query params like this in getStaticProps? I tries this in getserverSide props its working fine for me. But In getstaticprops its throwing error call id is undefined
Jun 27, 2022, 12:35 PM
K
Well you receive the route params in the
paramsobject. So if your page is called
[slug].js, you receive
{ params: { slug: 'foo' } }.
Jun 27, 2022, 12:36 PM
D
Thank you for help all working ......
/** * Makes Next.js aware of all the slugs it can expect at this route */ export async function getStaticPaths() { const allSlugsQuery = groq`*[_type == "article" && defined(slug.current)][].slug.current`; const pages = await getClient().fetch(allSlugsQuery); return { paths: pages.map((slug) => `/blog/${slug}`), fallback: true, }; } export async function getStaticProps({ params, preview = false }) { const query = groq` *[_type == "article" && slug.current == $slug] { ..., "id": _id,author->{avatar,name,description,twitter}, "blogCategories":blogCategories[]->{title,image,slug,description,slug, ${fetchContentBlocks} } } `; const queryParams = { slug: params.slug }; const data = await getClient(preview).fetch(query, queryParams); // console.log('data', data); // Escape hatch, if our query failed to return data if (!data) return { notFound: true }; // Helper function to reduce all returned documents down to just one const page = filterDataToSingleItem(data, preview); return { props: { preview, data: { query, queryParams, page, siteSettings: await fetchGlobalSettings(), }, }, }; }
Jun 27, 2022, 3:36 PM
D
Thank you all working now .....
/** * Makes Next.js aware of all the slugs it can expect at this route */ export async function getStaticPaths() { const allCategoryQuery = groq` *[_type == "blogCategory" && defined(slug.current)][].slug.current `; const pages = await getClient().fetch(allCategoryQuery); return { paths: pages.map((slug) => `/blog/category/${slug}`), fallback: true, }; } export async function getStaticProps({ params, preview = false }) { const query = groq` *[_type == "blogCategory" && slug.current == $slug] {..., "relatedBlogs":*[ _type == "article" && $slug in blogCategories[]->slug.current]} `; const queryParams = { slug: params.slug }; const data = await getClient(preview).fetch(query, queryParams); if (!data) return { notFound: true }; // Helper function to reduce all returned documents down to just one const page = filterDataToSingleItem(data, preview); return { props: { preview, siteSettings: await fetchGlobalSettings(), allCategories: await sanity.fetch(groq` *[_type == "blogCategory" && !(_id in path('drafts.**'))] {...}`), data: { page, query, queryParams, }, }, }; }
Jun 27, 2022, 3:37 PM
D
Is there any way to speed up the blog page?Speed is slow minor slow but ok
can you please help in this??
Im using getstaticprops.
can you please help in this??
Im using getstaticprops.
Jun 27, 2022, 3:39 PM
K
I guess it depends a lot what is the performance bottleneck. First, make sure you’re not assuming that just from your local environment, because it will always be significantly slower than production.
Jun 28, 2022, 7:14 AM
D
Ok thanks you.
Jun 28, 2022, 9:26 PM
D
yes its working very fast on prouction. thanks.
Jun 28, 2022, 9:27 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.