diff --git a/components/accordion/files/index.blade.php b/components/accordion/files/index.blade.php index 95a7710..8979c04 100755 --- a/components/accordion/files/index.blade.php +++ b/components/accordion/files/index.blade.php @@ -1,9 +1,86 @@ @props([ - 'reverse' => false + 'reverse' => false, + 'faq' => false ]) -
loadHTML( + '
' . $slotHtml . '
', + LIBXML_NOERROR | LIBXML_NOWARNING + ); + libxml_clear_errors(); + + foreach ((new \DOMXPath($dom))->query('//*[@role="region"]') as $region) { + $trigger = null; + $panel = null; + + foreach ($region->childNodes as $child) { + if (!$child instanceof \DOMElement) { + continue; + } + + if ($child->tagName === 'button' && !$trigger) { + $trigger = $child; + } elseif ($child->tagName === 'div' && !$panel) { + $panel = $child; + } + } + + if (!$trigger || !$panel) { + continue; + } + + $question = trim(preg_replace('/\s+/', ' ', $trigger->textContent)); + + $answerHtml = ''; + foreach ($panel->firstElementChild?->childNodes ?? [] as $node) { + $answerHtml .= $dom->saveHTML($node); + } + $answerHtml = trim($answerHtml); + + if ($question === '' || $answerHtml === '') { + continue; + } + + $questions[] = [ + '@type' => 'Question', + 'name' => $question, + 'acceptedAnswer' => [ + '@type' => 'Answer', + 'text' => $answerHtml, + ], + ]; + } + + if (!empty($questions)) { + $faqSchema = [ + '@context' => 'https://schema.org', + '@type' => 'FAQPage', + 'mainEntity' => $questions, + ]; + } + } + } +@endphp + +@if ($faqSchema) + @push('head') + + @endpush +@endif + +
merge([ 'class'=>"w-full flex flex-col" ]) }} diff --git a/components/accordion/usage.md b/components/accordion/usage.md index 202cd2f..0d61c44 100644 --- a/components/accordion/usage.md +++ b/components/accordion/usage.md @@ -284,6 +284,34 @@ Use the reverse layout to position chevron icons on the left side. ``` +### FAQ Schema (JSON-LD) + +Add the `faq` attribute to the root `` tag to automatically generate a [FAQPage JSON-LD schema](https://developers.google.com/search/docs/appearance/structured-data/faqpage) from the accordion's triggers and content, and push it to your page's ``. + +This walks the rendered accordion items, using each trigger's text as the `Question` and each content panel's markup as the `Answer`. + +```blade + + +

We offer a 30-day return policy for all unused items in their original packaging.

+
+ +

Standard shipping typically takes 3-5 business days.

+
+
+``` + +This pushes a `