nuxt-x-schema
Schema Components
All 16 Schema.org JSON-LD components with props reference.
Schema Components
All components inject a <script type="application/ld+json"> tag and accept structured data as props. No visible output — SEO only.
XSchemaArticle
<XSchemaArticle
headline="My Blog Post"
date-published="2024-01-15"
author="Jane Doe"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
headline | String | Yes | — | Article headline |
description | String | No | null | Short article description |
image | String | Array | No | null | Image URL(s) |
datePublished | String | Yes | — | ISO 8601 publish date |
dateModified | String | No | null | ISO 8601 modified date |
author | String | Object | Array | Yes | — | Author name, Person object, or array |
publisher | Object | No | null | Publisher Organization object |
articleType | String | No | "BlogPosting" | Schema type: Article, BlogPosting, NewsArticle, TechArticle |
url | String | No | null | Canonical URL |
wordCount | Number | No | null | Approximate word count |
XSchemaBreadcrumb
<XSchemaBreadcrumb
:items="[
{ label: 'Home', to: '/' },
{ label: 'Blog', to: '/blog' },
{ label: 'My Post' }
]"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
items | BreadcrumbItem[] | Yes | Array of breadcrumb items. Each item: { label, name, to, item }. The last item (current page) should omit to/item |
XSchemaEvent
<XSchemaEvent
name="Vue Conference 2024"
description="Annual Vue.js community conference"
start-date="2024-06-01T09:00:00"
end-date="2024-06-02T18:00:00"
event-attendance-mode="OfflineEventAttendanceMode"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | — | Event name |
description | String | Yes | — | Event description |
startDate | String | Yes | — | ISO 8601 start datetime |
endDate | String | Yes | — | ISO 8601 end datetime |
eventAttendanceMode | String | No | "OnlineEventAttendanceMode" | OnlineEventAttendanceMode, OfflineEventAttendanceMode, MixedEventAttendanceMode |
eventStatus | String | No | "EventScheduled" | EventScheduled, EventCancelled, EventPostponed, etc. |
location | Record<string, any> | No | — | Location object (Place or VirtualLocation) |
url | String | No | — | Event URL |
image | String | String[] | No | — | Event image URL(s) |
organizer | Organization | No | — | Organizer Organization object |
offers | Offer | No | — | Ticket/registration Offer object |
XSchemaFAQ
<XSchemaFAQ
:items="[
{ label: 'What is Vue?', content: 'A progressive JavaScript framework.' },
{ label: 'Is it free?', content: 'Yes, MIT licensed.' }
]"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
items | FAQ[] | Yes | Array of FAQ items. Each item accepts: label/question/name for the question; content/answer/text for the answer |
pageTitle | String | No | Optional page name added to the schema |
pageDescription | String | No | Optional page description |
datePublished | String | No | ISO 8601 publish date |
dateModified | String | No | ISO 8601 modified date |
author | String | Person | No | Page author |
XSchemaHowTo
<XSchemaHowTo
name="How to make coffee"
:steps="[
{ name: 'Boil water', text: 'Heat water to 95°C' },
{ name: 'Add grounds', text: 'Add 2 tbsp of coffee grounds' }
]"
total-time="PT5M"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | How-to title |
description | String | No | How-to description |
image | String | String[] | No | Illustration image URL(s) |
totalTime | String | No | ISO 8601 duration (e.g. PT30M) |
estimatedCost | MonetaryAmount | No | Estimated cost object { currency, value } |
supply | String[] | No | List of required supplies |
tool | String[] | No | List of required tools |
steps | HowToStep[] | Yes | Array of steps. Each step: { name, text, image?, url? } |
XSchemaLocalBusiness
<XSchemaLocalBusiness
name="Acme Coffee"
business-type="CafeOrCoffeeShop"
url="https://acmecoffee.com"
:address="{
streetAddress: '123 Main St',
addressLocality: 'Seattle',
addressRegion: 'WA',
postalCode: '98101',
addressCountry: 'US'
}"
telephone="+12065551234"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Business name |
businessType | String | Yes | Schema.org business type (e.g. Restaurant, MedicalClinic) |
url | String | Yes | Business website URL |
address | PostalAddress | Yes | Address object: { streetAddress, addressLocality, addressRegion, postalCode, addressCountry } |
telephone | String | No | Phone number |
email | String | No | Contact email |
image | String | No | Business image URL |
description | String | No | Business description |
openingHoursSpecification | Record<string,any>[] | No | Array of opening hours objects |
aggregateRating | AggregateRating | No | Rating object { ratingValue, reviewCount } |
priceRange | String | No | Price range indicator (e.g. $$) |
sameAs | String[] | No | Social profile and directory URLs |
XSchemaOffer
<XSchemaOffer
name="Premium Plan"
:price="49.99"
price-currency="USD"
availability="InStock"
url="https://example.com/premium"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | — | Offer name |
description | String | No | — | Offer description |
price | String | Number | Yes | — | Price value |
priceCurrency | String | No | "USD" | ISO 4217 currency code |
availability | String | No | "InStock" | InStock, OutOfStock, PreOrder, etc. |
url | String | No | — | Offer URL |
seller | Organization | No | — | Seller Organization object |
validFrom | String | No | — | ISO 8601 offer start date |
validThrough | String | No | — | ISO 8601 offer end date |
priceValidUntil | String | No | — | ISO 8601 price expiry date |
itemCondition | String | No | "NewCondition" | NewCondition, UsedCondition, RefurbishedCondition |
XSchemaOrganization
<XSchemaOrganization
name="Acme Corp"
url="https://acme.com"
logo="https://acme.com/logo.png"
:same-as="['https://twitter.com/acme', 'https://linkedin.com/company/acme']"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | — | Organization name |
url | String | Yes | — | Organization URL |
logo | String | Yes | — | Logo image URL |
legalName | String | No | — | Official legal name |
description | String | No | — | Organization description |
email | String | No | — | Contact email |
telephone | String | No | — | Contact phone |
address | PostalAddress | No | — | Postal address object |
sameAs | String[] | No | [] | Social and directory profile URLs |
foundingDate | String | No | — | ISO 8601 founding date |
founder | String | Person | No | — | Founder name or Person object |
XSchemaPerson
<XSchemaPerson
name="Jane Doe"
job-title="Senior Engineer"
url="https://janedoe.dev"
:same-as="['https://github.com/janedoe']"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | — | Person's full name |
jobTitle | String | No | — | Job title |
description | String | No | — | Short bio |
image | String | No | — | Profile image URL |
url | String | No | — | Personal website URL |
email | String | No | — | Email address |
telephone | String | No | — | Phone number |
sameAs | String[] | No | [] | Social and profile URLs |
worksFor | Organization | No | — | Employer Organization object |
knowsAbout | String[] | No | [] | Topics the person knows about |
alumniOf | String | Organization | No | — | Educational institution |
XSchemaProduct
<XSchemaProduct
name="Wireless Headphones"
description="Premium noise-cancelling headphones"
:offers="{ price: '199.99', priceCurrency: 'USD' }"
sku="WH-1234"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Product name |
description | String | Yes | Product description |
image | String | String[] | No | Product image URL(s) |
brand | String | Organization | No | Brand name or Organization object |
offers | Offer | Yes | Offer object with price and availability |
aggregateRating | AggregateRating | No | Rating object { ratingValue, reviewCount } |
review | Review[] | No | Array of Review objects |
sku | String | No | Stock-keeping unit identifier |
manufacturer | String | Organization | No | Manufacturer name or Organization |
category | String | No | Product category |
XSchemaQAPage
<XSchemaQAPage
:items="[
{
label: 'What is the capital of France?',
content: 'Paris',
answerAuthor: 'Expert User',
upvoteCount: 42
}
]"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
items | QAItem[] | Yes | Array of Q&A items. Each item: label/question/name for question; content/answer/text for accepted answer; optional answerAuthor, answerDate, suggestedAnswers, upvoteCount, answerCount, dateCreated |
pageTitle | String | No | Page name |
pageDescription | String | No | Page description |
datePublished | String | No | ISO 8601 publish date |
dateModified | String | No | ISO 8601 modified date |
author | String | Person | No | Page author |
XSchemaReview
<XSchemaReview
:item-reviewed="{ '@type': 'Product', name: 'Headphones' }"
:review-rating="{ ratingValue: 5, bestRating: 5 }"
author="Jane Doe"
review-body="Excellent sound quality!"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
itemReviewed | Record<string, any> | Yes | — | The item being reviewed (include @type and name) |
reviewRating | Rating | Yes | — | Rating object { ratingValue, bestRating? } |
author | String | Person | Yes | — | Reviewer name or Person object |
reviewBody | String | No | — | Full review text |
datePublished | String | No | — | ISO 8601 review date |
isAggregate | boolean | No | false | When true, outputs AggregateRating schema instead of individual Review |
ratingCount | Number | No | — | Total rating count (aggregate mode) |
reviewCount | Number | No | — | Total review count (aggregate mode) |
XSchemaService
<XSchemaService
name="Web Development"
description="Custom web application development services"
service-type="WebDevelopment"
area-served="Seattle, WA"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Service name |
description | String | Yes | Service description |
serviceType | String | Yes | Service type identifier |
provider | Organization | No | Provider Organization object (defaults to app config organization) |
areaServed | String | String[] | No | Geographic area(s) served |
offers | Offer | No | Pricing Offer object |
image | String | String[] | No | Service image URL(s) |
url | String | No | Service page URL |
category | String | No | Service category |
XSchemaSoftwareApplication
<XSchemaSoftwareApplication
name="MyApp"
description="A productivity application"
url="https://myapp.com"
application-category="BusinessApplication"
operating-system="Web"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Application name |
description | String | Yes | Application description |
url | String | Yes | Application URL |
applicationCategory | String | Yes | Schema.org application category (e.g. GameApplication, BusinessApplication) |
operatingSystem | String | String[] | No | Supported OS(es) |
offers | Offer | No | Pricing Offer object |
aggregateRating | AggregateRating | No | Rating object |
author | String | Person | No | Developer name or Person object |
screenshot | String | String[] | No | Screenshot URL(s) |
releaseNotes | String | No | Release notes URL or text |
XSchemaVideoObject
<XSchemaVideoObject
name="Introduction to Vue 3"
description="A beginner-friendly overview of Vue 3"
thumbnail-url="https://example.com/thumb.jpg"
upload-date="2024-01-10"
content-url="https://example.com/video.mp4"
duration="PT12M30S"
/>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Video title |
description | String | Yes | Video description |
thumbnailUrl | String | String[] | Yes | Thumbnail image URL(s) |
uploadDate | String | Yes | ISO 8601 upload date |
duration | String | No | ISO 8601 duration (e.g. PT1H30M) |
contentUrl | String | No | Direct URL to the video file |
embedUrl | String | No | Embed URL (e.g. YouTube embed) |
interactionCount | Number | No | Number of views/interactions |
author | String | Person | No | Creator name or Person object |
XSchemaWebSite
<XSchemaWebSite
name="My Website"
url="https://example.com"
:enable-search-box="true"
search-url="https://example.com/search?q={search_term_string}"
/>
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | — | Website name |
url | String | Yes | — | Website URL |
description | String | No | — | Website description |
publisher | Organization | No | — | Publisher Organization object |
enableSearchBox | boolean | No | false | Add Sitelinks Search Box potentialAction |
searchUrl | String | No | — | Search URL template; required when enableSearchBox is true |
queryInput | String | No | "required name=search_term_string" | query-input value for the SearchAction |
AI Context
package: "@xenterprises/nuxt-x-schema"
all-components:
- XSchemaArticle
- XSchemaBreadcrumb
- XSchemaEvent
- XSchemaFAQ
- XSchemaHowTo
- XSchemaLocalBusiness
- XSchemaOffer
- XSchemaOrganization
- XSchemaPerson
- XSchemaProduct
- XSchemaQAPage
- XSchemaReview
- XSchemaService
- XSchemaSoftwareApplication
- XSchemaVideoObject
- XSchemaWebSite
output: JSON-LD script tag in <head>
use-when: Adding structured data for rich Google results
place: In page-level components (pages/ or layouts/), NOT in shared headers
pattern: One component per page type — Article on blog posts, Product on product pages, etc.
notes:
- All components are wrapped in <ClientOnly>
- No visible rendered output; purely SEO metadata
- XSchemaReview can output either Review or AggregateRating schema via isAggregate prop
- XSchemaBreadcrumb auto-converts relative URLs to absolute using a base domain
- XSchemaService defaults provider to app config organization when omitted
