How to handle duplicate slugs with different parent pages in a client website.

11 replies
Last updated: Dec 15, 2022
Hi everyone, I have a client website with alot of pages, most have parent pages which will alter the slug so technically they are all different but the page slug itself may be duplicated across pages e.g. a page will have a slug of 'north-east' but they will all have different parents. I've tried to change the validation to return true if the there is only 1 occurence of the slug with a parent but it still returns the error of 'Slug is already in use' Any ideas how I can get around this?
Here is my current slug, parentPage code:


{
			name: 'slug',
			title: 'Slug',
			type: 'slug',
			options: {
				source: 'name',
				slugify: (input) =>
					input
						.toLowerCase()
						//Remove spaces
						.replace(/\s+/g, '-')
						//Remove special characters
						.replace(/[&\/\\#,+()$~%.''":*?<>{}]/g, ''),
			},
			validation: Rule => Rule.custom((slug, section) => {
				console.log(slug, section.parent.parentPage._ref)
				let parentRef = '*[_type=="pillar" && slug.current == $slug]{parentPage{_ref}}'
				const params = {slug: slug.current}
				return sanityClient.fetch(parentRef, params).then(matchingParents => {
					let count = 0;
					console.log({matchingParents})
					matchingParents.forEach(page => {
						page.parentPage._ref === section.parent.parentPage._ref ? count++ : count
					})

					console.log({count})
					if(count === 1) {
						return true
					} else {
						return false
					} 
				})
			})
		},

		{
			name: 'parentPage',
			title: 'Parent Page',
			type: 'reference',
			to: [{ type: 'pillar' }],
			// This ensures we cannot select other "children"
			options: {
				filter: '!defined(parentPage)',
			},
		},
Dec 5, 2022, 1:57 PM
I also tried using
isUnique
but it then didn't do any validation, this one has me stumped!
Dec 6, 2022, 9:32 AM
Bumping
Dec 7, 2022, 8:15 AM
If the above isn't possible, is there a way to completely remove validation on a slug or would it have to be a string field instead?
Dec 9, 2022, 1:50 PM
You may just be returning a promise. It also might be an issue that you're returning false instead of a string.
validation: Rule => Rule.custom(async (slug, section) => {
				const query = '*[_type=="pillar" && slug.current == $slug].parentPage._ref'
				const params = {slug: slug.current}
				const parentRefs = await sanityClient.fetch(query, params)

        return parentRefs.filter(parentRef => parentRef === section.parent.parentPage._ref).length === 1 ? true : 'This slug is already in use'
        
			})
Dec 9, 2022, 5:39 PM
Hi
user M
thanks for your help, I'm still learning my way around groq queries! Unfortunately when I used the above code I'm getting an error of
flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.
Dec 12, 2022, 8:44 AM
If I click on the tooltip at the top of the document it gives the original error of 'Slug is in use' and when I hover over the tooltip beside the slug field it causes the flushSync error, any ideas?
Dec 12, 2022, 8:47 AM
If I click on the tooltip at the top of the document it gives the original error of 'Slug is in use' and when I hover over the tooltip beside the slug field it causes the flushSync error, any ideas?
Dec 12, 2022, 8:48 AM
is there a way to override the original slug validation that comes with sanity?
Dec 15, 2022, 1:50 PM
Lookup isUnique method
Dec 15, 2022, 1:59 PM
brilliant, thank you! I was doing validation or isUnique, turns out I needed them both! Thank you so much, this was driving me crazy!
Dec 15, 2022, 3:29 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?