Fetch multiple Sanity content types in Next.js getStaticProps
Now fetching works but I also want to fetch a different type like “authors” on the same page and map through them.
But i don’t want to copy paste the client? How can I fetch multiple types on one page.
thanks!
Code:
import sanityClient from "../lib/client";
import { aboutQuery, teamQuery } from "../lib/queries";
const People = ({ context }) => {
const { title, author } = context;
console.log(context);
return (
<div>
<h2>{title}</h2>
<p>{author.name}</p>
</div>
)
}
export default People;
export async function getStaticProps() {
const context = await sanityClient.fetch(aboutQuery, teamQuery);
return { props: { context } };
}
export const aboutQuery = `*[_type == "page" && title == "About"][0]{
_id,
title,
slug,
author-> {
name
}
}`;
export const teamQuery = `*[_type == "author"]{
_id,
bio,
slug,
jobTitle,
name,
authorImage,
}`;Good news - you don't need to copy-paste the client! You can make multiple fetch calls with the same client, or even better, fetch multiple queries at once. Here are a few approaches:
Option 1: Multiple Fetch Calls (Simplest)
export async function getStaticProps() {
const aboutData = await sanityClient.fetch(aboutQuery);
const teamData = await sanityClient.fetch(teamQuery);
return {
props: {
aboutData,
teamData
}
};
}
const People = ({ aboutData, teamData }) => {
const { title, author } = aboutData;
return (
<div>
<h2>{title}</h2>
<p>{author.name}</p>
<h3>Team Members:</h3>
{teamData.map((member) => (
<div key={member._id}>
<h4>{member.name}</h4>
<p>{member.jobTitle}</p>
</div>
))}
</div>
)
}Option 2: Parallel Fetching with Promise.all (Faster)
export async function getStaticProps() {
const [aboutData, teamData] = await Promise.all([
sanityClient.fetch(aboutQuery),
sanityClient.fetch(teamQuery)
]);
return {
props: {
aboutData,
teamData
}
};
}This runs both queries in parallel, which is faster than sequential fetching.
Option 3: Single GROQ Query (Most Efficient)
You can combine both queries into a single GROQ query that returns an object with both datasets:
export const combinedQuery = `{
"about": *[_type == "page" && title == "About"][0]{
_id,
title,
slug,
author-> {
name
}
},
"team": *[_type == "author"]{
_id,
bio,
slug,
jobTitle,
name,
authorImage,
}
}`;
export async function getStaticProps() {
const data = await sanityClient.fetch(combinedQuery);
return {
props: {
aboutData: data.about,
teamData: data.team
}
};
}I'd recommend Option 2 (Promise.all) for your use case - it keeps your queries separate and maintainable while still being performant. Option 3 is great if you want to minimize API calls, but Option 2 is cleaner when you're reusing queries across different pages.
The key issue in your original code was that sanityClient.fetch() only accepts one query at a time - passing two queries as separate arguments (sanityClient.fetch(aboutQuery, teamQuery)) doesn't work. You need to make separate fetch calls or combine the queries in GROQ itself.
Show original thread1 reply
Was this answer helpful?
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.