Skip to content

Instantly share code, notes, and snippets.

@nickeforsberg
Last active October 20, 2023 08:33
Show Gist options
  • Save nickeforsberg/cc15c8d4875c9d4b10ba442dcac4ee27 to your computer and use it in GitHub Desktop.
Save nickeforsberg/cc15c8d4875c9d4b10ba442dcac4ee27 to your computer and use it in GitHub Desktop.
Child pages with parent in Sanity (Hook + page schema)
import sanityClient from 'part:@sanity/base/client';
// Slugify function from https://gist.github.com/mathewbyrne/1280286 for fixing some weird letters etc
function slugify(str) {
str = str.replace(/^\s+|\s+$/g, ''); // trim leading/trailing white space
str = str.toLowerCase(); // convert string to lowercase
str = str.replace(/[^a-z0-9 -]/g, '') // remove any non-alphanumeric characters
.replace(/\s+/g, '-') // replace spaces with hyphens
.replace(/-+/g, '-'); // remove consecutive hyphens
return str;
}
// This function is exported and used in the schema for the slug field
export async function asyncSlugifier(input) {
const client = sanityClient.withConfig({
apiVersion: process.env.SANITY_STUDIO_API_VERSION || '2021-10-13', // Using the Sanity client without specifying the API version is deprecated
});
const parentQuery = '*[_id == $id][0]'; // a GROQ query, feel free to change this up to match what you need
const parentQueryParams = {
id: input.doc.parent?._ref || '',
};
const parent = await client.fetch(
parentQuery,
parentQueryParams,
);
const parentSlug = parent?.slug?.current ? `${parent.slug.current}/` : ''; // if there's no parent assign an empty string, it will make the function return the current slug as the root
const pageSlug = slugify(input.doc.title)
.toLowerCase()
.replace(/\s+/g, '-') // slugify the title using a simple regex
.slice(0, 200);
return `${parentSlug}${pageSlug}`;
}
import { MdOutlineLibraryBooks } from 'react-icons/md'
import { asyncSlugifier } from '../hooks/asyncSlugifier'
export default {
title: 'Pages',
name: 'page',
type: 'document',
icon: MdOutlineLibraryBooks,
fields: [
{
name: 'title',
title: 'Title',
type: 'string',
},
{
name: 'parent', // <-- this is a reference to another document
type: 'reference',
to: [
{
type: 'page'
}
]
},
{
name: 'slug',
type: 'slug',
title: 'Slug (permalink)',
description: 'If changing URL slug, you may have to change the links (like buttons) pointing to that page.',
validation: Rule => Rule.required(),
options: {
source: (doc, options) => ({ doc, options }),
maxLength: 96,
slugify: asyncSlugifier, // you'll define this in a minute
}
},
{
name: 'blocks',
title: 'Blocks',
type: 'blocks'
},
{
title: 'SEO / Share Settings',
name: 'seo',
type: 'seo'
}
],
}
@nickeforsberg
Copy link
Author

PS. This is only for the backend part in Sanity.

@nickeforsberg
Copy link
Author

nickeforsberg commented Jun 15, 2023

You need to use spread dynamic route in nextjs and taking care of slugs coming as an array! like [....slug].js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment