Skip to content

Vyuh Structure Plugin

The Vyuh structure plugin (@vyuh/sanity-plugin-structure) is a powerful tool that helps you organize and combine Sanity schemas from multiple features into a unified master schema. This guide explains how to use the plugin effectively and how it integrates with the @vyuh/schema-core package.

Overview

When building a Vyuh application, each feature defines its schemas and exports them using the FeatureDescriptor class from @vyuh/sanity-schema-core. This approach ensures:

  1. Consistent schema organization across features
  2. Type-safe schema definitions
  3. Automatic schema registration and combination
  4. Automatic categorization of schemas by feature in the Desk Structure

The Vyuh structure plugin reads the FeatureDescriptor instances and assembles them into a single schema that can be used in your Sanity Studio. Here is how your studio would look after integrating a bunch of features. Notice the automatic grouping of schemas by feature.

Vyuh Structure Plugin

Installation

First, install the plugin package in your Sanity Studio project:

Terminal window
cd my-sanity-studio
pnpm add @vyuh/sanity-plugin-structure

Install the core schema package in your features. We are assuming that each of your feature is organized as a separate package with its own package.json.

Terminal window
cd features/my-feature
pnpm add @vyuh/sanity-schema-core

These packages provide:

  • @vyuh/sanity-schema-core: Core utilities for defining and organizing Sanity schemas, including the FeatureDescriptor class
  • @vyuh/sanity-plugin-structure: The Vyuh structure plugin that combines and organizes your feature schemas

Using FeatureDescriptor

Basic Structure

Each feature exports its schemas using a FeatureDescriptor instance. Here is an example from the conference feature:

features/conference/conference.ts
import {
BuiltContentSchemaBuilder,
FeatureDescriptor,
} from '@vyuh/sanity-schema-core'
import { DocumentDescriptor } from '@vyuh/sanity-schema-system'
import { conference } from './documents/conference'
import { session } from './documents/session'
import { speaker } from './documents/speaker'
// Export all schema types
export const schemaTypes = [conference, session, speaker]
// Export feature descriptor
export const conference = new FeatureDescriptor({
name: 'conf',
title: 'Conference Feature',
description: 'Conference management feature',
contentSchemaBuilders: [
new BuiltContentSchemaBuilder(conference),
new BuiltContentSchemaBuilder(session),
new BuiltContentSchemaBuilder(speaker),
],
})

Feature Descriptor Properties

The FeatureDescriptor accepts these key properties:

  • name: Unique identifier for the feature
  • title: Display name for the feature
  • description: Optional description
  • contents: Array of content descriptors that extend content items with additional capabilities (layouts, validations, etc.)
  • contentSchemaBuilders: Array of schema builders that define the actual schema types and their structure. Each builder corresponds to a single content type and assembles the corresponding ContentDescriptor elements into a single schema for the content-type.

Customizing Content Descriptors

For example, to add custom layouts to a content type:

features/conference/conference.ts
import { ContentDescriptor } from '@vyuh/sanity-schema-core'
import { conferenceLayout } from './layouts/conference'
// Create a custom content descriptor for conference
class ConferenceDescriptor extends ContentDescriptor {
constructor(props: Partial<ConferenceDescriptor>) {
super('conf.conference', props)
}
}
export const conference = new FeatureDescriptor({
name: 'conf',
title: 'Conference Feature',
contents: [
new ConferenceDescriptor({
layouts: [conferenceLayout],
}),
],
contentSchemaBuilders: [
new BuiltContentSchemaBuilder(conference),
// ... other schema builders
],
})

Schema Registration

In your Sanity configuration, register your features using the vyuh plugin from @vyuh/sanity-plugin-structure:

Note: The vision and media plugins are also included with the vyuh plugin.

my-sanity-studio/sanity.config.ts
import { defineConfig } from 'sanity'
import { vyuh } from '@vyuh/sanity-plugin-structure'
import { conference } from './features/conference'
import { blog } from './features/blog'
export default defineConfig([
{
name: 'default',
title: 'My Vyuh Studio',
basePath: '/',
projectId: 'your-project-id',
dataset: 'production',
plugins: [
vyuh({
features: [conference, blog],
}),
],
},
])

Best Practices

  1. Feature Namespacing: Prefix schema types with feature name (e.g., conf.session)
  2. Type Safety: Use TypeScript for schema definitions using the core types from Sanity such as defineType, defineField, etc.
  3. Modular Organization: Keep related schemas together in feature packages
  4. Documentation: Include descriptions for fields and types