npm package: @gearbox-built/sanity-structured-data
Description: A Sanity plugin that enables easy implementation of JSON-LD structured data using Schema.org vocabulary.
Author: Gearbox Built
Latest version: 0.5.1

# ⚡️ Sanity Structured Data

A Sanity plugin that enables easy implementation of JSON-LD structured data using Schema.org vocabulary.

> Inspired by Operation Nation's [`sanity-plugin-schema-markup`](https://github.com/Operation-Nation/sanity-plugin-schema-markup) plugin.

## Installation

```sh
npm install @gearbox-built/sanity-structured-data
```

## Sanity Usage

Add it as a plugin in `sanity.config.ts` (or .js):

### Basic Implementation

```ts
// sanity.config.ts
import {defineConfig} from 'sanity'
import {structuredData} from '@gearbox-built/sanity-structured-data'

export default defineConfig({
  //...
  plugins: [structuredData()],
})
```

Add the `structuredData` schemaField to your document:

```ts
const page = {
  type: 'document',
  name: 'Page',
  fields: [
    {
      title: 'Structured Data',
      name: 'structuredData',
      type: 'structuredData',
    },
  ],
}
```

Or if you're using [`@gearbox-built/sanity-schema-tool`](https://www.npmjs.com/package/@gearbox-built/sanity-schema-tool):

```ts
import {F} from '@gearbox-built/sanity-schema-tool'
const page = F.document({
  name: 'Page',
  fields: [F.field('structuredData')],
})
```

### Config Options

```ts
structuredData({
  apiVersion: '',
  types: {
    article: {},
    webSite: {},
    webPage: {},
    //...
  },
  queries: {
    company: '',
    websiteDescription: '',
    //...
  },
})
```

#### `apiVersion`

**Default: `v2021-03-25`**

Sanity API version.

#### `types`

Schema type overrides map. Replaces Sanity schema for the respective Schema.org schema type.

> **Note:** Directly overrides default schema structure. Use [Types Helpers](#helpers) for default schema structure.

#### `queries`

Query overrides map. Default GROQ queries for schema fields that query the Sanity dataset for values (query fields).

---

### Helpers

To make customization more simple, default schema, types, fields, utilites.

#### Types

Default schema types (ie. `WebPage`, `WebSite`, etc.).

```ts
import {types} from '@gearbox-built/sanity-structured-data'
const {webPage, videoObject} = types

console.log(webPage)
// {
//   type: 'object',
//   name: 'WebPageDataType',
//   title: 'WebPage',
//   fields: [ ... ]
//   //...
// }
```

#### Fields

Default schema types and custom [Schema Tool](https://www.npmjs.com/package/@gearbox-built/sanity-schema-tool) fields as field fuctions.

> Supports merging props with full TypeScript support.

```ts
import {fields} from '@gearbox-built/sanity-structured-data'
const {webPage} = fields

console.log(webPage({title: 'Definitely Not WebPage'}))
// {
//   type: 'object',
//   name: 'WebPageDataType',
//   title: 'Definitely Not WebPage', // ← Prop merged
//   fields: [ ... ]
//   //...
// }
```

#### Structured Data Config

For more complex configuration needs, abstracting configuration may be desired. To assist with this, you can use the `structuredDataConfig` helper:

```ts
// sanity.config.ts
import {defineConfig} from 'sanity'
import {structuredData} from '@gearbox-built/sanity-structured-data'
import {config} from './structuredDataConfig'

export default defineConfig({
  //...
  plugins: [structuredData(config)],
})
```

```ts
// structuredDataConfig.ts
import {structuredDataConfig, types} from '@gearbox-built/sanity-structured-data'
import {F} from '@gearbox-built/sanity-schema-tool'

// WebSite schema additions
const {fields: webSiteFields, ...webSiteType} = types.webSite

const webSiteAdditionalFields = [
  F.string({name: 'about', description: 'The subject matter of the content.'}),
]

const webSite = {
  ...webSiteType,
  title: 'Definitely Not WebSite',
  fields: webSiteFields.toSpliced(2, 0, ...webSiteAdditionalFields), // Order fields
}

export const config = structuredDataConfig({
  types: {
    webSite, // Replaces default WebSite schema
  },
  queries: {
    company: `*[_type == 'settings'][0].companyName`,
  },
})
```

## Frontend Component

Render your structured data markup in your React/Next.js app. Can be used with or without the `structuredData` Sanity schema.

```tsx
import StructuredData, {Schema} from '@gearbox-built/sanity-structured-data/component'

type Props = {
  structuredData: Schema[]
}

const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID
const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET

const SchemaMarkup = ({structuredData}: Props) => (
  <StructuredData data={structuredData} projectId={projectId} dataset={dataset} />
)

export default SchemaMarkup
```

## License

[MIT](LICENSE) © Gearbox Development Inc.

## Develop & test

This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
with default configuration for build & watch scripts.

See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
on how to run this plugin with hotreload in the studio.