@xenterprises/nuxt-x-schema
| Install | |
|---|---|
npm install @xenterprises/nuxt-x-schema |
|
| Latest Version: | 0.3.0 |
| Vue: | 3 |
| License: | Custom |
| Last Updated: | Jul 28, 2026 |
| Links: | npm |
@xenterprises/nuxt-x-schema
Nuxt layer providing 16 Schema.org structured data components for SEO. Renders JSON-LD via useHead for full SSR support — search engines see your schema markup on first paint.
Install
npm install @xenterprises/nuxt-x-schema
Add to your nuxt.config.ts:
export default defineNuxtConfig({
extends: ["@xenterprises/nuxt-x-schema"],
});
Usage
<template>
<main>
<h1>{{ article.title }}</h1>
<XSchemaArticle
:headline="article.title"
:description="article.description"
:date-published="article.publishedAt"
:author="article.author"
/>
</main>
</template>
Components render no visible HTML. They inject <script type="application/ld+json"> into <head> via Nuxt's useHead, ensuring schema is present in server-rendered HTML.
Configuration
Configure defaults in your app's app.config.ts (the layer ships all four keys as undefined; useSchema() applies the runtime fallbacks shown below when a key is unset):
export default defineAppConfig({
xSchema: {
siteUrl: "https://mysite.com",
siteName: "My Site",
siteLogo: "/logo.png",
organizationName: "My Company",
},
});
| Option | Type | Runtime fallback | Required | Description |
|---|---|---|---|---|
siteUrl |
string |
"https://example.com" |
Yes | Base URL for absolute URL construction |
siteName |
string |
"My Website" |
Yes | Default organization/publisher name |
siteLogo |
string |
omitted from output | No | Logo URL (relative to siteUrl or absolute) |
organizationName |
string |
falls back to siteName |
No | Organization name |
Components
XSchemaArticle
Blog posts, news articles, and written content.
| Prop | Type | Default | 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 |
datePublished | No | Last modification date |
publisher |
Organization |
app config | No | Publisher organization |
articleType |
string |
"BlogPosting" |
No | Article, BlogPosting, NewsArticle, TechArticle |
url |
string |
— | No | Canonical article URL |
wordCount |
number |
— | No | Word count |
XSchemaBreadcrumb
Navigation breadcrumb trail.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
items |
BreadcrumbItem[] |
— | Yes | Array of { label, to } or { name, item } |
Relative URLs in to/item are resolved to absolute URLs using xSchema.siteUrl.
XSchemaEvent
Events and conferences.
| Prop | Type | Default | 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 |
"OnlineEventAttendanceMode" |
No | Attendance mode |
eventStatus |
string |
"EventScheduled" |
No | Event status |
location |
object |
— | No | Location object |
url |
string |
— | No | Event URL |
image |
string | string[] |
— | No | Event image(s) |
organizer |
Organization |
app config | No | Organizer |
offers |
Offer |
— | No | Ticket offer |
XSchemaFAQ
FAQ pages with question/answer pairs.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
items |
FAQ[] |
— | Yes | Array of { question, answer } (also accepts label/content or name/text) |
pageTitle |
string |
— | No | Page title |
pageDescription |
string |
— | No | Page description |
datePublished |
string |
— | No | Publication date |
dateModified |
string |
— | No | Modification date |
author |
string | Person |
— | No | Page author |
XSchemaHowTo
Step-by-step guides and tutorials.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Guide title |
steps |
HowToStep[] |
— | Yes | Array of { name, text, image?, url? } |
description |
string |
— | No | Guide description |
image |
string | string[] |
— | No | Guide image(s) |
totalTime |
string |
— | No | ISO 8601 duration (e.g. "PT30M") |
estimatedCost |
MonetaryAmount |
— | No | Estimated cost |
supply |
string[] |
[] |
No | Required supplies |
tool |
string[] |
[] |
No | Required tools |
XSchemaLocalBusiness
Business locations (restaurants, shops, offices).
| Prop | Type | Default | 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 |
email |
string |
— | No | Email address |
image |
string |
— | No | Business image |
description |
string |
— | No | Business description |
openingHoursSpecification |
object[] |
— | No | Opening hours |
aggregateRating |
AggregateRating |
— | No | Rating summary |
priceRange |
string |
— | No | Price range (e.g. "$$") |
sameAs |
string[] |
— | No | Social media URLs |
XSchemaOffer
Pricing and purchase offers.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Offer name |
price |
string | number |
— | Yes | Price value |
description |
string |
— | No | Offer description |
priceCurrency |
string |
"USD" |
No | ISO 4217 currency code |
availability |
string |
"InStock" |
No | Availability status |
url |
string |
— | No | Offer URL |
seller |
Organization |
app config | No | Seller organization |
validFrom |
string |
— | No | Offer valid from date |
validThrough |
string |
— | No | Offer valid through date |
priceValidUntil |
string |
— | No | Price valid until date |
itemCondition |
string |
"NewCondition" |
No | Item condition |
XSchemaOrganization
Company or organization information.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Organization name |
url |
string |
— | Yes | Website URL |
logo |
string |
— | Yes | Logo image URL |
legalName |
string |
— | No | Legal name |
description |
string |
— | No | Description |
email |
string |
— | No | Contact email |
telephone |
string |
— | No | Phone number |
address |
PostalAddress |
— | No | Address |
sameAs |
string[] |
[] |
No | Social media URLs |
foundingDate |
string |
— | No | Founding date |
founder |
string | Person |
— | No | Founder (string auto-converts to Person) |
XSchemaPerson
Author and team profiles.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Person name |
jobTitle |
string |
— | No | Job title |
description |
string |
— | No | Bio |
image |
string |
— | No | Photo URL |
url |
string |
— | No | Personal website |
email |
string |
— | No | |
telephone |
string |
— | No | Phone |
sameAs |
string[] |
[] |
No | Social profiles |
worksFor |
Organization |
— | No | Employer |
knowsAbout |
string[] |
[] |
No | Expertise topics |
alumniOf |
string | Organization |
— | No | School/university |
XSchemaProduct
Products with offers and reviews.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Product name |
description |
string |
— | Yes | Product description |
offers |
Offer |
— | Yes | Pricing offer |
image |
string | string[] |
— | No | Product image(s) |
brand |
string | Organization |
app config name | No | Brand |
aggregateRating |
AggregateRating |
— | No | Rating summary |
review |
Review[] |
— | No | Individual reviews |
sku |
string |
— | No | Product SKU |
manufacturer |
string | Organization |
— | No | Manufacturer |
category |
string |
— | No | Product category |
XSchemaQAPage
Q&A pages with community answers.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
items |
QAItem[] |
— | Yes | Array of { question, answer, answerAuthor?, upvoteCount? } |
pageTitle |
string |
— | No | Page title |
pageDescription |
string |
— | No | Page description |
datePublished |
string |
— | No | Publication date |
dateModified |
string |
— | No | Modification date |
author |
string | Person |
— | No | Page author |
XSchemaReview
Reviews and aggregate ratings.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
itemReviewed |
object |
— | Yes | The item being reviewed (include @type) |
reviewRating |
Rating |
— | Yes | { ratingValue, bestRating? } |
author |
string | Person |
— | Yes | Reviewer |
reviewBody |
string |
— | No | Review text |
datePublished |
string |
— | No | Review date |
isAggregate |
boolean |
false |
No | Render as AggregateRating instead |
ratingCount |
number |
— | No | Total ratings (aggregate mode) |
reviewCount |
number |
— | No | Total reviews (aggregate mode) |
XSchemaService
Service pages.
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Service name |
description |
string |
— | Yes | Service description |
serviceType |
string |
— | Yes | Service type identifier |
provider |
Organization |
app config | No | Service provider |
areaServed |
string | string[] |
— | No | Geographic area served |
offers |
Offer |
— | No | Service pricing |
image |
string | string[] |
— | No | Service image(s) |
url |
string |
— | No | Service page URL |
category |
string |
— | No | Service category |
XSchemaSoftwareApplication
Web and mobile applications.
| Prop | Type | Default | 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) |
offers |
Offer |
— | No | Pricing |
aggregateRating |
AggregateRating |
— | No | Rating summary |
author |
string | Person |
— | No | Developer |
screenshot |
string | string[] |
— | No | Screenshot URL(s) |
releaseNotes |
string |
— | No | Latest release notes |
XSchemaVideoObject
Video content.
| Prop | Type | Default | 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 file URL |
embedUrl |
string |
— | No | Embed URL |
interactionCount |
number |
— | No | View count |
author |
string | Person |
— | No | Video creator |
XSchemaWebSite
Site-wide schema (typically in default layout).
| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | Yes | Site name |
url |
string |
— | Yes | Site URL |
description |
string |
— | No | Site description |
publisher |
Organization |
— | No | Publisher |
enableSearchBox |
boolean |
false |
No | Enable Sitelinks Search Box |
searchUrl |
string |
— | No | Search URL template (required if enableSearchBox) |
queryInput |
string |
"required name=search_term_string" |
No | Search query input spec |
Composable: useSchema
Auto-imported composable providing shared utilities for schema generation.
| 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
This layer does not require any environment variables. All configuration is via app.config.ts.
How It Works
- Each
XSchema*component accepts typed props describing the content. - Components call
useSchema().useSchemaHead()which wrapsuseHead()to inject a<script type="application/ld+json">tag into the page<head>. - Because
useHeadis SSR-safe, the JSON-LD is rendered server-side and visible to search engine crawlers on first paint — unlike<ClientOnly>approaches that only render client-side. - Default values for publisher/organizer/seller come from
app.config.tsvia theuseSchema()composable, so you configure once and all components use consistent branding. - String values for
author,founder,brand, andalumniOfare automatically converted to proper Schema.org typed objects (Person, Organization, Brand).
Layer Architecture
app/components/X/Schema/*.vue— 16 renderless components, each generating a specific Schema.org typeapp/composables/useSchema.ts— Shared utilities for URL resolution, default org/publisher, author normalization, anduseHeadinjectionapp/types/schema.ts— TypeScript interfaces for all Schema.org types used by componentsapp.config.ts— Layer defaults with type augmentation forxSchemanamespacenuxt.config.ts— Minimal layer config (components and composables auto-imported by Nuxt)
Validation
Test your schema output with:
Related Packages
A comprehensive Nuxt layer providing production-ready admin dashboard components...
A premium card component library for Nuxt 4 with cinematic image filters, warm s...
A comprehensive Nuxt layer for building marketing websites with 38+ pre-built co...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.3.0 | ^3.0.0 | Custom | |
| 0.2.3 | >=3.0.0 | Custom | |
| 0.2.2 | >=3.0.0 | Custom | |
| 0.2.1 | latest | Custom | |
| 0.2.0 | latest | Proprietary | |
| 0.1.3 | latest | ||
| 0.1.2 | latest | ||
| 0.1.0 | latest |