Using a reference field to generate a slug in Sanity Studio.

6 replies
Last updated: Apr 17, 2024
Hi! Is it possible to dereference something inside the studio? I have a document with a slug field, that I want to base on a different field in the document (a reference). I want to do something like this:
defineField({
    title: "Slug",
    name: "slug",
    type: "slug",
    options: {
        source: 'field_that_references_other_page',
        slugify: (input: string, schema, context) => {
           // .. use data from other_page chosen by context.parent.field_that_references_other_page
        }
AI Update

Yes, you can absolutely dereference a reference field inside the Studio to use it in your slug generation! The key is using the getClient() method available in the slugify function's context parameter.

Here's how you can accomplish this:

import {defineField} from 'sanity'

defineField({
  title: "Slug",
  name: "slug",
  type: "slug",
  options: {
    source: 'field_that_references_other_page',
    slugify: async (input, schemaType, context) => {
      const client = context.getClient({apiVersion: '2024-01-01'})
      const refId = context.document.field_that_references_other_page._ref
      
      if (!refId) return input
      
      // Fetch the referenced document
      const referencedDoc = await client.fetch(
        `*[_id == $refId][0]`,
        {refId}
      )
      
      // Use data from the referenced document
      // For example, use its title field
      const slugSource = referencedDoc?.title || input
      
      // Slugify the value (you can use a library or custom logic)
      return slugSource
        .toLowerCase()
        .replace(/\s+/g, '-')
        .replace(/[^\w-]+/g, '')
    }
  }
})

Key points:

  1. The slugify function is async - This allows you to fetch data from the Content Lake
  2. Access getClient() from context - As mentioned in the Sanity reference type documentation, the context parameter provides a getClient() method that you can use to fetch referenced documents
  3. Access the reference ID - Use context.document.field_that_references_other_page._ref to get the ID of the referenced document
  4. Fetch the referenced document - Use the client to query your referenced document with GROQ
  5. Custom slugification - You'll need to implement your own slugify logic (Sanity Studio uses speakingurl internally, but you can use any approach)

If you want to use a more robust slugification library, you can install slugify or speakingurl:

npm install slugify

Then use it in your function:

import slugify from 'slugify'

// ... in your slugify function:
return slugify(slugSource, {lower: true, strict: true})

This approach gives you full flexibility to dereference any field from the referenced document and use it to generate your slug. The slug field documentation covers the basics, and there are community examples of using references with slug generation that demonstrate similar patterns.

export async function parentSlugify(_input_: any) {

const parentQuery = '*[_id == $id][0]'

const parentQueryParams = {

id: _input_.doc.parent?._ref || '',

}


const parent = await client.fetch(parentQuery, parentQueryParams)


const parentSlug = parent?.slug?.current ? parent.slug.current : ''

const pageSlug = _input_.doc.title.toLowerCase().replace(/\s+/g, '-').slice(0, 200)


if (!parentSlug) {

return slugify(pageSlug)

}

`return `${slugify(parentSlug)}/${slugify(pageSlug)}``

}

And then in your slug:


slugify: parentSlugify
You'd probably have to change around the parentQueryParams, but that should do the trick
Thank you so much! I was afraid calling
client.fetch
in the studio would cause some sort of crazy loop, but apparently it doesn’t haha. I’ll try this!
This (I believe), will only run once, when you click generate.
It works like a charm! Thank you Liam 🙂
For me sanity replaces the slash in my slug with a dash "/" to "-" and i cant seem to fix this issue. Any help?

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.

Was this answer helpful?