🎤 Builder Talk: The Story Behind Lady Gaga’s Digital Experience – Register now

Adding Jump Links to Page Modules

By Mitchell Christ

Use modules to build your pages? Want to grab a link to a specific module? This schema is just for you!

How to add to your module

export default defineType({
  name: 'module-name',
  ...
  fields: [
    ...
    defineField({
      name: 'uid',
      title: 'Unique Identifier',
      type: 'uid',
      group: 'options',
    }),
  ],
})

The helper function (/lib/uid.ts)

export default function ({ uid = undefined, _key }) {
  return uid || _key
}

The frontend (React / Next.js)

import uid from '@/lib/uid'

export default function YourModuleComponent({ ...props }) {
  return (
    <section
      id={uid(props)}
      className="..."
    >
      ...
    </section>
  )
}

Schema + Input component

import { useState } from 'react'
import { defineType } from 'sanity'
import { Box, Button, Flex, Text, TextInput } from '@sanity/ui'
import { VscCheck, VscCopy } from 'react-icons/vsc'

export default defineType({
	name: 'uid',
	title: 'Unique Identifier',
	description: 'Used for anchor/jump links (HTML `id` attribute).',
	type: 'string',
	validation: (Rule) =>
		Rule.regex(/^[a-zA-Z0-9-]+$/g).error(
			'Must not contain spaces or special characters',
		),
	components: {
		input: ({ elementProps, path }) => {
			const indexOfModule = path.indexOf('modules')
			const moduleKey = (path[indexOfModule + 1] as any)?._key
			const [checked, setChecked] = useState(false)

			return (
				<Flex gap={1} align="center">
					<Text muted>#</Text>

					<Box flex={1}>
						<TextInput {...elementProps} placeholder={moduleKey} radius={2} />
					</Box>

					<Button
						title="Click to copy"
						mode="ghost"
						icon={checked ? VscCheck : VscCopy}
						disabled={checked}
						onClick={() => {
							navigator.clipboard.writeText(
								'#' + elementProps.value || moduleKey,
							)

							setChecked(true)
							setTimeout(() => setChecked(false), 1000)
						}}
					/>
				</Flex>
			)
		},
	},
})

👉 Read the original article on the SanityPress Blog

This uid schema+input component is part of SanityPress, a Next.js starter template with Tailwind CSS and pre-built schema.

You can find the source code for the uid here for easy copy and paste (no npm install necessary!)

Contributor

Other schemas by author

Text Input with Presets

Want to add some preset buttons/chips below your text input field? Look no further!

Mitchell Christ
Go to Text Input with Presets