🔮 Sanity Create is here. Writing is reinvented. Try now, no developer setup

Querying a single field from a Sanity schema using groq in Node.js

50 replies
Last updated: Sep 1, 2022
Hello everyone! I am not sure why I am having troubles with this, but I have a schema from which I am trying to only query a single field from, it's an image. It looks like this:
const filter = groq`*[_type == "siteSettings"]`;
  const projection = groq`{ image: gigs_image.asset->url}`;
  const query = [filter, projection].join(' ');
  const image = await client.fetch(query).catch(error => console.error(error));
I adapted this query from a different place, where all of the fields of
siteSettings
is used. But here, I only need that one field
gigs_image
. I know I can get that specific field with groq`*[_type == "siteSettings"]{gigs_image}`, but I am not sure how to get the..
.asset->url
stuff there.. I am sorry this is a really poorly phrased question, I am still super new to sanity.
Aug 29, 2022, 9:07 PM
I think I get what you're going for! Why are you defining the query and the projection separately and then joining them?
The following should return just the url you're looking for:

`*[_type == "siteSettings"].gigs_image.asset->.url
Aug 29, 2022, 9:13 PM
hm, this gives me
null
Aug 29, 2022, 9:18 PM
and, it returns an object
Aug 29, 2022, 9:19 PM
What version of the API are you using?
Aug 29, 2022, 9:19 PM
I am not sure I can answer that question
Aug 29, 2022, 9:20 PM
my package json says
Aug 29, 2022, 9:20 PM
"@sanity/client": "^2.0.0",
Aug 29, 2022, 9:21 PM
How have you configured your client?
Aug 29, 2022, 9:21 PM
"groq": "^0.142.0",
Aug 29, 2022, 9:21 PM
does that help?
Aug 29, 2022, 9:21 PM
the query is done by node, not by clientside javascript
Aug 29, 2022, 9:21 PM
if that makes a difference
Aug 29, 2022, 9:22 PM
Where and how are you running the query?
Aug 29, 2022, 9:22 PM
it's running as the site is being built by eleventy, via node
Aug 29, 2022, 9:22 PM
Ok, how have you added the client to your site?
Aug 29, 2022, 9:22 PM
there is no clientside javascript running
Aug 29, 2022, 9:23 PM
this is happening during build
Aug 29, 2022, 9:23 PM
I understand that. How have you connected your site to sanity?
Aug 29, 2022, 9:24 PM
... I don't know what that question means
Aug 29, 2022, 9:25 PM
I added a webhook to netlify, whenever the content changes in production, netlify triggers a rebuild
Aug 29, 2022, 9:25 PM
Where are you using this package?
Aug 29, 2022, 9:27 PM
I have a file that requires it and configures it with env vars
Aug 29, 2022, 9:28 PM
OK, what does that look like? That would be your client configuration.
Aug 29, 2022, 9:29 PM
but I never touched that, it was part of the eleventy starter
Aug 29, 2022, 9:29 PM
require('dotenv').config({
  path: `.env.${process.env.NODE_ENV || 'development'}`
})
const sanityClient = require("@sanity/client");

const { sanity } = require('../../client-config')

/**
 * Set manually. Find configuration in
 * studio/sanity.json or on <http://manage.sanity.io|manage.sanity.io>
 */

/*
const sanity = {
  projectId: 'anokeucs',
  dataset: 'eleventy',
  useCdn: true
}
*/

module.exports = sanityClient({...sanity, useCdn: !process.env.SANITY_READ_TOKEN, token: process.env.SANITY_READ_TOKEN});
Aug 29, 2022, 9:29 PM
so just to make sure I expressed myself correctly, I am getting everything as I wanted, I am just trying to query a single field instead of the entire schema with all of the fields. Instead of doing
settings.gigs_image
I just wanna use
gigs_image
Aug 29, 2022, 9:30 PM
I understand that the query for the field is
*[_type == "siteSettings"]{gigs_image}
according to doc. But I don't know how to use
.asset->url
in this context, because when I just add it to the query on top, it fails
Aug 29, 2022, 9:31 PM
I'm sorry that I am lacking the vocabulary to express myself correctly, I should have not relied on a starter. It's basically a black box for me with abstraction that is entirely foreign 😕
Aug 29, 2022, 9:32 PM
No worries, I understand! That first query I sent you would get you the url of the image you're looking for if you're using the right API version. It looks like your client is missing an API version , so it falls back to v1 which doesn't have support for that sort of query. If you add
apiVersion: '2022-08-29'
to the
sanity
object that contains your project id and dataset it should fix this.
If you want your data in it in the form of an object, your first message looks correct. That may have been failing because of the missing API version.
Aug 29, 2022, 9:37 PM
alright, I have added the
apiVersion
to the sanity object for the clientConfig. But with groq`*[_type == "siteSettings"].gigs_image.asset-&gt;.url`, it still returns
null
Aug 29, 2022, 9:39 PM
What does the schema for that page look like?
Aug 29, 2022, 9:40 PM
export default {
  name: 'siteSettings',
  type: 'document',
  title: 'Einstellungen',
  __experimental_actions: ['update', /* 'create', 'delete', */ 'publish'],
  fields: [
    {
      name: 'email',
      type: 'string',
      title: 'E-Mail*',
      validation: Rule => Rule.required()
    }, {
      name: 'image',
      type: 'image',
      title: 'SEO Bild*',
      description: 'Dieses Bild wird von der Suchmaschine verwendet.',
      validation: Rule => Rule.required()
    }, {
      name: 'sharing_image',
      type: 'image',
      title: 'Social Media Bild*',
      description: 'Dieses Bild wird angezeigt, wenn jemand den Link der Website auf Social Media geteilt wird.',
      validation: Rule => Rule.required()
    }, {
      name: 'gigs_image',
      type: 'image',
      title: 'Hero-Image: Gigs',
      description: 'Test test',
      validation: Rule => Rule.required()
    }
  ]
}
Aug 29, 2022, 9:41 PM
Have you added an image and published the document?
Aug 29, 2022, 9:41 PM
yes
Aug 29, 2022, 9:41 PM
I can access the asset url, if I do it the other way
Aug 29, 2022, 9:42 PM
In this query:
const filter = groq`*[_type == "siteSettings"]`;
  const projection = groq`{email, "image": image.asset->url, "sharing_image": sharing_image.asset->url, "gigs_image": gigs_image.asset->url}`;
  const query = [filter, projection].join(' ');
  const sanitySettings = await client.fetch(query).catch(error => console.error(error));
  const staticSettings = {
    domain: process.env.URL || '<http://localhost:8080>',
    thisYear: format(new Date(), 'yyyy'),
  };
  const settings = {...sanitySettings[0], ...staticSettings};
Aug 29, 2022, 9:42 PM
but I don't want all of this other stuff from the data, I only want that one, single
gigs_image
Aug 29, 2022, 9:42 PM
*[_type == "siteSettings"]
will return an array. Can you please try RD’s suggestion but slicing the first document?

*[_type == "siteSettings"][0].gigs_image.asset->.url
(Edit: Though I’d still be surprised you get a
null
response. I’d at least expect an array.)
Aug 29, 2022, 10:21 PM
it still returns `null`:/
Aug 30, 2022, 7:43 AM
Would you mind showing the return from
*[_type == "siteSettings"]
in Vision? For you to get data from
*[_type == "siteSettings"]{gigs_image}
but null from ``*[_type == "siteSettings"].gigs_image` means we must be misunderstanding something in your configuration.
Aug 30, 2022, 3:32 PM
this is what it returns:
[
  {
    _createdAt: '2019-03-29T10:09:19Z',
    _id: 'siteSettings',
    _rev: 'ns3tjWS9mvqkIfdQ8S1ltp',
    _type: 'siteSettings',
    _updatedAt: '2022-08-29T19:35:34Z',
    email: '',
    gigs_image: { _type: 'image', asset: [Object] },
    image: { _type: 'image', asset: [Object] },
    sharing_image: { _type: 'image', asset: [Object] }
  }
]
Aug 30, 2022, 3:57 PM
wait.. I am not sure what "Vision" is
Aug 30, 2022, 4:00 PM
Vision is a plugin in the Studio that lets you run GROQ queries quickly, but the above is equivalent to what you would have gotten there. 👍
Could you please post your snippet of code showing how you’re implementing the naked projection (i.e.,
*[_type == "siteSettings"][0].gigs_image
or something similar rather than using a projection) using the
filter
,
query
,
settings
, etc. in your previous posts?
Aug 30, 2022, 4:06 PM
I am not sure I fully understand what you mean. Here's my entire code, that I am using right now.
const query = groq`*[_type == "siteSettings"]{"url": gigs_image.asset->url}`;
  const image = await client.fetch(query).catch(error => console.error(error));
  
  return image[0].url;
This gives me what I want, but I don't understand why I can't just query do it without the
"url"
, it seems unnecessary
Aug 30, 2022, 4:15 PM
but maybe this is just how groq works? I really don't know
Aug 30, 2022, 4:15 PM
sorry I can't get syntax highlighting to work in slack? Idk what's going on
Aug 30, 2022, 4:16 PM
What does this give you?

const query = groq`*[_type == "siteSettings"][0].gigs_image.asset->url`;
  const image = await client.fetch(query).catch(error => console.error(error));
  
  return image;
Aug 30, 2022, 6:20 PM
Sorry for the late reply! It gives me back this:
[
  {
    url: '<https://cdn.sanity.io/images/gpygc6vl/production/a7f555027d8a791d9b4dd2915bf4ecbcb3019d36-1600x1600.webp>'
  }
]
Sep 1, 2022, 6:44 AM
Interesting. Is your client configured on
v1
(or with no
apiVersion
in the config) by chance?
Sep 1, 2022, 2:45 PM
user M
considered this a while ago and advised me to add `apiVersion: '2022-08-29'`to the client-config, which I did!
Sep 1, 2022, 3:03 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?