The Nuxt AEO module automatically generates semantic HTML along with Schema.org JSON-LD to optimize LLM crawling.
The automatic semantic HTML generation feature:
display: none, but is included in the HTML source so LLMs and crawlers can read itFirst, Schema.org JSON-LD is injected into the <head> tag:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [...]
}
</script>
When using the renderHtml: true option, semantic HTML is automatically generated based on schema data and injected into the <body> tag:
<div class="nuxt-aeo-semantic-faqpage nuxt-aeo-visually-hidden" aria-hidden="true">
<div itemscope itemtype="https://schema.org/FAQPage">
<div itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">
<h2 itemprop="name">Question</h2>
<div itemprop="acceptedAnswer" itemscope itemtype="https://schema.org/Answer">
<p itemprop="text">Answer</p>
</div>
</div>
</div>
</div>
When visuallyHidden: true (default), the generated semantic HTML is hidden with the visually-hidden class:
.nuxt-aeo-visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
useSchemaFaq is set to renderHtml: true by default:
<script setup lang="ts">
useSchemaFaq({
mainEntity: [
{
name: 'Question 1',
acceptedAnswer: {
text: 'Answer 1',
},
},
],
renderHtml: true, // Default: true
visuallyHidden: true, // Default: true
})
</script>
useSchema is set to renderHtml: false by default. To generate semantic HTML, you must explicitly set renderHtml: true:
<script setup lang="ts">
useSchema({
context: 'https://schema.org',
type: 'Organization',
name: 'My Company',
url: 'https://example.com',
renderHtml: true, // Generate semantic HTML
visuallyHidden: true, // Visually hide
})
</script>
You can configure globally in nuxt.config.ts:
export default defineNuxtConfig({
modules: ['nuxt-aeo'],
aeo: {
schemas: [
{
type: 'Organization',
name: 'My Company',
url: '/', // Relative URL - will be normalized to absolute
logo: '/images/logo.png', // Relative URL - will be normalized to absolute
renderHtml: true, // Set on individual schema
visuallyHidden: true,
},
],
renderHtml: true, // Global default value
visuallyHidden: true, // Global default value
},
})
Semantic HTML is automatically generated for the following Schema types:
<script setup lang="ts">
useSchema({
context: 'https://schema.org',
type: 'Person',
name: 'John Doe',
alternateName: 'JD',
jobTitle: 'Software Engineer',
url: '/profile', // Relative URL - will be normalized to absolute
image: 'https://example.com/profile.jpg', // Absolute URL - used as-is
knowsAbout: ['JavaScript', 'TypeScript'],
renderHtml: true,
})
</script>
Generated HTML:
<div itemscope itemtype="https://schema.org/Person">
<span itemprop="name">John Doe</span>
<span itemprop="alternateName">JD</span>
<span itemprop="jobTitle">Software Engineer</span>
<a itemprop="url" href="https://example.com">https://example.com</a>
<span itemprop="knowsAbout">JavaScript</span>
<span itemprop="knowsAbout">TypeScript</span>
</div>
<script setup lang="ts">
useSchema({
context: 'https://schema.org',
type: 'Organization',
name: 'My Company',
description: 'Company description',
url: '/', // Relative URL - will be normalized to absolute
logo: '/images/logo.png', // Relative URL - will be normalized to absolute
renderHtml: true,
})
</script>
Generated HTML:
<div itemscope itemtype="https://schema.org/Organization">
<span itemprop="name">My Company</span>
<span itemprop="description">Company description</span>
<a itemprop="url" href="https://example.com">https://example.com</a>
</div>
<script setup lang="ts">
useSchema({
context: 'https://schema.org',
type: 'ItemList',
name: 'Top 10 Languages',
description: 'List description',
itemListElement: [
{
type: 'ListItem',
position: 1,
name: 'JavaScript',
item: '/tech/javascript', // Relative URL - will be normalized to absolute
},
{
type: 'ListItem',
position: 2,
name: 'TypeScript',
item: 'https://www.typescriptlang.org', // Absolute URL - used as-is
},
],
renderHtml: true,
})
</script>
Generated HTML:
<div itemscope itemtype="https://schema.org/ItemList">
<span itemprop="name">Top 10 Languages</span>
<span itemprop="description">List description</span>
<ol>
<li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<meta itemprop="position" content="1">
<span itemprop="name">JavaScript</span>
<a itemprop="item" href="https://example.com/javascript">https://example.com/javascript</a>
</li>
</ol>
</div>
<script setup lang="ts">
useSchema({
context: 'https://schema.org',
type: 'Article',
headline: 'Article Title',
description: 'Article description',
datePublished: '2024-01-15',
image: '/images/article.jpg', // Relative URL - will be normalized to absolute
author: {
type: 'Person',
name: 'John Doe',
url: 'https://example.com/author', // Absolute URL - used as-is
},
renderHtml: true,
})
</script>
Generated HTML:
<div itemscope itemtype="https://schema.org/Article">
<span itemprop="headline">Article Title</span>
<span itemprop="description">Article description</span>
<span itemprop="datePublished">2024-01-15</span>
<div itemprop="author" itemscope itemtype="https://schema.org/Person">
<span itemprop="name">John Doe</span>
</div>
</div>
<body> tag in the Elements tabnuxt-aeo-semantic-* classRun the following command in the Developer Tools console:
// Check semantic HTML
document.querySelectorAll('[class*="nuxt-aeo-semantic"]').forEach(el => {
console.log('✅ Found:', el.className, el.innerHTML.substring(0, 100) + '...')
})
// Check JSON-LD schema
document.querySelectorAll('script[type="application/ld+json"]').forEach(script => {
console.log('✅ JSON-LD:', JSON.parse(script.innerHTML))
})
Some LLM crawlers and search engines may not be sufficient with JSON-LD alone. Using semantic HTML together:
Important: The generated semantic HTML is hidden with the
visually-hiddenclass and is not visible to users. However, it is included in the HTML source so LLMs and crawlers can read it.
This page includes FAQPage Schema to help AI models and search engines understand common questions about automatic semantic HTML generation.
<script setup lang="ts">
useSchemaFaq({
mainEntity: [
{
name: 'Why is semantic HTML needed?',
acceptedAnswer: {
text: 'Some LLM crawlers and search engines may not be sufficient with JSON-LD alone. Using JSON-LD and semantic HTML together allows crawlers that read HTML source directly to better understand content and ensures maximum compatibility.',
},
},
{
name: 'What is the default value of the renderHtml option?',
acceptedAnswer: {
text: 'For useSchemaFaq(), the default value of renderHtml is true, while for useSchema(), the default is false. In global configuration, the default value of renderHtml is also true.',
},
},
{
name: 'Is the generated HTML visible to users?',
acceptedAnswer: {
text: 'No, the generated semantic HTML is hidden with the visually-hidden class and is not visible to users. However, it is included in the HTML source so LLM crawlers and search engines can read it.',
},
},
{
name: 'Which Schema types generate semantic HTML?',
acceptedAnswer: {
text: 'Semantic HTML is automatically generated for major Schema types such as Person, Organization, ItemList, Article, and FAQPage. Appropriate HTML structure and microdata attributes are generated for each type.',
},
},
],
})
</script>