Brand Voice Validator Function

Official(made by Sanity team)

By Ken Jones Pizza

Generate content changes for a piece of content

schemaTypes/post.ts

defineField({
  name: 'suggestedChanges',
  title: 'Suggested Changes',
  type: 'text',
  readOnly: () => true, // This is optional
  description: 'Content suggestions will be automatically generated when you publish a post',
}),

functions/brand-voice-validator/index.ts

import {createClient} from '@sanity/client'
import {documentEventHandler} from '@sanity/functions'

export const handler = documentEventHandler(async ({context, event}) => {
  const {data} = event
  const {local} = context // local is true when running locally

  const client = createClient({
    ...context.clientOptions,
    apiVersion: 'vX',
    useCdn: false,
  })

  const brandsWritingStyleGuide = `
# Brand Style Guide

## Voice and Tone
Keep the language casual, clear, and friendly. Speak directly to readers as "you."

- **Casual yet Professional:** Informal enough to feel personal but always trustworthy.
- **Inclusive and Welcoming:** Assume readers are curious but not experts.
- **Light-hearted and Enthusiastic:** Keep enthusiasm genuine.

## Language and Vocabulary
- **Jargon:** Use sparingly. Always briefly explain technical terms.
- **Examples:** Offer relatable, real-life analogies or scenarios.
- **Tone:** Optimistic, helpful, and down-to-earth.

## Headlines and Subheadings
- **Clear and Engaging:** Capture interest without clickbait.
- **Friendly and Informative:** Indicate clearly what readers will learn.

## Formatting and Structure
- **Short Paragraphs:** 2–3 sentences maximum for readability.
- **Bullet Points and Lists:** Use liberally to break down complex ideas clearly.
`

  try {
    const result = await client.agent.action.generate({
      noWrite: local ? true : false, // if local is true, we don't want to write to the document, just return the result for logging
      instructionParams: {
        content: {
          type: 'field',
          path: 'content',
        },
        brandsWritingStyleGuide: {
          type: 'constant',
          value: brandsWritingStyleGuide,
        },
      },
      instruction: `Examine the $content. Using the $brandsWritingStyleGuide, list specific changes that the author should make to improve the content. Start each suggestion with a dash and be concise.`,
      target: {
        path: 'suggestedChanges',
      },
      conditionalPaths: {
        defaultReadOnly: false,
      },
      documentId: data._id,
      schemaId: '_.schemas.default',
      forcePublishedWrite: true,
    })
    console.log(
      local
        ? 'Generated content suggestions (LOCAL TEST MODE - Content Lake not updated):'
        : 'Generated content suggestions:',
      result.suggestedChanges,
    )
  } catch (error) {
    console.error('Error occurred during content suggestions generation:', error)
  }
})

sanity.blueprint.ts

import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'

export default defineBlueprint({
  resources: [
    defineDocumentFunction({
     type: 'sanity.function.document',
     name: 'brand-voice-validator',
     src: './functions/brand-voice-validator',
     memory: 2,
     timeout: 60,
     event: {
       on: ['create', 'update'],
        filter:
          "_type == 'post' && defined(content) && (delta::changedAny(content) || delta::operation() == 'create')",
        projection: '{_id}',
     },
   }),
  ],
})

This Sanity Function addresses a critical content management challenge: ensuring brand consistency across your content library. Content creators often struggle to maintain alignment with brand guidelines, leading to inconsistent voice and missed opportunities for optimization across your editorial workflow.

Quick Start

View full instructions and source code.

Initialize blueprints if you haven't already: npx sanity blueprints init

Then: npx sanity blueprints add function --example brand-voice-validator

Then deploy: npx sanity blueprints deploy

How It Works

When a content editor publishes a new blog post, the function automatically:

  • Triggers on the publish event for post documents
  • Analyzes the post's (or desired field's) content field against built-in brand style guidelines
  • Generates specific, actionable improvement suggestions using AI
  • Writes feedback to a dedicated suggestedChanges field in the document
  • Provides immediate, non-intrusive editorial guidance

Key Benefits

  • Maintains brand voice consistency across all content
  • Provides instant feedback on writing style and structure
  • Reduces editorial review time by flagging issues automatically
  • Scales brand guideline enforcement as your team grows
  • Improves content quality through AI-powered suggestions
  • Enables self-service content optimization for creators

Technical Implementation

The function uses Sanity's AI Agent Actions to analyze portable text content against comprehensive brand guidelines. It's built with:

  • Event-driven architecture (triggers on document publish)
  • Built-in brand style guide emphasizing professional yet casual tone
  • Non-intrusive feedback system using dedicated schema fields
  • Comprehensive error handling and logging

Perfect For

  • Content teams needing consistent brand voice enforcement
  • Organizations with specific style guide requirements
  • Editorial workflows requiring automated quality checks
  • Brands scaling content production across multiple creators

The function works with any Sanity project and can be customized to match your specific brand guidelines and content requirements.

Contributor

Official Recipes by Sanity

First Published Timestamp Function

Featured contribution
Official(made by Sanity team)

Automatically track when content was first published with a timestamp that sets once and never overwrites, providing reliable publication history for analytics and editorial workflows.

Knut Melvær
Go to First Published Timestamp Function

Automatically tag blog posts

Featured contribution
Official(made by Sanity team)

AI-powered automatic tagging for Sanity blog posts that analyzes content to generate 3 relevant tags, maintaining consistency by reusing existing tags from your content library.

Go to Automatically tag blog posts