Schema.org is a vocabulary of structured data that helps search engines understand the content and context of your pages. By adding Schema.org markup (typically as JSON-LD), you enable rich snippets in Google search results—enhanced displays that can show:
Rich snippets can increase click-through rates by up to 30% and provide users with more information before they visit your site.
Laioutr can use Nuxt Schema.org (part of Nuxt SEO) to automatically generate JSON-LD structured data for your pages. Unlike robots.txt (which is included by default), Schema.org is optional and needs to be added to your project.
Nuxt Schema.org provides a simple API to define structured data using 30+ Schema.org node types (Organization, Product, BreadcrumbList, FAQPage, etc.). The module:
<head>noindex skip Schema.org renderingYou define structured data using composables (e.g. useSchemaOrg) in your pages or components, and the module handles the rest.
To enable Schema.org structured data, add @nuxtjs/schema-org to your Nuxt modules:
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'@laioutr-core/frontend-core',
'@nuxtjs/schema-org', // Add this
// ... other modules
],
});
Then install the package:
pnpm add @nuxtjs/schema-org
# or
npm install @nuxtjs/schema-org
Set global defaults in nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
schemaOrg: {
// Your site URL
host: 'https://yourstore.com',
// Default language
defaultLanguage: 'en',
},
});
Define your organization and website once, and it will be included on all pages:
// nuxt.config.ts or a plugin
import { useSchemaOrg } from '#imports';
useSchemaOrg({
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'Your Store',
url: 'https://yourstore.com',
logo: 'https://yourstore.com/logo.png',
sameAs: [
'https://twitter.com/yourstore',
'https://facebook.com/yourstore',
],
});
Add Product structured data to product detail pages:
// In a product detail page component or section
import { useSchemaOrg } from '#imports';
const product = await useOrchestr().executeQuery(ProductBySlugQuery, { slug });
useSchemaOrg([
{
'@type': 'Product',
name: product.name,
description: product.description,
image: product.media.map(m => m.sources[0].src),
brand: {
'@type': 'Brand',
name: product.brand,
},
offers: {
'@type': 'Offer',
price: product.prices.price,
priceCurrency: product.prices.currency,
availability: product.inStock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',
},
aggregateRating: product.rating ? {
'@type': 'AggregateRating',
ratingValue: product.rating.average,
reviewCount: product.rating.count,
} : undefined,
},
]);
Add breadcrumb navigation for better search result display:
// In PageRenderer or a breadcrumb component
import { useSchemaOrg } from '#imports';
const breadcrumbs = [
{ name: 'Home', url: '/' },
{ name: 'Category', url: '/categories/electronics' },
{ name: 'Product', url: '/products/laptop' },
];
useSchemaOrg({
'@type': 'BreadcrumbList',
itemListElement: breadcrumbs.map((crumb, index) => ({
'@type': 'ListItem',
position: index + 1,
name: crumb.name,
item: crumb.url,
})),
});
Define your organization and website structure:
// In a plugin or app.vue
import { useSchemaOrg } from '#imports';
useSchemaOrg([
{
'@type': 'Organization',
name: 'Your Store',
url: 'https://yourstore.com',
logo: 'https://yourstore.com/logo.png',
},
{
'@type': 'WebSite',
name: 'Your Store',
url: 'https://yourstore.com',
potentialAction: {
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: 'https://yourstore.com/search?q={search_term_string}',
},
'query-input': 'required name=search_term_string',
},
},
]);
Add FAQ structured data for FAQ pages:
// In an FAQ page component
import { useSchemaOrg } from '#imports';
const faqs = [
{ question: 'What is your return policy?', answer: 'We offer 30-day returns...' },
{ question: 'Do you ship internationally?', answer: 'Yes, we ship worldwide...' },
];
useSchemaOrg({
'@type': 'FAQPage',
mainEntity: faqs.map(faq => ({
'@type': 'Question',
name: faq.question,
acceptedAnswer: {
'@type': 'Answer',
text: faq.answer,
},
})),
});
Since Laioutr pages are rendered via PageRenderer, you can add structured data per page type:
useProductSchema, useCategorySchema)For example, in a product detail section:
<!-- sections/ProductDetail.vue -->
<script setup lang="ts">
import { useSchemaOrg } from '#imports';
const props = defineProps<{
product: Product;
}>();
// Add Product structured data
useSchemaOrg({
'@type': 'Product',
name: props.product.name,
description: props.product.description,
// ... other product fields
});
</script>
Since pages fetch data via Orchestr (products, categories, etc.), you can use that data to generate structured data:
// After fetching product data
const product = await useOrchestr().executeQuery(ProductBySlugQuery, { slug });
useSchemaOrg({
'@type': 'Product',
name: product.name,
description: product.description,
image: product.media?.map(m => m.sources[0]?.src).filter(Boolean),
offers: {
'@type': 'Offer',
price: product.prices.price,
priceCurrency: product.prices.currency,
availability: product.inStock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock',
},
});
If you're using @nuxtjs/robots (which is included by default), Nuxt Schema.org automatically skips rendering structured data for pages marked as noindex. This ensures that pages excluded from search results don't send conflicting signals to search engines.
You can combine Schema.org with the page variant's SEO settings from Studio:
// In PageRenderer or a page component
const pageVariant = computed(() => props.page.variants[0]);
useSchemaOrg({
'@type': 'WebPage',
name: pageVariant.value.seo.title || props.page.type,
description: pageVariant.value.seo.description,
url: currentUrl,
});
You can add multiple schema types to a single page:
useSchemaOrg([
{ '@type': 'Product', /* ... */ },
{ '@type': 'BreadcrumbList', /* ... */ },
{ '@type': 'Organization', /* ... */ },
]);
Add structured data conditionally based on page type or data:
// In PageRenderer or a page component
if (props.page.type === 'ecommerce/product-detail-page') {
useSchemaOrg({
'@type': 'Product',
// ... product data
});
} else if (props.page.type === 'ecommerce/product-listing-page') {
useSchemaOrg({
'@type': 'CollectionPage',
// ... collection data
});
}
Nuxt Schema.org supports 30+ built-in types, but you can also define custom schema if needed:
useSchemaOrg({
'@context': 'https://schema.org',
'@type': 'CustomType',
// ... your custom properties
});
Use the Schema.org Validator to test your JSON-LD markup and find errors. You can also:
<head> sectionnoindex skip Schema.org rendering automatically.For detailed configuration options, available schema types, and advanced usage, see the Nuxt Schema.org documentation.
Robots.txt
Control how search engines and crawlers interact with your Laioutr frontend using robots.txt, meta tags, and X-Robots-Tag headers. Configure globally and per-page via Studio.
Sitemap
Generate XML sitemaps for your Laioutr frontend to help search engines discover and index your pages. Automatically includes pages from your runtime config and integrates with robots.txt.