Project Spark emits more than a dozen JSON-LD schema types, articles, FAQs, breadcrumbs, local businesses, events, videos, products, recipes, how-tos, on a site whose content is Hebrew. Shipping that much structured data taught us that the hard part isn’t generating schema; it’s generating schema that stays valid against real-world data, in any language, without ever becoming a security hole.
Key takeaway: Structured data fails in production through edge cases, not syntax: empty fields emitted as empty strings, prices of zero treated as missing, coordinates defaulting to the middle of the Atlantic Ocean. Schema generators need the same defensive rigor as any other data pipeline.
Why structured data carries so much weight
JSON-LD is the closest thing the web has to a common language between your content and every machine that reads it. Search engines use it for rich results, star ratings, FAQ dropdowns, event cards, product prices in the results page. Answer engines use it to extract facts with confidence (Part 9). Voice assistants use it to answer “are they open now?” without a click (Part 12). Knowledge graphs use it to connect your organization, its branches, and its people into entities.
That breadth is exactly why defects here are expensive. A malformed schema block does not fail loudly; it is silently ignored, and the rich result you had last month quietly disappears. A misleading schema block is worse: machines confidently repeat whatever you asserted, including the assertion that your business sits at latitude zero, longitude zero. The engineering standard for structured data therefore has to match the standard for any other data pipeline, validation, type discipline, and tests, rather than the copy-the-example culture the topic usually attracts.
The schema portfolio
Every page type gets appropriate markup automatically: BlogPosting on articles, BreadcrumbList everywhere (with the last item correctly URL-less, per Google’s spec), WebSite-with-SearchAction on the home page, FAQPage where Q&A pairs exist, LocalBusiness/Organization from location data (Part 10), plus detection-driven types: HowTo, Recipe, Event, VideoObject, and Product for commerce content. Hebrew content flows through untouched, JSON-LD is encoding-agnostic as long as you don’t mangle the bytes.
“Automatically” is doing real work in that sentence. Editors never write JSON. The plugin detects what a page is, an article, a recipe-shaped how-to, a page with video embeds, a product, and emits the corresponding type with fields drawn from the same reviewed metadata that powers titles and descriptions. Detection has its own pitfalls: the video detector, for example, once carried a pattern that failed to match the canonical embed URL format, so video schema silently never generated for an entire class of posts. A test-writing campaign found it (Part 14); no user ever had, because absent schema looks exactly like no schema was intended.
Type specificity is the other quiet lever. The business-type registry carries 153 schema.org LocalBusiness subtypes, because “Optician” and “MedicalBusiness” are not decoration, the more specific type is what makes a listing eligible for category-appropriate rich treatment, and what tells an answer engine precisely what kind of establishment it is describing.
Five production lessons
1. Escape for the context you’re in
JSON-LD lives inside a <script> tag. If any user-editable value can contain </script>, an attacker can break out and inject markup. The fix is encoding every payload with hex-escaping for HTML-sensitive characters (<, >, &, quotes), a one-flag decision that’s shockingly easy to omit. We enforce it with tests that inject a script-breakout payload and assert containment: the test literally writes a hostile title containing a closing script tag and asserts that exactly one script element exists in the output and the payload appears only in escaped form. Security reviews forget; tests do not (Part 13).
2. Empty is not a value
An early bug emitted "name": "" for locations missing a field. Invalid schema, silently rejected by Google. The rule that emerged: emit the key correctly or don’t emit it at all. Every optional field is gated on non-emptiness, and every parent block is gated on having at least one real child, a location with no populated address fields emits no address object rather than an empty shell. The same applies at the top: a page with nothing to say in a given type emits nothing, because an empty schema block is a validation warning waiting to be indexed.
3. Zero is not empty
The inverse bug, and my favorite in the whole project: a validator flagged products with "price": "0" as “missing price.” Free items are legitimate, schema.org allows a price of zero, and Google’s guidance for free offerings expects it, but the language’s truthiness rules treat the string "0" as falsy, so the presence check silently classified a real price as an absent one. The fix is an explicit is-this-actually-empty comparison rather than a truthiness shortcut. The same bug family surfaced in seven other places once we audited for it, descriptions, titles, keywords, all capable of legitimately being “0”, a hunt that gets its own installment (Part 15).
4. Coordinates need a zero-guard
A location with no coordinates must emit no geo block, not latitude: 0, longitude: 0, which confidently places your business in the ocean off West Africa. The guard has two halves: both coordinates must be present and non-empty before a geo block is emitted, and the values must be cast to real numbers, schema.org expects numeric types, and string-typed coordinates confuse strict consumers. The same dual discipline (presence gate plus type cast) applies to every numeric field: prices, dimensions, durations, counts.
5. Validate your own output continuously
The plugin ships an internal schema validator, required and recommended properties per type, URL and date shape checks, aspect-ratio rules for images, run across the whole site from an audit dashboard. Catching invalid schema in your own dashboard beats discovering it in Search Console weeks later, on Google’s reporting schedule rather than yours. The validator distinguishes hard requirements (missing headline: error) from recommendations (missing price on an offer: warning), because a dashboard that cannot rank its findings trains operators to ignore all of them. And the validator is itself tested, including the free-product case above, which began life as a validator defect.
Testing the tester
An internal validator introduces a recursion most teams miss: who validates the validator? Ours shipped with a defect of its own, the free-product bug in lesson three lived inside the validation logic, meaning the tool responsible for catching schema errors was generating a false one. That experience produced a standing rule: the validator has its own test suite, covering every rule in both directions. For each check there is a fixture that must fail it and a fixture that must pass it, including the awkward fixtures: the price of "0" that must pass, the whitespace-only name that must fail, the missing key that must warn without crashing.
The two-directional discipline matters because validator bugs are asymmetric in cost. A validator that misses real errors is merely useless; a validator that raises false alarms actively teaches operators to distrust and then ignore it, after which every real alarm is ignored too. False positives are the more expensive defect, and they are exactly what untested validators produce.
One page, one voice
A final scale lesson: schema conflicts are not only internal. When another SEO plugin is active during a migration window, both products will happily emit their own JSON-LD graphs, two Organizations, two WebSites, conflicting values, and consuming machines choose between them unpredictably. Project Spark’s coexistence layer (Part 19) treats schema as a surface to defer: when a competitor plugin is detected emitting structured data, ours goes silent on the overlapping types rather than competing. Whatever emits your schema, the invariant to protect is singular: one page, one graph, one set of claims. Machines forgive missing data far more readily than contradictory data.
Hebrew specifics
Almost everything “just works” if byte fidelity holds (Part 8). JSON-LD is UTF-8; Hebrew names, descriptions, and answers flow through untouched, provided nothing in the pipeline mangles the bytes on the way. The two things that don’t come free: separators and brand suffixes inside headline fields (solved at render time, Part 7), and day-of-week and opening-hours normalization from Google’s API format into schema.org’s expected English enumerations, the values stay standardized even when the content is Hebrew, because consumers match enumerations, not translations. The practical rule for any non-English site: localize the free-text fields, standardize the enumerated ones, and never let a well-meaning translation layer touch the latter.
A working checklist for your own site
- Inventory what you emit. View source on your key templates and collect every JSON-LD block. Duplicates from theme-plus-plugin overlap are common and harmful (Part 19).
- Validate with real pages, not ideal ones. Test the product that is free, the location without coordinates, the post with an empty excerpt. Edge-case pages are where schema fails.
- Gate every optional field on genuine non-emptiness, including the value
"0", which is data, not absence. - Check your escaping. If user-editable text reaches a script tag without context-appropriate encoding, you have a security finding, not just an SEO one.
- Automate revalidation. A monthly pass through a rich-results tester, or an internal validator if you operate the code. Schema rots through redesigns and plugin updates, silently.
Next: Part 12, Voice Search Optimization
FAQ
How do I add schema markup to a Hebrew website?
The same as any site, JSON-LD handles Hebrew natively, but ensure byte-faithful storage, keep enumerated values (day names, types) in schema.org’s standard English forms, and validate output with Google’s Rich Results Test.
Why is my structured data invalid in Google Search Console?
The usual causes are empty-string values for required properties, wrong types (string coordinates instead of numbers), missing required fields on specific types, or malformed JSON from unescaped content.
Is JSON-LD a security risk?
It can be: JSON-LD inside a script tag must hex-escape HTML-sensitive characters, or user-supplied content containing </script> can inject markup into every page.
Should I emit schema fields with empty values?
No. Emit optional properties only when they have real values, empty strings and placeholder zeros make schema invalid or misleading.
Can a product have a price of zero in schema markup?
Yes. Free products are legitimate in schema.org and expected by Google for free offerings. Validators must not treat the string “0” as a missing price.
How many schema types should a website use?
As many as genuinely describe your content, articles, breadcrumbs, organization, FAQ, plus type-specific markup like Product or Event where relevant. Emit nothing speculative; every block should describe something real.





