Course → Module 2: Structured Data: Speaking Google's Language
Session 2 of 10

JSON-LD stands for JavaScript Object Notation for Linked Data. It is a method of encoding structured data using standard JSON syntax, wrapped in a <script> tag on your web page. Google has recommended JSON-LD as its preferred structured data format since 2015, and the vast majority of new implementations use it.

This session covers the syntax rules, where to place it, and the mistakes that cause validation failures. If you get the basics right here, every subsequent session in this module builds cleanly on top.

The Anatomy of a JSON-LD Block

Every JSON-LD block follows the same structure:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Acme Corp",
  "url": "https://www.acmecorp.com",
  "logo": "https://www.acmecorp.com/images/logo.png"
}
</script>

Three elements are always required:

  1. @context: Always "https://schema.org". This tells the parser which vocabulary you are using.
  2. @type: The Schema.org type (Organization, Person, Product, etc.).
  3. At least one property: A name, url, or other descriptor that identifies the entity.
graph TD A["script tag
type=application/ld+json"] --> B["JSON Object"] B --> C["@context
schema.org"] B --> D["@type
Organization, Person, etc."] B --> E["Properties
name, url, logo, etc."] E --> F["Simple values
strings, numbers, dates"] E --> G["Nested objects
address, founder, etc."] style A fill:#222221,stroke:#c8a882,color:#ede9e3 style B fill:#222221,stroke:#c8a882,color:#ede9e3 style C fill:#222221,stroke:#6b8f71,color:#ede9e3 style D fill:#222221,stroke:#6b8f71,color:#ede9e3 style E fill:#222221,stroke:#6b8f71,color:#ede9e3 style F fill:#222221,stroke:#8a8478,color:#ede9e3 style G fill:#222221,stroke:#8a8478,color:#ede9e3

Placement Rules

JSON-LD blocks can be placed in the <head> or anywhere in the <body> of your HTML document. Google processes both locations identically. However, best practice is to place them in the <head> for two reasons:

You can have multiple JSON-LD blocks on a single page. A homepage might have an Organization block, a WebSite block with a SearchAction, and a BreadcrumbList block. Each goes in its own <script> tag. Alternatively, you can use a JSON array to combine them:

<script type="application/ld+json">
[
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "Acme Corp",
    "url": "https://www.acmecorp.com"
  },
  {
    "@context": "https://schema.org",
    "@type": "WebSite",
    "name": "Acme Corp",
    "url": "https://www.acmecorp.com",
    "potentialAction": {
      "@type": "SearchAction",
      "target": "https://www.acmecorp.com/search?q={search_term_string}",
      "query-input": "required name=search_term_string"
    }
  }
]
</script>

Data Types and Formatting

JSON-LD values must follow JSON rules. Strings are quoted. Numbers are not. Booleans are true or false (lowercase, unquoted). Dates follow ISO 8601 format.

Data Type Format Example
String Double-quoted "name": "Acme Corp"
URL Full absolute URL "url": "https://www.acmecorp.com"
Date ISO 8601 "foundingDate": "2003-06-15"
Number Unquoted "numberOfEmployees": 50
Boolean Unquoted lowercase "isAccessibleForFree": true
Array Square brackets "sameAs": ["https://twitter.com/acme", "https://linkedin.com/company/acme"]
Nested object Object with @type "address": { "@type": "PostalAddress", ... }

Common Mistakes

Most JSON-LD errors fall into a small number of categories. The following table covers the ones that appear most frequently in validation tools:

Mistake What Happens Fix
Trailing comma after last property Invalid JSON, entire block ignored Remove the trailing comma
Single quotes instead of double quotes Invalid JSON JSON requires double quotes only
Missing @context Parser cannot resolve types Add "@context": "https://schema.org"
Wrong @type spelling Type not recognized Check Schema.org for exact casing
Relative URLs URL cannot be resolved Use full absolute URLs
HTML entities in JSON Invalid JSON syntax Use plain text, escape with backslash if needed
Duplicate @context in nested objects Unnecessary but not harmful Only declare @context at the top level
Content mismatch Google may ignore or penalize Ensure JSON-LD matches visible page content

Key concept: JSON-LD is JSON. If your JSON is invalid, the entire block is discarded. Always validate your JSON syntax before checking Schema.org compliance. A missing comma or misplaced bracket makes everything else irrelevant.

A Complete, Correct Example

Here is a JSON-LD block for a real business, demonstrating proper nesting, arrays, and data types:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Acme Corp",
  "legalName": "Acme Corporation LLC",
  "url": "https://www.acmecorp.com",
  "logo": "https://www.acmecorp.com/images/logo.png",
  "foundingDate": "2003-06-15",
  "founder": {
    "@type": "Person",
    "name": "Jane Smith"
  },
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "123 Main Street",
    "addressLocality": "Austin",
    "addressRegion": "TX",
    "postalCode": "73301",
    "addressCountry": "US"
  },
  "contactPoint": {
    "@type": "ContactPoint",
    "telephone": "+1-512-555-0100",
    "contactType": "customer service"
  },
  "sameAs": [
    "https://www.facebook.com/acmecorp",
    "https://www.linkedin.com/company/acmecorp",
    "https://twitter.com/acmecorp"
  ]
}
</script>

Notice: every URL is absolute. The @context appears only once, at the top level. Nested objects have their own @type but no @context. The sameAs property uses an array because there are multiple values. Dates use ISO 8601. The telephone number includes the country code.

Testing Your JSON-LD

Before publishing, always test. Google provides two tools:

We cover testing in depth in Session 2.10. For now, bookmark both tools.

Further Reading

Assignment

Write a JSON-LD block for your own organization (or a fictional one). Include:

  1. @context, @type, name, url, logo
  2. A nested address object with full postal address
  3. A sameAs array with at least three social profile URLs
  4. A contactPoint with telephone and contact type

Validate your JSON at jsonlint.com first (pure JSON validity), then test it at the Schema Markup Validator.