StartupKitstartupkit
SEO

Structured Data

How to add JSON-LD schemas for rich search results

Structured data (JSON-LD) helps search engines understand your content and can enable rich results like knowledge panels, breadcrumbs, and article cards.

Available Schemas

SchemaUse Case
generateOrganizationSchemaCompany info in knowledge panels
generateWebsiteSchemaSite-wide search box
generateBreadcrumbSchemaBreadcrumb navigation
generateArticleSchemaBlog posts and articles

Organization Schema

Display your company in Google's Knowledge Panel:

app/layout.tsx
import {  } from "@startupkit/seo"

const  = ({
  : "My Company",
  : "https://mycompany.com",
  : "https://mycompany.com/logo.png",
  : "We build amazing software",
  : [
    "https://twitter.com/mycompany",
    "https://linkedin.com/company/mycompany",
    "https://github.com/mycompany"
  ]
})

export default function ({  }) {
  return (
    <>
      <>
        <
          ="application/ld+json"
          ={{ : .() }}
        />
      </>
      <>{}</>
    </>
  )
}

Parameters

ParameterTypeRequiredDescription
namestringYesOrganization name
urlstringYesWebsite URL
logostringNoLogo image URL
descriptionstringNoOrganization description
sameAsstring[]NoSocial profile URLs

Output

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "My Company",
  "url": "https://mycompany.com",
  "logo": "https://mycompany.com/logo.png",
  "description": "We build amazing software",
  "sameAs": [
    "https://twitter.com/mycompany",
    "https://linkedin.com/company/mycompany"
  ]
}

Website Schema

Enable sitelinks search box in Google:

app/layout.tsx
import {  } from "@startupkit/seo"

const  = ({
  : "My App",
  : "https://myapp.com",
  : "The best app for productivity"
})

export default function ({  }) {
  return (
    <>
      <>
        <
          ="application/ld+json"
          ={{ : .() }}
        />
      </>
      <>{}</>
    </>
  )
}

Parameters

ParameterTypeRequiredDescription
namestringYesWebsite name
urlstringYesWebsite URL
descriptionstringYesWebsite description

Show breadcrumb navigation in search results:

app/docs/[slug]/page.tsx
import {  } from "@startupkit/seo"

export default function ({  }) {
  const  = ([
    { : "Home", : "https://myapp.com" },
    { : "Docs", : "https://myapp.com/docs" },
    { : .slug, : `https://myapp.com/docs/${.slug}` }
  ])

  return (
    <>
      <
        ="application/ld+json"
        ={{ : .() }}
      />
      <>...</>
    </>
  )
}

Parameters

ParameterTypeDescription
itemsArray<{name, url}>Breadcrumb items in order

Output

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

Article Schema

Enhance blog posts with rich results:

app/blog/[slug]/page.tsx
import {  } from "@startupkit/seo"

export default async function ({  }) {
  const  = await getPost(.slug)

  const  = ({
    : .title,
    : .excerpt,
    : .publishedAt,
    : .updatedAt,
    : .author.name,
    : .coverImage
  })

  return (
    <>
      <
        ="application/ld+json"
        ={{ : .() }}
      />
      <>
        <>{.title}</>
        <>By {.author.name}</>
        <>{.content}</>
      </>
    </>
  )
}

Parameters

ParameterTypeRequiredDescription
headlinestringYesArticle title
descriptionstringYesArticle summary
datePublishedstringYesISO 8601 date string
dateModifiedstringNoLast modified date
authorNamestringYesAuthor's name
imageUrlstringYesFeatured image URL

Output

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "How to Build an AI-Powered App",
  "description": "A complete guide to building...",
  "image": "https://myapp.com/blog/ai-app-guide.png",
  "datePublished": "2024-01-15T09:00:00Z",
  "dateModified": "2024-01-20T14:30:00Z",
  "author": {
    "@type": "Person",
    "name": "John Doe"
  }
}

Multiple Schemas

Combine multiple schemas on a page:

app/layout.tsx
import { 
  , 
   
} from "@startupkit/seo"

const  = [
  ({
    : "My Company",
    : "https://mycompany.com"
  }),
  ({
    : "My App",
    : "https://myapp.com",
    : "The best app"
  })
]

export default function ({  }) {
  return (
    <>
      <>
        {.((, ) => (
          <
            ={}
            ="application/ld+json"
            ={{ : .() }}
          />
        ))}
      </>
      <>{}</>
    </>
  )
}

Testing Structured Data

Google's Rich Results Test

  1. Go to Rich Results Test
  2. Enter your page URL
  3. Check for errors and warnings

Schema Markup Validator

  1. Go to Schema.org Validator
  2. Paste your JSON-LD
  3. Verify structure is correct

Best Practices

  1. One Organization schema - Add to root layout only
  2. Breadcrumbs on nested pages - Not needed on homepage
  3. Article schema for blog posts - Helps with rich results
  4. Keep data accurate - Match visible content
  5. Test before deploying - Use Google's testing tool

Next Steps

On this page