nuxt-x-schema
nuxt-x-schema
16 renderless Schema.org structured data components for Nuxt 4. Each component injects a <script type="application/ld+json"> tag into <head> via useHead — fully SSR-safe, visible to search engine crawlers on first paint.
Installation
npm install @xenterprises/nuxt-x-schema
// nuxt.config.ts
export default defineNuxtConfig({
extends: ["@xenterprises/nuxt-x-schema"],
});
What This Layer Provides
- 16 Schema.org components — all renderless, all auto-imported
useSchema()composable — shared utilities for URL resolution and JSON-LD injection
Configuration (app.config.ts)
export default defineAppConfig({
xSchema: {
siteUrl: "https://mysite.com",
siteName: "My Site",
siteLogo: "/logo.png",
organizationName: "My Company",
},
});
| Option | Type | Default | Description |
|---|---|---|---|
siteUrl | string | "https://example.com" | Base URL for absolute URL construction. |
siteName | string | "My Website" | Default organization/publisher name. |
siteLogo | string | "/logo.png" | Logo URL. |
organizationName | string | "" | Organization name (falls back to siteName). |
Components
XSchemaArticle — Blog posts, news articles
| Prop | Type | Required | Description |
|---|---|---|---|
headline | string | Yes | Article title. |
datePublished | string | Yes | ISO 8601 publication date. |
author | string | Person | Array | Yes | Author name(s) or Person object(s). |
description | string | No | Article summary. |
image | string | string[] | No | Article image URL(s). |
dateModified | string | No | Last modification date (defaults to datePublished). |
articleType | string | No | Article, BlogPosting, NewsArticle, TechArticle (default: "BlogPosting"). |
url | string | No | Canonical URL. |
wordCount | number | No | Word count. |
XSchemaBreadcrumb — Navigation breadcrumbs
| Prop | Type | Required | Description |
|---|---|---|---|
items | BreadcrumbItem[] | Yes | Array of { label, to } or { name, item }. Relative URLs resolved to absolute. |
XSchemaEvent — Events and conferences
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Event name. |
description | string | Yes | Event description. |
startDate | string | Yes | ISO 8601 start date/time. |
endDate | string | Yes | ISO 8601 end date/time. |
eventAttendanceMode | string | No | Attendance mode (default: "OnlineEventAttendanceMode"). |
location | object | No | Location object. |
offers | Offer | No | Ticket offer. |
XSchemaFAQ — FAQ pages
| Prop | Type | Required | Description |
|---|---|---|---|
items | FAQ[] | Yes | Array of { question, answer } (also accepts label/content or name/text). |
pageTitle | string | No | Page title. |
datePublished | string | No | Publication date. |
author | string | Person | No | Page author. |
XSchemaHowTo — Step-by-step guides
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Guide title. |
steps | HowToStep[] | Yes | Array of { name, text, image?, url? }. |
totalTime | string | No | ISO 8601 duration (e.g. "PT30M"). |
supply | string[] | No | Required supplies. |
tool | string[] | No | Required tools. |
XSchemaLocalBusiness — Business locations
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Business name. |
businessType | string | Yes | Schema.org type (e.g. "Restaurant", "Store"). |
url | string | Yes | Business website URL. |
address | PostalAddress | Yes | Business address. |
telephone | string | No | Phone number. |
openingHoursSpecification | object[] | No | Opening hours. |
aggregateRating | AggregateRating | No | Rating summary. |
priceRange | string | No | Price range (e.g. "$$"). |
XSchemaOffer — Pricing offers
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Offer name. |
price | string | number | Yes | Price value. |
priceCurrency | string | No | ISO 4217 currency (default: "USD"). |
availability | string | No | Availability (default: "InStock"). |
validThrough | string | No | Offer expiry date. |
XSchemaOrganization — Company information
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Organization name. |
url | string | Yes | Website URL. |
logo | string | Yes | Logo image URL. |
sameAs | string[] | No | Social media URLs. |
foundingDate | string | No | Founding date. |
founder | string | Person | No | Founder. |
XSchemaPerson — Author/team profiles
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Person name. |
jobTitle | string | No | Job title. |
image | string | No | Photo URL. |
sameAs | string[] | No | Social profiles. |
knowsAbout | string[] | No | Expertise topics. |
XSchemaProduct — Products with offers
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Product name. |
description | string | Yes | Product description. |
offers | Offer | Yes | Pricing offer. |
image | string | string[] | No | Product image(s). |
aggregateRating | AggregateRating | No | Rating summary. |
sku | string | No | Product SKU. |
XSchemaQAPage — Q&A pages
| Prop | Type | Required | Description |
|---|---|---|---|
items | QAItem[] | Yes | Array of { question, answer, answerAuthor?, upvoteCount? }. |
XSchemaReview — Reviews and ratings
| Prop | Type | Required | Description |
|---|---|---|---|
itemReviewed | object | Yes | The item being reviewed (include @type). |
reviewRating | Rating | Yes | { ratingValue, bestRating? }. |
author | string | Person | Yes | Reviewer. |
isAggregate | boolean | No | Render as AggregateRating instead. |
XSchemaService — Service pages
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Service name. |
description | string | Yes | Service description. |
serviceType | string | Yes | Service type identifier. |
areaServed | string | string[] | No | Geographic area served. |
XSchemaSoftwareApplication — Web/mobile apps
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | App name. |
description | string | Yes | App description. |
url | string | Yes | App URL. |
applicationCategory | string | Yes | Category (e.g. "BusinessApplication"). |
operatingSystem | string | string[] | No | Supported OS(es). |
XSchemaVideoObject — Video content
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Video title. |
description | string | Yes | Video description. |
thumbnailUrl | string | string[] | Yes | Thumbnail URL(s). |
uploadDate | string | Yes | ISO 8601 upload date. |
duration | string | No | ISO 8601 duration (e.g. "PT10M30S"). |
contentUrl | string | No | Direct video URL. |
embedUrl | string | No | Embed URL. |
XSchemaWebSite — Site-wide schema
| Prop | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Site name. |
url | string | Yes | Site URL. |
enableSearchBox | boolean | No | Enable Sitelinks Search Box. |
searchUrl | string | No | Search URL template (required if enableSearchBox). |
useSchema() Composable
| Method | Returns | Description |
|---|---|---|
siteUrl | ComputedRef<string> | Configured site URL (no trailing slash). |
siteName | ComputedRef<string> | Configured site name. |
resolveUrl(path) | string | undefined | Convert relative URL to absolute. |
getDefaultOrganization() | Organization | Default org from app config. |
getDefaultPublisher() | object | Default publisher with ImageObject logo. |
normalizeAuthor(author) | Person | Person[] | undefined | Convert string/array to Person schema. |
normalizeImage(image) | string[] | undefined | Ensure image is array. |
useSchemaHead(fn) | void | Inject JSON-LD into <head> via useHead. |
Environment Variables
None required. All configuration is via app.config.ts.
How It Works
Each XSchema* component calls useSchema().useSchemaHead() which wraps useHead() to inject a <script type="application/ld+json"> tag into the page <head>. Because useHead is SSR-safe, the JSON-LD is rendered server-side and visible to crawlers on first paint. Default values for publisher/organizer come from app.config.ts via useSchema(), so branding is configured once and reused across all components. String values for author, founder, and brand are automatically converted to proper Schema.org typed objects.
Test your output: Google Rich Results Test · Schema.org Validator
