Building structured data for search engines just got a lot safer. When you are injecting dynamic SEO metadata or serializing complex search data for rich snippets, a single typo can cause Google to entirely ignore your markup. Enter @antinna/schema-ld-types: a comprehensive, fully type-safe library tailored for Schema.org JSON-LD objects.
Whether you are building a headless CMS, an e-commerce storefront, or a dynamic blog, this package ensures both runtime and compile-time accuracy for your structured data pipelines, completely eliminating silent SEO failures before they reach production.
Search engines are incredibly strict about schema structures. If you misspell jobTitle as jobtitle, or forget to declare an @type on a deeply nested organization object, Google Search Console will flag it as an error and strip your page of its Rich Snippet eligibility. Writing raw JSON objects manually leaves you highly vulnerable to these undetectable typos.
Implementation Breakdown
Overview Core Features
This library acts as a robust middle-layer between your application data and the final DOM injection, providing:
- Full Type-Safety: Thousands of autogenerated TypeScript definitions compiled directly from the official Schema.org vocabulary.
- Validation & Typeguards: Built-in helper utilities to validate and assert schema structures securely at runtime.
- Smart Hydration: Automatically inserts missing
@typeproperties onto deeply nested objects based on Schema.org relational rules. - Serialization / Deserialization: Seamless translation to and from JSON-LD strings, handling the annoying
@contextwrappers for you automatically.
Setup Installation
Add the package to your front-end framework or Node.js backend using your preferred package manager:
npm install @antinna/schema-ld-types
Step 1 Importing Types & Utilities
The package exports hundreds of strictly typed Schema models (like Person, Article, Product, Organization) alongside five core functional utilities.
import {
Person,
validate,
assertType,
serialize,
deserialize,
hydrate
} from '@antinna/schema-ld-types';
Step 2 Validation & Type Guarding
When you are pulling data from a database or a third-party API, you need to verify that the payload accurately maps to a Schema structure before injecting it into your page head. The validate function acts as a boolean type guard.
const dynamicData: any = {
'@type': 'Person',
name: 'Jane Doe',
jobTitle: 'Software Engineer',
worksFor: {
'@type': 'Organization',
name: 'Antinna'
}
};
if (validate<Person>(dynamicData, 'Person')) {
// TypeScript now intelligently narrows 'dynamicData' to strictly be a Person object.
// You get full IDE autocomplete for properties like dynamicData.name
console.log(`Successfully verified Person: ${dynamicData.name}`);
} else {
// Gracefully fallback or log an error without breaking the app UI
console.error("Payload failed to match Schema.org Person guidelines!");
}
Step 3 Assertion Testing (Fail-Fast)
In backend data-pipelines or build scripts, you might prefer the script to fail immediately if the SEO data is corrupted. assertType will throw a descriptive runtime error if the data shape is invalid.
try {
const verifiedPerson = assertType<Person>(dynamicData, 'Person');
// Safe to proceed with database save or SSR injection
console.log(verifiedPerson.name);
} catch (error) {
console.error("Critical SEO pipeline failure:", error.message);
}
Step 4 Serialization
Once your object is built, it must be converted into a string to be placed inside your <script type="application/ld+json"> tags. The serialize method automatically prepends the mandatory "@context": "https://schema.org" namespace so you never have to remember it.
const author: Person = {
'@type': 'Person',
name: 'Manish',
url: 'https://github.com/manishmg3994'
};
const jsonLdString = serialize(author);
console.log(jsonLdString);
/*
Output:
{
"@context": "https://schema.org",
"@type": "Person",
"name": "Manish",
"url": "https://github.com/manishmg3994"
}
*/
Step 5 Deserialization & Smart Hydration
This is where the library shines. Often, when you write raw JSON, you forget to add the @type declaration to child objects. The library's smart hydration engine reads the official Schema documentation rules to figure out what type the child *should* be, and automatically injects it for you.
Notice in the code below how the nested worksFor object is missing its @type string. Google would normally reject this payload. However, our deserializer recognizes that worksFor on a Person expects an Organization, and automatically repairs the JSON for you on the fly!
const rawJson = `
{
"name": "John Doe",
"worksFor": {
"name": "Antinna"
}
}
`;
// Deserializes and automatically infers worksFor's @type as Organization
const loadedPerson = deserialize<Person>(rawJson, 'Person');
console.log(loadedPerson['@type']);
// Output: "Person"
console.log(loadedPerson.worksFor['@type']);
// Output: "Organization" (Automatically injected!)
📄 Open Source License
This project is proudly open-source and freely available under the MIT License. Contributions, pull requests, and GitHub stars are always welcome to help keep the schema definitions up to date with the latest web standards.
