Next.js Discord

Discord Forum

What's the correct way to fetch for data with Sanity?

Unanswered
Texas leafcutting ant posted this in #help-forum
Open in Discord
Texas leafcutting antOP
Since getStaticProps() is no longer an option, what is the correct way to fetch data from Sanity?

Example from their tutorial https://www.sanity.io/docs/connect-your-content-to-next-js, see image.

My code:
export const fetchData = async () => {
  const pets = await client.fetch(`*[_type == "pet"]`);

  return {
    props: {
      pets,
    },
  };
};


Something I noticed: I console.logged pets in my component and it showed undefined. I was, and still am, not sure why, trying to understand it. However, I deleted my block of code (including the Sanity client), and it still showed undefined. Something tells me that I made a mistake along the way, but I'm not sure.

So question about the data fetching, if my way is correct and if not, how I should do it?

Thanks everyone 🙂

----
Full code in case it's helpful:
import { createClient } from "next-sanity";

const Home = ({ pets }: any) => {
  console.log("Pets is: " + pets);

  return (
    <main>
        <h1>PETS?</h1>
        {pets?.length > 0 && (
          <ul>
            {pets.map((pet: any) => (
              <li key={pet._id}>{pet?.name}</li>
            ))}
          </ul>
        )}

        {/* @ts-ignore */}
        {!pets?.length > 0 && <p>No pets to show</p>} 
    </main>
  );
};

export default Home;

const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  dataset: "production",
  apiVersion: "2023-07-14",
  useCdn: false,
});

export const fetchData = async () => {
  const pets = await client.fetch(`*[_type == "pet"]`);

  return {
    props: {
      pets,
    },
  };
};

----

15 Replies

@Texas leafcutting ant Since `getStaticProps()` is no longer an option, what is the correct way to fetch data from Sanity? Example from their tutorial <https://www.sanity.io/docs/connect-your-content-to-next-js>, see image. **My code:** ts export const fetchData = async () => { const pets = await client.fetch(`*[_type == "pet"]`); return { props: { pets, }, }; }; Something I noticed: I console.logged `pets` in my component and it showed `undefined`. I was, and still am, not sure why, trying to understand it. However, I deleted my block of code (including the Sanity client), and it still showed `undefined`. Something tells me that I made a mistake along the way, but I'm not sure. So question about the data fetching, if my way is correct and if not, how I should do it? Thanks everyone 🙂 ---- Full code in case it's helpful: ts import { createClient } from "next-sanity"; const Home = ({ pets }: any) => { console.log("Pets is: " + pets); return ( <main> <h1>PETS?</h1> {pets?.length > 0 && ( <ul> {pets.map((pet: any) => ( <li key={pet._id}>{pet?.name}</li> ))} </ul> )} {/* @ts-ignore */} {!pets?.length > 0 && <p>No pets to show</p>} </main> ); }; export default Home; const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, dataset: "production", apiVersion: "2023-07-14", useCdn: false, }); export const fetchData = async () => { const pets = await client.fetch(`*[_type == "pet"]`); return { props: { pets, }, }; }; ----
Giant panda
You're still trying to fetch data as if you were using getstaticprops.
You can fetch directly within the Home component.
Texas leafcutting antOP
Gotcha, thanks! That makes sense, I’ll try that tomorrow.

Thanks for your reply ✌🏼
Texas leafcutting antOP
Hey there, Jon!

Trying my luck and hoping you'll be able to help me out again C':

I'm now trying to display an image on the frontend.

I've successfully queried all information but since image is actually an object, I can't really use it as the source for my Next.js Link.

With the following query I've managed to query the actual URL, but I'm somehow still unable to display the image? Can't figure out why.

// Query
*[featured == true]{
  "imageUrl": image.asset->url
}

// Output
[…] 1 item
0:{…} 1 property
imageUrl:https://cdn.sanity.io/images/s5dkpr7w/production/e8fb8d81dda09b9e2a4021de9fbe470262ce8408-4898x3265.jpg


I did find the plugin next-sanity-image, but didn't help much for now... I think I'm so close to finding the solution, but not yet...
Sorry for the ping you may have gotten from this thread, it's Saturday after all.
Code if it helps:
const FeaturedCard = async () => {
  const featured = await client.fetch(`*[featured == true]`);
  const src = await client.fetch(`*[featured == true]{
    "imageUrl": image.asset->url
  }`);

  console.log(src); // Output, image below

  return (
    <section className="d">
      {featured?.map((x: any) => (
        <div key={x._id}>
          <h1 className="">{x.name}</h1>
          <Image src={src} height={400} width={500} alt={x.alt} />
        </div>
      ))}
    </section>
  );
};

export default FeaturedCard;
Giant panda
Does it give an error code?
Texas leafcutting antOP
Nope, just get the infamous no-image thingy
Giant panda
Oh wait, nevermind. I see what you're saying.
You need to remove the url from the object.
const url = src[0].imageUrl;

This will get the URL from the first object in the array.
Texas leafcutting antOP
Aha, I see what mistake I made. I tried doing that, but tried so in the src within the Link comp.

How would I do that for an multiple images at once? Since this time I needed just one, but in a while I'll need the src for many images at once.
Giant panda
Many ways of doing that. Would you fetch multiple image urls from within one fetch to the database?
Texas leafcutting antOP
Trying to make a sort of photo blog. So essentially I want to upload some photos to the Studio, some from say China, some from say Greece. Then I want to display them all in one page, grouped ideally.

Later I want to add the functionality of clicking on links to 'collections' of photos, so say one page with only photos from Greece (:
Giant panda
If the return is an array of objects that contain the urls, you simply loop through the array and extract the url from each.
It could be something like
srcs.map( (urlObject) =>  urlObject.imageUrl
)


This would return an array of url strings.
Texas leafcutting antOP
Okay ya, makes sense !