Help with generating a slug based on attributes in a Next.js FrontEnd using Sanity.io
5 replies
Last updated: Mar 7, 2023
Y
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
Y
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
D
awesome
user S
😊Mar 7, 2023, 2:08 PM
D
May I suggest some improvements to your code?
So instead of triple
So instead of triple
awaitcalls, 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
D
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.