GROQ query in Next.js components returns empty array, works in pages

11 replies
Last updated: Jan 14, 2026
help: I use the GROQ query in the next js components, not pages. it's not fetching data. showing empty array. But on the other hand, if add this query on the page its works fine. So the question is how I use this query in the header, footer, others.              So please someone help me? How I write query I next component. So my code is..  

import React from 'react';
import groq from 'groq';
import sanity from '../../utils/sanity';

import { Heading } from '../elements';

const ReviewBlock = ({ title, products = [] }) => {
  console.log(products, 'products');
  return (
    <section className="section is-medium">
      <div className="container">
        {title && (
          <Heading centered className="has-text-black mb-6">
            {title}
          </Heading>
        )}
      </div>
    </Section>
  );
};
export async function getStaticProps() {
  return {
    props: {
      products: await sanity.fetch(groq`
          *[_type == "product" && isFeatured && !(_id in path('drafts.**'))] {"id": _id, ...}|order(publishedAt desc)
        `),
    },
  };
}
export default ReviewBlock;
AI Update

I can see the issue! You're trying to use getStaticProps inside a component file, but getStaticProps only works in page files in Next.js (files inside the pages/ directory). That's why it works on pages but returns an empty array in your component.

Here are your solutions depending on your Next.js version:

For Next.js App Router (13+)

Convert your component to a Server Component and fetch data directly inside it:

import React from 'react';
import groq from 'groq';
import { createClient } from 'next-sanity';
import { Heading } from '../elements';

// Create your Sanity client
const client = createClient({
  projectId: 'your-project-id',
  dataset: 'production',
  apiVersion: '2024-01-01',
  useCdn: true,
});

const ReviewBlock = async ({ title }) => {
  // Fetch directly in the component
  const products = await client.fetch(groq`
    *[_type == "product" && isFeatured && !(_id in path('drafts.**'))] 
    {"id": _id, ...} | order(publishedAt desc)
  `);

  console.log(products, 'products');
  
  return (
    <section className="section is-medium">
      <div className="container">
        {title && (
          <Heading centered className="has-text-black mb-6">
            {title}
          </Heading>
        )}
      </div>
    </section>
  );
};

export default ReviewBlock;

This works because Server Components in the App Router can be async and fetch data directly.

For Next.js Pages Router (12 and below)

You have two options:

Option 1: Fetch in the page and pass as props

// pages/your-page.js
export async function getStaticProps() {
  const products = await sanity.fetch(groq`
    *[_type == "product" && isFeatured && !(_id in path('drafts.**'))] 
    {"id": _id, ...} | order(publishedAt desc)
  `);
  return {
    props: { products }
  };
}

export default function YourPage({ products }) {
  return <ReviewBlock title="Reviews" products={products} />;
}

// components/ReviewBlock.js
const ReviewBlock = ({ title, products = [] }) => {
  // Just use the products prop
  console.log(products, 'products');
  return (/* your JSX */);
};

Option 2: Fetch client-side with SWR or useEffect

import useSWR from 'swr';
import groq from 'groq';
import sanity from '../../utils/sanity';

const ReviewBlock = ({ title }) => {
  const { data: products = [] } = useSWR(
    groq`*[_type == "product" && isFeatured && !(_id in path('drafts.**'))] 
         {"id": _id, ...} | order(publishedAt desc)`,
    (query) => sanity.fetch(query)
  );

  console.log(products, 'products');
  return (/* your JSX */);
};

For shared components (Header/Footer)

For layout components that need data:

  • App Router: Create them as async Server Components (like the first example above)
  • Pages Router: Fetch data in your page's getStaticProps and pass it down, or use client-side fetching with SWR/React Query

The key takeaway: getStaticProps and getServerSideProps are page-level only in the Pages Router. For components, you either need to pass data down as props, use Server Components (App Router), or fetch client-side.

Check out the next-sanity package documentation for more patterns on integrating Sanity with Next.js!

Show original thread
11 replies

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?