Skip to content

feat: new og images#2292

Open
harlan-zw wants to merge 57 commits intonpmx-dev:mainfrom
harlan-zw:feat/og-image-v7
Open

feat: new og images#2292
harlan-zw wants to merge 57 commits intonpmx-dev:mainfrom
harlan-zw:feat/og-image-v7

Conversation

@harlan-zw
Copy link
Copy Markdown
Contributor

@harlan-zw harlan-zw commented Mar 27, 2026

🔗 Linked issue

#1654

🧭 Context

The previous PR was rolled back due to some Takumi stability issues. These are now solved afaik and OG Image got a v6 stable release so it's a good time to reintroduce it. (Takumi is v1 beta now so also likely stable very soon)

📚 Description

Same as before, I've resynced the UI to match recent branding changes.

sample - check PR files for more

https://npmx.dev/
og-image-home

https://npmx.dev/accessibility
og-image-accessibility

https://npmx.dev/blog/alpha-release
og-image-blog-alpha-release

https://npmx.dev/package/@nuxt/kit
og-image-package--nuxt-kit

https://npmx.dev/package-docs/ufo/v/1.6.3
og-image-package-docs-ufo-v-1-6-3

Supersedes #2122 (rebased on latest main with CI fixes).

Bump nuxt-og-image to 6.2.6 and takumi to 1.0.0-beta.20. Disable
prerender failOnError in test builds to match main branch behavior
(OAuth plugin crashes without valid clientUri in CI).
Revert changes unrelated to OG image migration:
- CI NODE_OPTIONS memory bump
- site.description casing change
- nitro prerender failOnError workaround
- favicon.svg and logo-icon.svg branding changes
- a11y test cosmetic string template refactoring
…ge security

- Fix blog post avatar stacking (vertical → horizontal) by adding flex-row to container
- Remove htmlValidator.ignore regexes that broke structuredClone in @nuxt/test-utils
- Remove long-title rule override (not needed without ignore pattern)
- Add ogImage.security.maxQueryParamSize
- Update blog post snapshot
nuxt-og-image v6 causes runtimeConfig to contain values that
structuredClone rejects during vite-plus-test project resolution.
Replace structuredClone with JSON roundtrip in @nuxt/test-utils
config.mjs as a workaround.
The structuredClone crash was caused by objects created in Vite's
module runner (separate V8 context) being stored in runtimeConfig.
Fixed upstream in nuxt-site-config by JSON-serializing the runtimeConfig
contribution before assignment.
Vite's module runner creates objects in a separate V8 context that
structuredClone rejects. Replace with JSON roundtrip in test-utils
config resolution until upstream nuxt-site-config fix is published.
@danielroe danielroe requested a review from alexdln March 27, 2026 20:15
test: {
environmentOptions: {
- nuxtRuntimeConfig: applyEnv(structuredClone(options.nuxt.options.runtimeConfig), {
+ nuxtRuntimeConfig: applyEnv(JSON.parse(JSON.stringify(options.nuxt.options.runtimeConfig)), {
Copy link
Copy Markdown
Contributor Author

@harlan-zw harlan-zw Mar 28, 2026

Choose a reason for hiding this comment

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

@danielroe I tried debugging what could have been causing this issue in nuxt og image (or nuxt site config) but as far as I could tell, neither of them had non-serializable data in the runtime config so it was very strange.

Do you think this fix upstream in @nuxt/test-utils makes sense? Happy to send a PR for it if so. We may consider a structuredClone with this json parse/stringify as fallback if it fails with a warning instead.

Context: https://github.com/npmx-dev/npmx.dev/actions/runs/23634594311/job/68841078028?pr=2292

Restore i18n locale files, schema, and logo-icon.svg to match main.
Re-use og_title i18n key in package-docs ogTitle meta instead of removing it.
Comment on lines -296 to -304
fonts: [
{ name: 'Geist', weight: 400, path: '/fonts/Geist-Regular.ttf' },
{ name: 'Geist', weight: 500, path: '/fonts/Geist-Medium.ttf' },
{ name: 'Geist', weight: 600, path: '/fonts/Geist-SemiBold.ttf' },
{ name: 'Geist', weight: 700, path: '/fonts/Geist-Bold.ttf' },
{ name: 'Geist Mono', weight: 400, path: '/fonts/GeistMono-Regular.ttf' },
{ name: 'Geist Mono', weight: 500, path: '/fonts/GeistMono-Medium.ttf' },
{ name: 'Geist Mono', weight: 700, path: '/fonts/GeistMono-Bold.ttf' },
],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not needed anymore?

Comment on lines +292 to +294
security: {
maxQueryParamSize: 2048,
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

oh?

href: '/opensearch.xml',
},
],
meta: [{ name: 'twitter:card', content: 'summary_large_image' }],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not needed anymore?

* - Static pages (Page.takumi)
* - Packages (Package.takumi with download-chart, code-tree, function-tree variants)
*/
const testCases = [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could we use screaming snake case

Comment on lines +25 to +36
// og-image uses hardcoded classes we don't want bundled into main app
content: {
pipeline: {
exclude: [
// Preserve the UnoCSS defaults that @unocss/nuxt normally sets
/\.(css|postcss|sass|scss|less|stylus|styl)($|\?)/,
/\?macro=true/,
// Exclude OG image templates from the pipeline
'**/OgImage/*.takumi.vue',
],
},
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

could you explain how this works?

Comment on lines +372 to +375
<span
v-else-if="row.kind === 'symbol'"
class="w-5 h-5 shrink-0 text-fg-muted force-mr-1.5 i-lucide:code"
/>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

does this branch need an else?

class="pt-3 lg:text-4xl text-3xl opacity-70 font-mono tracking-tight leading-none"
:style="{ textOverflow: 'ellipsis', lineClamp: 1 }"
>
v{{ version }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

does this display the resolved version, or could it display the range? not sure which we want here 🤔

{
title: () => `${$t('about.title')}`,
description: 'a fast, modern browser for the npm registry',
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

why is this partially translated?

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.

3 participants