1- import { For , Show } from 'solid-js'
1+ import { For , Show , createMemo , createSignal } from 'solid-js'
22import { Section , SectionDescription } from '@tanstack/devtools-ui'
3+ import { useHeadChanges } from '../hooks/use-head-changes'
4+ import { useLocationChanges } from '../hooks/use-location-changes'
35import { isInsideDevtools } from '../utils/devtools-dom-filter'
46import { sectionHealthScore } from '../utils/seo-section-summary'
57import { useSeoStyles } from '../utils/use-seo-styles'
@@ -340,7 +342,7 @@ function analyzeJsonLdScripts(): Array<JsonLdEntry> {
340342 ) . filter ( ( script ) => ! isInsideDevtools ( script ) )
341343
342344 return scripts . map ( ( script , index ) => {
343- const raw = script . textContent . trim ( ) || ''
345+ const raw = script . text . trim ( )
344346 if ( raw . length === 0 ) {
345347 return {
346348 id : `jsonld-${ index } ` ,
@@ -600,21 +602,34 @@ function JsonLdBlock(props: { entry: JsonLdEntry; index: number }) {
600602}
601603
602604export function JsonLdPreviewSection ( ) {
603- const entries = analyzeJsonLdScripts ( )
604605 const styles = useSeoStyles ( )
605- const score = getJsonLdScore ( entries )
606+ const [ tick , setTick ] = createSignal ( 0 )
607+
608+ useHeadChanges ( ( ) => {
609+ setTick ( ( t ) => t + 1 )
610+ } )
611+
612+ useLocationChanges ( ( ) => {
613+ setTick ( ( t ) => t + 1 )
614+ } )
615+
616+ const entries = createMemo ( ( ) => {
617+ void tick ( )
618+ return analyzeJsonLdScripts ( )
619+ } )
620+ const score = createMemo ( ( ) => getJsonLdScore ( entries ( ) ) )
606621 const s = styles ( )
607- const fieldGaps = sumMissingSchemaFieldCounts ( entries )
622+ const fieldGaps = createMemo ( ( ) => sumMissingSchemaFieldCounts ( entries ( ) ) )
608623 const healthScoreClass = ( ) => {
609- const tier = seoHealthTier ( score )
624+ const tier = seoHealthTier ( score ( ) )
610625 return tier === 'good'
611626 ? s . seoHealthScoreGood
612627 : tier === 'fair'
613628 ? s . seoHealthScoreFair
614629 : s . seoHealthScorePoor
615630 }
616631 const healthFillClass = ( ) => {
617- const tier = seoHealthTier ( score )
632+ const tier = seoHealthTier ( score ( ) )
618633 const tierFill =
619634 tier === 'good'
620635 ? s . seoHealthFillGood
@@ -623,55 +638,56 @@ export function JsonLdPreviewSection() {
623638 : s . seoHealthFillPoor
624639 return `${ s . seoHealthFill } ${ tierFill } `
625640 }
626- const errorCount = entries . reduce (
641+ const errorCount = ( ) => entries ( ) . reduce (
627642 ( total , entry ) =>
628643 total + entry . issues . filter ( ( issue ) => issue . severity === 'error' ) . length ,
629644 0 ,
630645 )
631- const warningCount = entries . reduce (
646+ const warningCount = ( ) => entries ( ) . reduce (
632647 ( total , entry ) =>
633648 total +
634649 entry . issues . filter ( ( issue ) => issue . severity === 'warning' ) . length ,
635650 0 ,
636651 )
637- const infoCount = entries . reduce (
652+ const infoCount = ( ) => entries ( ) . reduce (
638653 ( total , entry ) =>
639654 total + entry . issues . filter ( ( issue ) => issue . severity === 'info' ) . length ,
640655 0 ,
641656 )
642- const progressAriaLabel = ( ( ) => {
643- const parts = [ `JSON-LD health ${ Math . round ( score ) } percent` ]
657+ const progressAriaLabel = createMemo ( ( ) => {
658+ const parts = [ `JSON-LD health ${ Math . round ( score ( ) ) } percent` ]
644659 const sev = [
645- errorCount && `${ errorCount } error${ errorCount === 1 ? '' : 's' } ` ,
646- warningCount && `${ warningCount } warning${ warningCount === 1 ? '' : 's' } ` ,
647- infoCount && `${ infoCount } info` ,
660+ errorCount ( ) && `${ errorCount ( ) } error${ errorCount ( ) === 1 ? '' : 's' } ` ,
661+ warningCount ( ) &&
662+ `${ warningCount ( ) } warning${ warningCount ( ) === 1 ? '' : 's' } ` ,
663+ infoCount ( ) && `${ infoCount ( ) } info` ,
648664 ] . filter ( Boolean )
649665 if ( sev . length ) parts . push ( sev . join ( ', ' ) )
650666 const gapBits : Array < string > = [ ]
651- if ( fieldGaps . required > 0 )
667+ if ( fieldGaps ( ) . required > 0 )
652668 gapBits . push (
653- `${ fieldGaps . required } required field${ fieldGaps . required === 1 ? '' : 's' } ` ,
669+ `${ fieldGaps ( ) . required } required field${ fieldGaps ( ) . required === 1 ? '' : 's' } ` ,
654670 )
655- if ( fieldGaps . recommended > 0 )
671+ if ( fieldGaps ( ) . recommended > 0 )
656672 gapBits . push (
657- `${ fieldGaps . recommended } recommended field${ fieldGaps . recommended === 1 ? '' : 's' } ` ,
673+ `${ fieldGaps ( ) . recommended } recommended field${ fieldGaps ( ) . recommended === 1 ? '' : 's' } ` ,
658674 )
659- if ( fieldGaps . optional > 0 )
675+ if ( fieldGaps ( ) . optional > 0 )
660676 gapBits . push (
661- `${ fieldGaps . optional } optional field${ fieldGaps . optional === 1 ? '' : 's' } ` ,
677+ `${ fieldGaps ( ) . optional } optional field${ fieldGaps ( ) . optional === 1 ? '' : 's' } ` ,
662678 )
663679 if ( gapBits . length ) parts . push ( `Missing: ${ gapBits . join ( ', ' ) } ` )
664680 return parts . join ( '. ' )
665- } ) ( )
666- const missingFieldsLine = ( ( ) => {
681+ } )
682+ const missingFieldsLine = createMemo ( ( ) => {
667683 const bits : Array < string > = [ ]
668- if ( fieldGaps . required > 0 ) bits . push ( `${ fieldGaps . required } required` )
669- if ( fieldGaps . recommended > 0 )
670- bits . push ( `${ fieldGaps . recommended } recommended` )
671- if ( fieldGaps . optional > 0 ) bits . push ( `${ fieldGaps . optional } optional` )
684+ if ( fieldGaps ( ) . required > 0 ) bits . push ( `${ fieldGaps ( ) . required } required` )
685+ if ( fieldGaps ( ) . recommended > 0 )
686+ bits . push ( `${ fieldGaps ( ) . recommended } recommended` )
687+ if ( fieldGaps ( ) . optional > 0 ) bits . push ( `${ fieldGaps ( ) . optional } optional` )
672688 if ( bits . length === 0 ) return null
673689 return `Missing schema fields: ${ bits . join ( ' · ' ) } `
674- } ) ( )
690+ } )
675691
676692 return (
677693 < Section >
@@ -693,7 +709,7 @@ export function JsonLdPreviewSection() {
693709 </ div >
694710 </ div >
695711 < Show
696- when = { entries . length > 0 }
712+ when = { entries ( ) . length > 0 }
697713 fallback = {
698714 < div class = { styles ( ) . seoMissingTagsSection } >
699715 No JSON-LD scripts were detected on this page.
@@ -703,37 +719,39 @@ export function JsonLdPreviewSection() {
703719 < div class = { s . seoJsonLdHealthCard } >
704720 < div class = { s . seoHealthHeaderRow } >
705721 < span class = { s . seoJsonLdHealthTitle } > JSON-LD Health</ span >
706- < span class = { healthScoreClass ( ) } > { score } %</ span >
722+ < span class = { healthScoreClass ( ) } > { score ( ) } %</ span >
707723 </ div >
708724 < div
709725 class = { s . seoHealthTrack }
710726 role = "progressbar"
711727 aria-valuemin = { 0 }
712728 aria-valuemax = { 100 }
713- aria-valuenow = { Math . round ( score ) }
714- aria-label = { progressAriaLabel }
729+ aria-valuenow = { Math . round ( score ( ) ) }
730+ aria-label = { progressAriaLabel ( ) }
715731 >
716732 < div
717733 class = { healthFillClass ( ) }
718- style = { { width : `${ Math . min ( 100 , Math . max ( 0 , score ) ) } %` } }
734+ style = { { width : `${ Math . min ( 100 , Math . max ( 0 , score ( ) ) ) } %` } }
719735 />
720736 </ div >
721737 < div class = { s . seoHealthCountsRow } >
722738 < span class = { s . seoHealthCountError } >
723- { errorCount } error{ errorCount === 1 ? '' : 's' }
739+ { errorCount ( ) } error{ errorCount ( ) === 1 ? '' : 's' }
724740 </ span >
725741 < span class = { s . seoHealthCountWarning } >
726- { warningCount } warning{ warningCount === 1 ? '' : 's' }
742+ { warningCount ( ) } warning{ warningCount ( ) === 1 ? '' : 's' }
727743 </ span >
728744 < span class = { s . seoHealthCountInfo } >
729- { infoCount } info{ infoCount === 1 ? '' : 's' } (2 pts each)
745+ { infoCount ( ) } info{ infoCount ( ) === 1 ? '' : 's' } (2 pts each)
730746 </ span >
731747 </ div >
732- < Show when = { missingFieldsLine } >
733- < div class = { s . seoJsonLdHealthMissingLine } > { missingFieldsLine } </ div >
748+ < Show when = { missingFieldsLine ( ) } >
749+ < div class = { s . seoJsonLdHealthMissingLine } >
750+ { missingFieldsLine ( ) }
751+ </ div >
734752 </ Show >
735753 </ div >
736- < For each = { entries } >
754+ < For each = { entries ( ) } >
737755 { ( entry , index ) => < JsonLdBlock entry = { entry } index = { index ( ) } /> }
738756 </ For >
739757 </ Show >
0 commit comments