@gearbox-built/sanity-path-input
v1.0.0
Published
A custom input component that syncs the slug to the path
Readme
@gearbox-built/sanity-path-input
This is a Sanity Studio v3 & v4 plugin with React 18 & 19 support.
Compatibility
- React: 18.3+ or 19.x
- Sanity Studio: v3.x or v4.x
- Node.js: 18+ (Node.js 20+ required for Sanity v4)
- TypeScript: 5.5+ with full type safety
What it does
This plugin automatically syncs your document's slug field to a path field, with support for custom path generation logic. Perfect for generating URLs with parent paths, custom routing, or complex path structures.
Installation
npm install @gearbox-built/sanity-path-inputor
yarn add @gearbox-built/sanity-path-inputImportant: Field Visibility
The path field MUST be visible whenever the slug field is visible. This is critical because the path input component only watches for slug changes when it's mounted. In Sanity Studio, React components only mount when they're visible in the UI.
If you organize fields using tabs or conditional fieldsets:
- ✅ Correct: Place
slugandpathin the same tab/fieldset - ❌ Incorrect: Place
slugandpathin different tabs
When fields are in different tabs, changing the slug won't update the path until the user navigates to the path field's tab.
Usage
Add it as a plugin in sanity.config.ts (or .js):
import {defineConfig} from 'sanity'
import PathInputPlugin from '@gearbox-built/sanity-path-input'
import generatePath from '@/utils/generatePath' // Custom async function you provide to fetch parent paths and custom routing need
export default defineConfig({
//...
plugins: [
PathInputPlugin({
generatePath, // defaults to `/${document.slug.current}`
}),
],
})Schema
import {defineField} from 'sanity'
defineField({
type: 'path',
name: 'path',
title: 'Path',
}),Schema With just the input
import {defineField} from 'sanity'
import {PathInput} from '@gearbox-built/sanity-path-input'
defineField({
type: 'string',
name: 'path',
title: 'Path',
components: {
input: PathInput
}
}),generatePath (Optional)
By default, paths are generated as /${document.slug.current}. You can customize this by providing a generatePath function to handle complex routing logic.
Simple routing by type
import type {SanityClient} from 'sanity'
export const generatePath = async ({document, client}: {document: any, client: SanityClient}) => {
switch (document._type) {
case 'post':
return `/blog/${document.slug.current}`
default:
return `/${document.slug.current}`
}
}Complex logic with parent paths
export const generatePath = async ({document, client}: {document: any, client: SanityClient}) => {
switch (document._type) {
case 'post':
case 'page':
// Custom logic to fetch parent paths recursively
return getRecursiveFetchingOfParentPaths(document, client)
default:
return `/${document.slug.current}`
}
}Requirements
- Your document schema must include a
slugfield (type:slug) for the path input to function - The slug field must be present and visible when using the path input
How it works
The path field automatically updates when the slug changes, with a 250ms debounce to prevent excessive calls to your generatePath function. This means:
- Path updates happen shortly after you finish typing the slug
- Your
generatePathfunction won't be called on every keystroke - The field is read-only to prevent manual editing (it's auto-generated)
License
MIT © Gearbox Built
Testing
This plugin includes a comprehensive test suite using Vitest:
# Run all tests
yarn test
# Run tests in watch mode
yarn test:watch
# Run tests with coverage
yarn test:coverage
# Run tests with UI
yarn test:ui
# Type-check without building
yarn type-checkDevelop & test
This plugin uses @sanity/plugin-kit with default configuration for build & watch scripts.
See Testing a plugin in Sanity Studio on how to run this plugin with hotreload in the studio.
Development Commands
# Build the plugin
yarn build
# Build in watch mode
yarn watch
# Link and watch for testing in a Sanity Studio
yarn link-watch