Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defineQuery with multiple requests only retrieves the first request #1765

Open
cmolisee opened this issue Oct 15, 2024 · 4 comments
Open

defineQuery with multiple requests only retrieves the first request #1765

cmolisee opened this issue Oct 15, 2024 · 4 comments

Comments

@cmolisee
Copy link

In my project I have content from 4 documents I need to retrieve on a single page. When using the vision tool I can correctly retrieve all the documents. When using defineQuery() and actually running the query I am only ever getting results for the first query and none of the others.

query:
export const multipleQueries = defineQuery({ 'a': *[_type == "aDocument"][0], 'b': *[_type == "bDocument"][0..4], 'c': *[_type == "cDocument"][0..4], 'd: *[_type == "dDocument"][0..4], });

when running the above I get results for 'a' but everything else is an empty array.
when i remove 'a' i get results for 'b' but everything else is an empty array.
likewise for the remainder.

To Reproduce

  1. create 4 different documents
  2. using next-sanity defineQuery() create a query for those documents as above
  3. using client.fetch(multipleQueries).catch(..) in a server side next page observe the behavior

Expected behavior

I should receive content for ALL the queries as I do in when using the vision tool and not just the first query

Which versions of Sanity are you using?

using react 18, sanity 3.44, next-sanity 9.3.10

What operating system are you using?

MacOS sonoma 14.5

Which versions of Node.js / npm are you running?

npm -v && node -v
10.2.0
v21.7.1

@stipsan
Copy link
Member

stipsan commented Oct 17, 2024

Can you try setting the Perspective in Vision to Published?
image

Vision uses your Studio auth and have access to draft content. When you fetch data from next.js, then unless you give your createClient() a token, it'll only have access to the data that's published.

@cmolisee
Copy link
Author

cmolisee commented Oct 17, 2024

Can you try setting the Perspective in Vision to Published? image

Vision uses your Studio auth and have access to draft content. When you fetch data from next.js, then unless you give your createClient() a token, it'll only have access to the data that's published.

I changed the Perpective to published as described and I am getting all the results as expected.

I am making the request on a server side rendered page in an async function following recommended practice of Next. I tried moving the request into a client component to see what would happen and the request inside of the client component is actually returning all the results as expected.

I'm thinking there is something going on with SSR and the readablestream that sanity query returns. I don't understand why but I am looking into possible solution like suspense, swr, changing the request strategy to be done in a client component, or otherwise.

EDIT: SWR has a lot of restriction in Next with app router so I won't be using that.

If my theory is correct then the next question would be is this expected behavior?

@cmolisee
Copy link
Author

Alright. So I did a test using suspense and on the ssr page and i got the expected results.

My best guess is that sanity takes the each of the queries individually and doesn't wait for the all to resolve before sending back data. Thus, when the first one resolves it gets sent back and then ssr proceeds thinking it has everything it needs - which is why the remaining query result aren't included.

throwing in suspense it will actually give me all the results as they come through the readablestream returned by sanity query. still not sure if thats expected behavior or not. as far as a solution goes it seems suspense makes the most sense.

@stipsan
Copy link
Member

stipsan commented Nov 6, 2024

It should be sending all the data every time, I think what we have here is a cache problem. You could bump the apiVersion by a day (if it's 2024-11-05 atm, try changing it to 2024-11-06) to bypass existing cache in Next.js and start with a new cache.
That said, calling React.use(props.data) and then giving a client component <Component data={dataPromise} /> where const dataPromise = client.fetch(), this is a well supported pattern.
But if you don't have other reasons for Component to be a client component, beyond working around the cache issue you were facing, then I'd recommend moving things back to the simpler and performant server-only model where you await the fetch on the server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants