# Fetching Deeply in Sanity.io: A Comprehensive Guide

I posted my frustration a week ago on [X](https://twitter.com/tinotendajoe01/status/1694773263593791745?s=20) about how I lost my sanity studio code base. So yesterday morning, I finally finished reverse engineering the code base, lol. But guess what? I ended up spending the whole day again, failing to figure out a bug while trying to fetch the URL of a document in one of my data sets.  

```javascript
    {
      name: "file",
      title: "File",
      type: "file",
    },
```

  
The `file` object contains metadata relating to a file. However, when I was trying to get `item.file.asset.url`, it returns `undefined`. I wasn't aware that this was due to the structure of data I was receiving from the sanityClient.

Today that is when I realized that the default behavior of sanityClient fetch is that it does not deeply populate references, so if the `file` is referencing another object `asset` that has a property `URL`, it won't be populated in fetch.

And to fetch deeply in Sanity, I have to explicitly state it in my query:

```javascript
export async function fetchAllResources() {
  try {
    const query = `*[_type == "resources"]{ ..., file-> }`;
    ...
  }
  ...
}
```

Here, `file->` indicates that fetch should populate the `file` reference.

In this scenario, I was now able to directly ask for the url of the file in the query itself.

So I decided to share with you some more technical ways around nested data structures with sanity.

`Always remember: understanding the data structure you are working with is critical, and make sure to use correct fetching methods for dealing with references in databases like Sanity.`

So lets get technical!

# Fetching Deeply

[Sanity.io](http://Sanity.io) is a platform for structured content that comes with an open-source editing environment, Sanity Studio, that you can customize with JavaScript and a real-time hosted data store . This write up will guide you through the process of fetching deeply nested data from [Sanity.io](http://Sanity.io), which can be a common requirement when working with complex data structures.

## Understanding The Structure of [Sanity.io](http://Sanity.io)

In [Sanity.io](http://Sanity.io), data is stored as documents in a dataset. Each document contains a set of fields, which can be of different types such as string, number, boolean, array, and object. In addition, one important type is the reference type, which allows linking between different documents ([Source 3](https://www.sanity.io/docs/how-queries-work)).

For example, a `resources` document might look like this:

```javascript
{
  _id: "resource1",
  _type: "resources",
  title: "Resource Title",
  mainImage: { /* image object */ },
  description: "Resource description",
  file: { /* file object */ },
  Year: "2020-03-27T11:30:00.000Z",
  publisher: "Publisher Name",
  tags: ["tag1", "tag2"],
  status: "active",
  category: "forms"
}
```

## Fetching Data

[Sanity.io](http://Sanity.io) uses Groq (Graph-Relational Object Queries) as its primary query language. To fetch data from Sanity, you need to send a query to Sanity's API endpoint. This can be done manually by constructing a URL with your project ID, dataset name, and query, or by using a Sanity client library .

Here is an example of how to fetch all `resources` documents using the Sanity client in JavaScript:

```javascript
const query = `*[_type == "resources"]`;
const response = await sanityClient.fetch(query);
```

This will return an array of `resources` documents.

## Fetching Deeply Nested Data

In many cases, the data you need is nested within fields that are arrays or objects, or behind references. You need to specify these fields in your query in order to fetch them.

### Fetching Nested Fields

If a field is an array or an object, you can fetch its nested fields by specifying them in your query. For example, to fetch the `url` field of the `file` object in each `resources` document, you can use this query:

```javascript
const query = `*[_type == "resources"]{..., file{..., asset->}}`;
const response = await sanityClient.fetch(query);
```

In this query, the `...` operator is used to fetch all other fields in the `resources` documents and in the `file` objects. The `asset->` part is used to dereference the `asset` field in the `file` objects.

### Fetching References

References in [Sanity.io](http://Sanity.io) allow you to link between different documents. To fetch the data of a document that is referenced in another document, you need to dereference the reference field using the `->` operator ([Source 3](https://www.sanity.io/docs/how-queries-work)).

For example, if the `file` field in the `resources` documents is a reference to `file` documents, you can fetch the `url` field of the referenced `file` documents like this:

```javascript
const query = `*[_type == "resources"]{..., file->}`;
const response = await sanityClient.fetch(query);
```

## Best Practices for Fetching Data in [Sanity.io](http://Sanity.io)

Here are some best practices for fetching data in [Sanity.io](http://Sanity.io):

1. **Be specific in your queries**: Only fetch the fields you need. This can improve the performance of your queries and reduce the amount of data transferred.
    
2. **Handle errors**: Always include error handling in your fetch operations. This can help you identify issues with your queries and prevent your application from crashing if a fetch operation fails.
    
3. **Use the Sanity client libraries**: Sanity provides client libraries for several programming languages that make it easier to fetch data from Sanity. These libraries also provide additional features such as caching and real-time updates.
    
4. **Be aware of CORS**: When fetching data from a web browser, you need to make sure that the origin of your web page is allowed by Sanity's CORS (Cross-Origin Resource Sharing) settings. You can add origins in the API settings of your Sanity project
    
5. **Keep learning about Groq**: The Groq query language used by Sanity is very powerful and flexible. The more you learn about Groq, the more efficient your queries can be. You can find more information about Groq
    

## Common Bugs and Solutions when Fetching Data in [Sanity.io](http://Sanity.io) with Next.js

When using [Sanity.io](http://Sanity.io) with Next.js, you might encounter various bugs, especially when fetching different data types. This section will discuss some of these common issues and how to rectify them.

### 1\. Incorrect Configuration of Sanity Client

The Sanity client must be correctly configured with the correct project ID, dataset name, and token. If these values are incorrect, you will encounter errors when trying to fetch data. The project ID and dataset name can be found in your Sanity project settings on the [Sanity.io](http://Sanity.io) website, and the token can be generated there as well.

Here is an example of how to correctly configure the Sanity client in Next.js:

```javascript
import { createClient } from "next-sanity";

const client = createClient({
  projectId: "your_project_id",
  dataset: "your_dataset_name",
  useCdn: process.env.NODE_ENV === "production",
  token: "your_token",
});
```

### 2\. Incorrect GROQ Query Syntax

When fetching data from [Sanity.io](http://Sanity.io), you need to use the GROQ query language. If your GROQ query syntax is incorrect, you will encounter errors. For instance, when fetching a document by its slug, you should use the correct syntax in your query.

Here is an example of how to correctly fetch a document by its slug in Next.js:

```javascript
const slug = "your_slug";
const query = `*[_type == "post" && slug.current == $slug][0]`;
const post = await client.fetch(query, { slug });
```

### 3\. CORS Issues

When fetching data from [Sanity.io](http://Sanity.io) in a Next.js application, you might encounter CORS (Cross-Origin Resource Sharing) issues. This can happen if you are making requests to [Sanity.io](http://Sanity.io) from a different origin (URL) than the one configured in your Sanity project settings. To solve this, you need to add your Next.js application's origin to the CORS origins list in your Sanity project settings.

### 4\. Module Not Found

Sometimes, you might encounter a "Module not found" error. This can happen if you try to import a module that doesn't exist or if there's a problem with your project's configuration. To solve this, make sure all your imports are correct and your project is properly configured .

### 5\. Problems with Next.js's Concurrent Features

Next.js 12 introduced new concurrent features that are still in alpha. Using these features with Sanity can cause Next.js to hang. This is due to an issue where the `window` object is not defined. Unfortunately, there is currently no known solution for this issue, and you might need to avoid using Next.js's concurrent features with Sanity until a fix is available .

In conclusion, when fetching data from [Sanity.io](http://Sanity.io) in a Next.js application, it's important to correctly configure the Sanity client, use the correct GROQ query syntax, handle CORS issues, ensure all imports are correct, and be aware of potential issues with new features in Next.js.
