Utils

Schema

Introduction

This document outlines the various Schema.org implementations used throughout the Toolstation frontend for SEO and structured data. The schemas cover products, branches, brands, FAQs, homepage metadata, and article content. Each schema is generated through a corresponding function, which is documented with example code and expected JSON structure.


1. Product List Schema

Function: schemaProductList(products)

Generates an ItemList schema from an array of product objects.

Example Output:

{
  "@context": "https://schema.org",
  "@type": "ItemList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "url": "https://ts-eu24-develop.ventrox.com/example-product/p12345",
      "item": { ...Product Schema... }
    }
  ]
}

Sample Code:

function schemaProductList(products) {
  return {
    "@context": "https://schema.org",
    "@type": "ItemList",
    itemListElement: products.map((product, index) => ({
      "@type": "ListItem",
      position: index + 1,
      url: product.url,
      item: schemaPDP(product),
    })),
  };
}

2. Product Detail Schema

Function: schemaPDP(product)

Provides detailed product information including images, brand, offers, rating, and technical specifications.

Sample Code:

function schemaPDP(product) {
  return {
    "@context": "https://schema.org",
    "@type": "Product",
    name: product.name,
    image: product.images,
    sku: product.sku,
    brand: {
      "@type": "Brand",
      name: product.brand,
    },
    offers: {
      "@type": "Offer",
      price: product.price,
      priceCurrency: "GBP",
      availability: product.inStock
        ? "https://schema.org/InStock"
        : "https://schema.org/OutOfStock",
    },
    aggregateRating: schemaRating(product.rating, product.reviewCount),
  };
}

3. Breadcrumb Schema

Function: schemaBreadcrumb(breadcrumbs)

Generates a BreadcrumbList for enhanced navigation structure in search results.

Example Output:

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Tools",
      "item": "/tools"
    }
  ]
}

Sample Code:

function schemaBreadcrumb(breadcrumbs) {
  return {
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    itemListElement: breadcrumbs.map((crumb, index) => ({
      "@type": "ListItem",
      position: index + 1,
      name: crumb.name,
      item: crumb.url,
    })),
  };
}

4. Homepage Schema

Function: schemaHomePage(route, siteBaseUrl)

Implements multiple schemas for the homepage including Organization, WebPage, WebSite, and Logo.

Sample Code:

function schemaHomePage(route, siteBaseUrl) {
  return [
    {
      "@context": "https://schema.org",
      "@type": "Organization",
      name: "Toolstation",
      url: siteBaseUrl,
      logo: `${siteBaseUrl}/logo.svg`,
      sameAs: [
        "https://www.facebook.com/toolstationuk",
        "https://twitter.com/toolstationuk",
      ],
    },
    {
      "@type": "WebSite",
      name: "Toolstation",
      url: siteBaseUrl,
    },
    {
      "@type": "WebPage",
      name: "Home",
      url: `${siteBaseUrl}${route}`,
    },
  ];
}

5. FAQ Schema

Function: schemaFAQs(faqs)

Encodes FAQs into a FAQPage schema for rich result display.

Sample Code:

function schemaFAQs(faqs) {
  return {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    mainEntity: faqs.map((faq) => ({
      "@type": "Question",
      name: faq.question,
      acceptedAnswer: {
        "@type": "Answer",
        text: faq.answer,
      },
    })),
  };
}

6. Branch Schema

Function: schemaBranch(branchData, productRating?, productReviews?)

Describes a local store branch with location, geocoordinates, services, and optionally aggregate ratings.

Sample Code:

function schemaBranch(branchData, productRating, productReviews) {
  return {
    "@context": "https://schema.org",
    "@type": "Store",
    name: branchData.name,
    address: {
      "@type": "PostalAddress",
      streetAddress: branchData.address.street,
      addressLocality: branchData.address.city,
      addressRegion: branchData.address.region,
      postalCode: branchData.address.postcode,
      addressCountry: "GB",
    },
    geo: schemaGeoCoordinates(branchData.latitude, branchData.longitude),
    telephone: branchData.phone,
    openingHours: branchData.openingHours,
    aggregateRating:
      productRating && productReviews
        ? schemaRating(productRating, productReviews)
        : undefined,
  };
}

7. Branch Listing Schema

Function: schemaBranchListing(branchesData)

Creates a CollectionPage schema that lists all branches grouped alphabetically.

Sample Code:

function schemaBranchListing(branchesData) {
  return {
    "@context": "https://schema.org",
    "@type": "CollectionPage",
    name: "Toolstation Store Locations",
    hasPart: branchesData.map((branch) => schemaBranch(branch)),
  };
}

8. Brand and Brand Listing Schema

Functions:

  • schemaBrands(brandData)
  • schemaBrandListing(brandsData)

Describes brand details and generates a listing of multiple brands using ItemList.

Sample Code for Brand:

function schemaBrands(brandData) {
  return {
    "@context": "https://schema.org",
    "@type": "Brand",
    name: brandData.name,
    url: brandData.url,
    logo: brandData.logo,
  };
}

Sample Code for Brand Listing:

function schemaBrandListing(brandsData) {
  return {
    "@context": "https://schema.org",
    "@type": "ItemList",
    itemListElement: brandsData.map((brand, index) => ({
      "@type": "ListItem",
      position: index + 1,
      item: schemaBrands(brand),
    })),
  };
}

9. Article / Blog Content Schema

Functions:

  • generateContentSchema(item, schemaType, options?)
  • generateSchemaItem(item, schemaType, options?)
  • generateSchemaList(items, itemType, schemaType, options?)

Generates detailed structured data for articles, with fields such as:

  • Headline, description
  • Author info
  • Word count and keywords
  • Category and publish dates

10. Utility Schema Helpers

schemaRating(rating, reviewCount)

Returns an AggregateRating schema.

schemaPropertyValue(name, value)

Returns a PropertyValue object.

schemaGeoCoordinates(latitude, longitude)

Returns GeoCoordinates object.

schemaAggregateRating(otherAttributes)

Parses custom attributes for review data.


Notes

  • All schema objects are registered via useSchemaOrg().
  • Be sure all fields required by schema.org types are provided when available.

Copyright © 2026