Skip to main content
seofields
docs
.md

HowTo

Add HowTo structured data to your Sanity-powered site to describe step-by-step instructions in a machine-readable way. Google no longer shows HowTo rich results, but the markup is still valid Schema.org and can help other consumers understand the steps.

About HowTo

HowTo schema describes real step-by-step instructions that are visible on the page. It can help search engines and answer systems understand procedural content, but rich result display and AI citations are not guaranteed. Use it when the page genuinely teaches users how to complete a task.

Fields

FieldTypeRequiredDescription
namestring✓The name of the how-to guide.
descriptionstring—A description of what the how-to guide covers.
imagestring | object—Image for this how-to guide — a URL string or a full ImageObject.
totalTimestring—Total time to complete in ISO 8601 duration format (e.g. "PT30M" for 30 minutes).
estimatedCost.currencystring—ISO 4217 currency code for the estimated cost, e.g. "USD".
estimatedCost.valuestring—The estimated cost amount, e.g. "25.00".
supply[].namestring—Name of a supply needed for this how-to.
tool[].namestring—Name of a tool needed for this how-to.
step[].namestring✓The name/title of this step.
step[].textstring—Detailed instructions for this step.
step[].urlstring—URL for this specific step, if applicable.
step[].imagestring—URL of an image illustrating this step.

Plugin Registration

sanity.config.ts
import { defineConfig } from "sanity";
import { schemaOrgHowToPlugin } from "sanity-plugin-seofields/schema";

export default defineConfig({
  // ... your project config
  plugins: [
    schemaOrgHowToPlugin(),
  ],
});

Schema Usage

Add the schemaOrgHowTo field to any document schema:

schemas/page.ts
import { defineField, defineType } from 'sanity'

export default defineType({
  name: 'page',
  title: 'Page',
  type: 'document',
  fields: [
    // ... your other fields
    defineField({
      name: 'schemaOrgHowTo',
      title: 'How-To Schema',
      type: 'schemaOrgHowTo',
    }),
  ],
})

GROQ Query

GROQ query
*[_type == "yourDocument"][0]{
  schemaOrgHowTo {
    name,
    description,
    image,
    totalTime,
    estimatedCost {
      currency,
      value
    },
    supply[] {
      name
    },
    tool[] {
      name
    },
    step[] {
      name,
      text,
      url,
      image
    }
  }
}

Next.js Component

app/layout.tsx
import { HowToSchema } from "sanity-plugin-seofields/schema/next";

export default function Layout({ children }: { children: React.ReactNode }) {
  // Fetch your HowTo data from Sanity
  const tutorial = await sanityClient.fetch(query);

  return (
    <html lang="en">
      <body>
        <HowToSchema data={tutorial.howTo} />
        {children}
      </body>
    </html>
  );
}

JSON-LD Output

Generated JSON-LD
{
  "@context": "https://schema.org",
  "@type": "HowTo",
  "name": "How to Make Homemade Pasta",
  "description": "A step-by-step guide to making fresh pasta from scratch.",
  "image": "https://example.com/pasta.jpg",
  "totalTime": "PT45M",
  "estimatedCost": {
    "@type": "MonetaryAmount",
    "currency": "USD",
    "value": "5.00"
  },
  "supply": [
    { "@type": "HowToSupply", "name": "All-purpose flour" },
    { "@type": "HowToSupply", "name": "Eggs" }
  ],
  "tool": [
    { "@type": "HowToTool", "name": "Rolling pin" },
    { "@type": "HowToTool", "name": "Pasta machine" }
  ],
  "step": [
    {
      "@type": "HowToStep",
      "name": "Make the dough",
      "text": "Combine flour and eggs on a clean surface and knead into a smooth dough.",
      "url": "https://example.com/pasta#step1",
      "image": "https://example.com/pasta-step1.jpg"
    },
    {
      "@type": "HowToStep",
      "name": "Roll out the pasta",
      "text": "Using a rolling pin or pasta machine, roll the dough to 2mm thickness.",
      "url": "https://example.com/pasta#step2",
      "image": "https://example.com/pasta-step2.jpg"
    }
  ]
}

Was this page helpful?