Skip to content

fix: finish getting star metadata when rendering og images#933

Merged
danielroe merged 9 commits intonpmx-dev:mainfrom
alexdln:fix/stars-in-og-images
Feb 4, 2026
Merged

fix: finish getting star metadata when rendering og images#933
danielroe merged 9 commits intonpmx-dev:mainfrom
alexdln:fix/stars-in-og-images

Conversation

@alexdln
Copy link
Member

@alexdln alexdln commented Feb 4, 2026

What

Stars weren't showing up in OG images. This made previews look sad

The problem was that we weren't actually waiting for stars to load, as they're lazy.

Downloads worked because there was an await loadVersion below, which essentially just took longer, and that was enough.

Fix

I added a condition that if it is one of the standard scanners, it will wait for a full render on the server and only then return a response.

Test

To test we can override the agent (Chrome docs) for something like:

facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)

Closes #932

@vercel
Copy link

vercel bot commented Feb 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 4, 2026 2:33pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 4, 2026 2:33pm
npmx-lunaria Ignored Ignored Feb 4, 2026 2:33pm

Request Review

@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/pages/package/[...package].vue 0.00% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

The PR moves the package OG image definition to the top of app/pages/package/[...package].vue, changing its inputs to derive name from packageName and version from requestedVersion, and removes downloads, stars and license inputs plus the usePackageDownloads(packageName, 'last-week') hook. The OgImage component at app/components/OgImage/Package.vue was refactored to resolve exact versions server‑side, fetch package/repo/downloads data, handle 4xx resolution as 404, construct monorepo repository URLs with joinURL, and refresh data on mount. A declaration file app/components/OgImage/Package.d.vue.ts was added.

Possibly related PRs

  • PR 849 — Adjusts knip configuration/workspace glob patterns, which is directly related to adding .d.vue.ts files in app/components (knip.ts change).
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description check ✅ Passed The description explains the issue with missing stars in OG images, the root cause (lazy loading), and the solution implemented (waiting for full server-side render for crawlers).
Linked Issues check ✅ Passed Changes address the core objective of ensuring lazy-loaded stars are included in OG images by implementing server-side render waiting for crawler detection.
Out of Scope Changes check ✅ Passed All changes focus on fixing the missing stars issue: OG image component refactoring, server-side data fetching, and configuration updates directly support the linked issue requirement.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Important

Action Needed: IP Allowlist Update

If your organization protects your Git platform with IP whitelisting, please add the new CodeRabbit IP address to your allowlist:

  • 136.113.208.247/32 (new)
  • 34.170.211.100/32
  • 35.222.179.152/32

Reviews will stop working after February 8, 2026 if the new IP is not added to your allowlist.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/pages/package/[...package].vue (1)

461-463: Redundant case normalisation.

The regex already uses the /i flag for case-insensitive matching, making .toLowerCase() unnecessary.

♻️ Suggested simplification
-  const agent = event?.node.req.headers['user-agent']?.toLowerCase() || ''
-  const crawlerRegex =
-    /(facebookexternalhit|bluesky|twitterbot|linkedinbot|discordbot|slackbot|telegrambot|whatsapp|vkshare|skypeuripreview|googlebot|bingbot|yandexbot|baiduspider|duckduckbot|crawler|spider|bot|preview)/i
+  const agent = event?.node.req.headers['user-agent'] || ''
+  const crawlerRegex =
+    /(facebookexternalhit|bluesky|twitterbot|linkedinbot|discordbot|slackbot|telegrambot|whatsapp|vkshare|skypeuripreview|googlebot|bingbot|yandexbot|baiduspider|duckduckbot|crawler|spider|bot|preview)/i

@alexdln
Copy link
Member Author

alexdln commented Feb 4, 2026

Found a specific case: if the user visited this page themselves and visited it before the crawler, we'll cache the user's version (without wait). Generally, this link isn't very accessible to users, and they shouldn't visit it, but it's still topic to talk about

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about instead we move this logic into the Package ogImage component itself and perform the fetch there, awaiting the data?

@alexdln
Copy link
Member Author

alexdln commented Feb 4, 2026

@danielroe How confident are we in caching and memoization? Couldn't this results that the OG crawler will load data from the main page to obtain the title and description, and the same requests will be sent from this component in parallel?

And how critical is this probability 🤔

@danielroe
Copy link
Member

it would deduplicate.

@alexdln
Copy link
Member Author

alexdln commented Feb 4, 2026

It looks much better now, thanks

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
app/components/OgImage/Package.vue (2)

52-57: Consider handling undefined stars gracefully.

If stars.value is undefined or null, Intl.NumberFormat.format() will produce "NaN". Consider providing a fallback value.

♻️ Proposed improvement
 const formattedStars = computed(() =>
   Intl.NumberFormat('en', {
     notation: 'compact',
     maximumFractionDigits: 1,
-  }).format(stars.value),
+  }).format(stars.value ?? 0),
 )

122-123: Consider defensive access for downloads.downloads.

Whilst v-if="downloads" guards against a null downloads object, if the API response structure ever changes or downloads.downloads is undefined, this could display incorrectly. Consider using optional chaining or a fallback.

♻️ Proposed improvement
-        <span v-if="downloads">
-          <span>• {{ $n(downloads.downloads) }} </span>
+        <span v-if="downloads?.downloads != null">
+          <span>• {{ $n(downloads.downloads) }} </span>

@alexdln
Copy link
Member Author

alexdln commented Feb 4, 2026

Oops, sorry I missed that. Is there anything I can do to catch these errors locally?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
app/components/OgImage/Package.vue (1)

51-56: Consider guarding against undefined stars value.

If stars.value is undefined or null before the repo metadata loads, Intl.NumberFormat.format() will return "NaN". Consider providing a fallback.

💡 Suggested improvement
 const formattedStars = computed(() =>
   Intl.NumberFormat('en', {
     notation: 'compact',
     maximumFractionDigits: 1,
-  }).format(stars.value),
+  }).format(stars.value ?? 0),
 )

@danielroe
Copy link
Member

in this case it's absolutely not your bug - it's a side effect of something nuxt-og-image is doing and my 'fix' is more of a workaround.

we probably need to fix upstream in nuxt-og-image

@danielroe danielroe changed the title fix: wait page readiness for robots and og fix: finish getting star metadata when rendering og images Feb 4, 2026
@danielroe danielroe enabled auto-merge February 4, 2026 14:32
@danielroe danielroe added this pull request to the merge queue Feb 4, 2026
Merged via the queue into npmx-dev:main with commit c7ba252 Feb 4, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix: Stars are not showing in OG preview

2 participants