Skip to content

Product builder

Creates Product metadata with offers, ratings, reviews, and identifiers. The Product builder injects @type, validates synchronously, and rejects unknown properties.

// Astro — shown first when Astro is selected
import { Product } from '@unschema-graph/astro';
// Svelte 5
import { Product } from '@unschema-graph/svelte';
// Core / Node.js
import { Product } from '@unschema-graph/core';
import { ProductSchema } from '@unschema-graph/core';

The ProductSchema Zod schema is also exported for composition and advanced validation.

import {
ProductSchema,
type SchemaInput,
type SchemaOutput,
} from '@unschema-graph/core';
type ProductInput = SchemaInput<typeof ProductSchema>;
type ProductOutput = SchemaOutput<typeof ProductSchema, 'Product'>;
Property Input type Required Default / constraints
@id string No non-empty
name string Yes non-empty
image string | ImageObject | Array<string | ImageObject> No non-empty
description string No —
brand string | Brand | Organization | EntityReference No non-empty
offers Offer | AggregateOffer | Array<Offer | AggregateOffer> No —
aggregateRating AggregateRating No —
review Review | Array<Review> No —
sku string No —
gtin string No —
gtin8 string No —
gtin13 string No —
gtin14 string No —
mpn string No —
category string No —
color string No —
material string No —
releaseDate string | number No non-empty

The aliases above remain the exact authority for nested object types. The builder also accepts a validation configuration as its second argument and always returns @type: 'Product'.

import { Product } from '@unschema-graph/core';
const entity = Product({
"name": "Mechanical keyboard",
"sku": "KB-001",
"brand": "Acme"
});
{
"@type": "Product",
"name": "Mechanical keyboard",
"brand": {
"@type": "Brand",
"name": "Acme"
},
"sku": "KB-001"
}
  • Passing an unknown property to the strict builder.
  • Using source data that is missing a required property.
  • Assuming valid Schema.org guarantees a search appearance.

Use Product.safeParse(input) for external data. If Schema.org supports a property that is not modeled yet, validate the entity first and then use withAdditionalProperties(). Never pass invented properties to the strict builder.