👋 Next.js Conf 2024: Come build, party, run, and connect with us! See all events

Help with generating a slug based on attributes in a Next.js FrontEnd using Sanity.io

5 replies
Last updated: Mar 7, 2023
Hi all, I wanted to know if someone can help me with this, I am usin*g V3* in Next.js FrontEnd and I want in my product.js schema to generate my Slug based on attributes, example
*slug* = name+color+material+style.


export default defineType({
  name: 'product',
  title: 'Products',
  type: 'document',
  icon: IconPackage,
  description: 'A product that is available for rent',
  fields: [
    defineField({
      name: 'name',
      title: 'Name',
      type: 'string',
      description: 'The name of the product',
      validation: (Rule) => Rule.required()
    }),
    defineField({
      name: 'description',
      title: 'Description',
      type: 'string',
      description: 'The description of the product'
    }),
    defineField({
      name: 'sku',
      title: 'SKU',
      type: 'string',
      description: 'The SKU of the product'
    }),
    defineField({
      name: 'category',
      title: 'Category',
      type: 'reference',
      to: [{ type: 'category' }],
      description: 'The category of the product',
      validation: (Rule) => Rule.required()
    }),
    defineField({
      name: 'properties',
      title: 'Properties',
      type: 'object',
      description: 'The properties of the product',
      fields: [
        {
          name: 'color',
          type: 'reference',
          description: 'The color of the product',
          to: [{ type: 'color' }]
        },
        {
          name: 'material',
          type: 'reference',
          description: 'The material of the product',
          to: [{ type: 'material' }]
        },
        {
          name: 'style',
          type: 'reference',
          description: 'The style of the product',
          to: [{ type: 'style' }]
        },
        {
          name: 'size',
          description: 'The size of the product',
          type: 'string'
        }
      ]
    }),
   .....
    defineField({
      name: 'slug',
      title: 'Slug',
      type: 'slug',
      description: 'The slug for the product',
      options: {
        source: 'name'
      },
      validation: (Rule) => Rule.required()
    })
  ],
})

Mar 6, 2023, 6:05 PM
Have you tried setting up your source and slugify options ?
Mar 6, 2023, 9:36 PM
Thanks, in the end I tried slugify and I implemented it like this

async function SlugWithNameColorMaterialStyle(input, schemaType, context) {
  const { getClient, parent } = context
  const { name, color, material, style } = parent
  const client = getClient({
    apiVersion: process.env.NEXT_PUBLIC_SANITY_API_VERSION
  })
  const colorName = await client.fetch(`*[_id == $id][0].name`, {
    id: color._ref
  })
  const materialName = await client.fetch(`*[_id == $id][0].name`, {
    id: material._ref
  })
  const styleName = await client.fetch(`*[_id == $id][0].name`, {
    id: style._ref
  })
  return slugify(
    `${name && name}-${colorName && colorName}-${
      materialName && materialName
    }-${styleName && styleName}`,
    {
      lower: true
    }
  )
} 
Mar 7, 2023, 1:46 PM
awesome
user S
😊
Mar 7, 2023, 2:08 PM
May I suggest some improvements to your code?
So instead of triple
await
calls, you could improve with something like below:

const [colorName, materialName, styleName] = await Promise.all([
    client.fetch(`*[_id == $id][0].name`, {
      id: color._ref
    }),
    client.fetch(`*[_id == $id][0].name`, {
      id: material._ref
    }),
    client.fetch(`*[_id == $id][0].name`, {
      id: style._ref
    })
  ])

Mar 7, 2023, 2:10 PM
That’ll allow things to run in parallel. I hope it helps! 😊
Mar 7, 2023, 2:11 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?