šŸ‘‹ Next.js Conf 2024: Come build, party, run, and connect with us! See all events

Trouble getting the slug from an internal link in a Sanity query

14 replies
Last updated: Aug 9, 2023
Can anyone help? I run this query trying to get the slug from internal link

*[_type == "page" && _id == "c57c9277-0669-4bf3-8cba-f6fc16a90955"]{
  _id,
  _createdAt,
  title,
  "slug": slug.current,
  pageBuilder[]{
    _key,
    _type,
    ...,
    cta{
      preHeading,
      heading,
      description,
      button {
        text,
        link {
          internalLink->{
            "slug": slug.current
          },
        }
      },
    },
  }
}
But i get back I still only get back _type: reference and _ref: b2971fe5-7509-4630-8519-0c107fe1a876 with no slug? What am i doing wrong here?
Aug 5, 2023, 12:36 PM
I think you need to do a join query to get the reference details, they aren't included by default in the query.
Aug 5, 2023, 8:46 PM
user L
I'm not too sure where to put my join query as button is an object that comes from an external button-schema.ts and included in my cta schema. If i create an internal link inside cta {not as an external object} i can access the slug but because button is an object this is where i am having trouble. Any help would be much appreciated as have been blocked for days on this!
Aug 6, 2023, 9:18 PM
Would you be able to share your code for the button and cta schema? I am specifically interested in the type definition for button and cta schemas, how you are referencing the cta in the button schema, as well as the slug field in cta.
Aug 8, 2023, 4:52 PM
user F
your help would be highly appreciated. Code as follows:
Button schema


import { defineType } from "sanity";

export const button = defineType({
  name: "button",
  type: "object",
  title: "Button",
  fields: [
    {
      name: "text",
      type: "string",
      title: "text",
    },
    {
      name: "link",
      type: "object",
      title: "Link",
      fields: [
        {
          name: "externalLink",
          type: "object",
          title: "External link",
          fields: [
            {
              name: "href",
              type: "url",
              title: "URL",
            },
            {
              title: "Open in new tab",
              name: "blank",
              description: "Read <https://css-tricks.com/use-target_blank/>",
              type: "boolean",
            },
          ],
          // hidden: ({ parent, value }) => !value && parent?.internalLink
        },
        {
          name: "internalLink",
          type: "object",
          title: "Internal link",
          // hidden: ({ parent, value }) => !value && parent?.externalLink,
          fields: [
            {
              name: "reference",
              type: "reference",
              title: "Reference",
              to: [
                { type: "page" },
                // { type: "staticPages" },
                // other types you may want to link to
              ],
            },
          ],
        },
      ],
    },
  ],
});


Cta schema:


import { defineField, defineType, defineArrayMember } from "sanity";

export const cta = defineType({
  name: "cta",
  type: "object",
  title: "CTA Section",
  fields: [
    defineField({
      name: "preHeading",
      title: "Pre Heading",
      type: "string",
    }),
    defineField({
      name: "heading",
      title: "Main CTA heading",
      type: "string",
    }),
    defineField({
      name: "description",
      title: "Description text",
      type: "array",
      of: [{ type: "block" }],
    }),
    // Add your button schema as a reference
    defineField({
      name: "button",
      title: "Button",
      type: "button", // Use your button object type here
    }),
  ],
});
Aug 8, 2023, 4:55 PM
Thanks for sharing the code. Assuming your
pageBuilder
field definition looks like this:
defineField({
	name: 'pageBuilder',
	type: 'array',
	title: 'Page Builder',
	of: [{type: 'cta'}],
}),
A groq query like this should probably work:

*[_type == 'page' && _id == 'c57c9277-0669-4bf3-8cba-f6fc16a90955'] {
  slug,
  "Internal Slug": pageBuilder[].button.link.internalLink.reference->slug,
}
Aug 9, 2023, 9:41 AM
ah thank you this now works, fantastic! Is there a reason it does not work when nested further in the query as I had it before?
Aug 9, 2023, 9:54 AM
Btw happy if you want to point me to a resource to save you typing out a full explanation šŸ™‚
Aug 9, 2023, 9:56 AM
I am not a 100% sure but the one thing that does stand out is the fact that
internalLink
has field
Reference
of type
reference
.In groq, if you want to follow a
reference
, you will need to use the dereferencing operator
->
as documented here .More resources
here , here and here if it helps šŸ™‚
Edit: Looks like you were just missing one bit in your original GROQ query:

button{
	link {
		internalLink{
			reference->{ // <- this was missing :)
				"slug": slug.current
			}
		}
	}
}
Aug 9, 2023, 9:59 AM
Yea I understand that, thank you for the resources, this has got me past many hours trying to work it out so i'm very grateful. Thanks again!
Aug 9, 2023, 10:00 AM
regarding your edit above, it still does not work in that way, it only works if done how you first suggested at the top level of the query going through pageBuilder[] etc
Here is my edit based on what you said in your edited reply:


cta{
              preHeading,
              heading,
              description,
              button {
                text,
                link {
                  externalLink {
                    href,
                    blank
                  },
                  internalLink{
                    reference->{
                      "slug": slug.current
                    }
                  },
                }
              },
            },
But i still get back:


button:{ā€¦} 3 properties
_type:button
link:{ā€¦} 1 property
internalLink:{ā€¦} 1 property
reference:{ā€¦} 2 properties
_ref:17e91108-79d2-4243-945f-78ba22730d08
_type:reference
text:My button
hero:null
cta:null
Aug 9, 2023, 3:31 PM
Ah so based on the nesting as seen in your screenshot, can you try something like this?
*[_type == "page" && _id == "c57c9277-0669-4bf3-8cba-f6fc16a90955"]{
  "internal slug": pageBuilder[]{
    button{
      link {
        internalLink{
          reference->{
            slug
          }
        }
      }
    }
  }
}
Aug 9, 2023, 3:50 PM
This works fine, so i think that narrows it down to either the pageBuilder[] array or the cta{} object within it being the problem, for reference here is my query as a whole whith those recent edits:

*[_type == "page" && _id == "c57c9277-0669-4bf3-8cba-f6fc16a90955"]{
 _id,
          _createdAt,
          title,
          "slug": slug.current,
   "Internal Slug": pageBuilder[]{
   button{
   link{
     internalLink{
       reference->{
         slug
       }
     }
   }
   }
   },
          pageBuilder[]{
            _key,
            _type,
            ...,
            hero{
              heading,
              descriptiveHeading,
              excerpt,
              "imageUrl": image.asset->url,
              "imageAlt": image.alt,
              buttons[]{
                label,
                variant,
                link {
                  anchor,
                  internal->{
                    ...,
                    "slug": reference->slug.current
                  },
                }
              }
            },
            cta{
              preHeading,
              heading,
              description,
              button {
                text,
                link {
                  externalLink {
                    href,
                    blank
                  },
                  internalLink{
                    reference->{
                      "slug": slug.current
                    }
                  },
                }
              },
            },
            "servicesSection": servicesSection[]{
              _key,
              _type,
              preHeading,
              mainHeading,
              excerpt,
              "imageUrl": image.asset->url,
              "imageAlt": image.alt,
              "services": services[]->{
                _id,
                _createdAt,
                name,
                "slug": slug.current,
                "icon": image.asset->url,
                content,
                excerpt,
              }
            },
          }
        }

Aug 9, 2023, 3:55 PM
I think the issue is the
cta{}
bit.An easy way to verify would be to run something like this and examine the result.

*[_type == "page" && _id == "c57c9277-0669-4bf3-8cba-f6fc16a90955"]{
  pageBuilder[]
}
You will see that the nesting is as follows: pageBuilder -&gt; button -&gt; link -&gt; internalLink -&gt; reference.

I would then build on top of this one level at a time, observing the result as I go e.g. pageBuilder -&gt; button

*[_type == "page" && _id == "c57c9277-0669-4bf3-8cba-f6fc16a90955"]{
  pageBuilder[]{
    button,
  }
}
Then traverse the next level: pageBuilder -&gt; button -&gt; link

*[_type == "page" && _id == "1379eccc-b231-4b19-a523-a99c064e558d"]{
  pageBuilder[]{
    button{
      link,
    },
  }
}
And so forth till you are able to get to the final level.
Aug 9, 2023, 4:07 PM
The thing is i can get to the final level this is not a problem. The problem is deferencing the linked document ref when we get to the final level
Aug 9, 2023, 4:46 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?