@@ -113,7 +113,6 @@ watch(
113113 },
114114)
115115
116- // Fetch provenance details when the displayed version has attestations
117116const {
118117 data : provenanceData,
119118 status : provenanceStatus,
@@ -130,15 +129,18 @@ const {
130129 immediate: false ,
131130 },
132131)
133- watch (
134- () => [displayVersion .value ?.version , hasProvenance (displayVersion .value )],
135- () => {
132+ if (import .meta .client ) {
133+ watchEffect (() => {
136134 if (displayVersion .value && hasProvenance (displayVersion .value )) {
137135 fetchProvenance ()
138136 }
139- },
140- { immediate: true },
141- )
137+ })
138+ }
139+
140+ const provenanceBadgeMounted = ref (false )
141+ onMounted (() => {
142+ provenanceBadgeMounted .value = true
143+ })
142144
143145// Keep latestVersion for comparison (to show "(latest)" badge)
144146const latestVersion = computed (() => {
@@ -294,8 +296,6 @@ function getDependencyCount(version: PackumentVersion | null): number {
294296 return Object .keys (version .dependencies ).length
295297}
296298
297- // Check if a version has provenance/attestations
298- // The dist object may have attestations that aren't in the base type
299299function hasProvenance(version : PackumentVersion | null ): boolean {
300300 if (! version ?.dist ) return false
301301 const dist = version .dist as NpmVersionDist
@@ -440,40 +440,48 @@ function handleClick(event: MouseEvent) {
440440 >
441441 <span v-else >v{{ displayVersion.version }}</span >
442442
443- <AppPopover v-if =" hasProvenance(displayVersion)" position =" bottom" >
444- <template #content >
445- <p class =" flex items-center gap-2 text-fg m-0" >
446- <span
447- class =" i-solar-shield-check-outline w-3.5 h-3.5 shrink-0 text-emerald-500"
448- aria-hidden =" true"
449- />
450- <span >{{
451- provenanceData
452- ? $t('package.provenance_section.built_and_signed_on', {
453- provider: provenanceData.providerLabel,
454- })
455- : $t('package.verified_provenance')
456- }}</span >
457- </p >
458- <a href =" #provenance" class =" block mt-1.5 link font-medium" >
459- {{ $t('package.provenance_section.view_more_details') }}
460- </a >
461- </template >
462- <template #default =" { popoverVisible } " >
463- <a
464- :href =" `https://www.npmjs.com/package/${pkg.name}/v/${displayVersion.version}#provenance`"
465- target =" _blank"
466- rel =" noopener noreferrer"
467- class =" inline-flex items-center justify-center gap-1.5 text-fg-muted hover:text-emerald-500 transition-colors duration-200 min-w-6 min-h-6"
468- :class =" popoverVisible && 'text-emerald-500'"
469- >
470- <span
471- class =" i-solar-shield-check-outline w-3.5 h-3.5 shrink-0"
472- aria-hidden =" true"
473- />
474- </a >
475- </template >
476- </AppPopover >
443+ <template v-if =" hasProvenance (displayVersion ) && provenanceBadgeMounted " >
444+ <div class =" relative inline-flex" >
445+ <AppPopover position =" bottom" >
446+ <template #content >
447+ <p class =" flex items-center gap-2 text-fg m-0" >
448+ <span
449+ class =" i-solar-shield-check-outline w-3.5 h-3.5 shrink-0 text-emerald-500"
450+ aria-hidden =" true"
451+ />
452+ <span >{{
453+ provenanceData && provenanceStatus !== 'pending'
454+ ? $t('package.provenance_section.built_and_signed_on', {
455+ provider: provenanceData.providerLabel,
456+ })
457+ : $t('package.verified_provenance')
458+ }}</span >
459+ </p >
460+ <a href =" #provenance" class =" block mt-1.5 link font-medium" >
461+ {{ $t('package.provenance_section.view_more_details') }}
462+ </a >
463+ </template >
464+ <template #default =" { popoverVisible , popoverId } " >
465+ <a
466+ :href =" `https://www.npmjs.com/package/${pkg.name}/v/${displayVersion.version}#provenance`"
467+ target =" _blank"
468+ rel =" noopener noreferrer"
469+ :aria-label =" $t('package.provenance_section.view_more_details')"
470+ :aria-expanded =" popoverVisible"
471+ aria-haspopup =" true"
472+ :aria-controls =" popoverVisible ? popoverId : undefined"
473+ class =" inline-flex items-center justify-center gap-1.5 text-fg-muted hover:text-emerald-500 transition-colors duration-200 min-w-6 min-h-6"
474+ :class =" popoverVisible && 'text-emerald-500'"
475+ >
476+ <span
477+ class =" i-solar-shield-check-outline w-3.5 h-3.5 shrink-0"
478+ aria-hidden =" true"
479+ />
480+ </a >
481+ </template >
482+ </AppPopover >
483+ </div >
484+ </template >
477485 <span
478486 v-if ="
479487 requestedVersion &&
@@ -951,8 +959,11 @@ function handleClick(event: MouseEvent) {
951959 }}</a >
952960 </p >
953961
954- <!-- Provenance details (when version has attestations) -->
955- <template v-if =" hasProvenance (displayVersion )" >
962+ <section
963+ v-if =" hasProvenance(displayVersion) && provenanceBadgeMounted"
964+ id =" provenance"
965+ class =" scroll-mt-20"
966+ >
956967 <div
957968 v-if =" provenanceStatus === 'pending'"
958969 class =" mt-8 flex items-center gap-2 text-fg-subtle text-sm"
@@ -970,7 +981,7 @@ function handleClick(event: MouseEvent) {
970981 :version =" displayVersion?.version"
971982 class =" mt-8"
972983 />
973- </template >
984+ </section >
974985 </section >
975986
976987 <div class =" area-sidebar" >
0 commit comments