Conversation
There was a problem hiding this comment.
Pull request overview
Adds build-time, per-route Open Graph image generation for the Nuxt site (including session pages with agenda-specific cards), replacing the previous site-wide static og:image/twitter:image approach and ensuring images are produced during nuxt generate.
Changes:
- Integrates
nuxt-og-image(Takumi renderer) and adds OG templates (DefaultandSession) plus per-pagedefineOgImage(...)usage. - Extends prerendering to include bilingual session detail routes (
/session/:idand/en/session/:id) and relaxes Nitro prerender error handling. - Adds build/runtime dependencies and build script changes to support large-scale OG image generation (fonts, renderer deps, increased Node heap).
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Locks newly added OG-image, renderer, font, and build tooling dependencies. |
| package.json | Adds nuxt-og-image + renderer deps; increases build heap via cross-env in build script. |
| nuxt.config.ts | Registers modules, configures fonts for OG rendering, disables Nitro prerender fail-on-error, removes global static og/twitter image meta. |
| app/app.vue | Adds site-wide fallback defineOgImage('Default'). |
| app/pages/session.vue | Prerenders both zh (default) and /en session detail routes. |
| app/pages/session/[id].vue | Defines per-session OG images using the Session template with fetched session metadata. |
| app/pages/[...slug].vue | Defines per-content-page OG images using the Default template populated from content metadata. |
| app/components/OgImage/theme.ts | Introduces shared inline-style constants for OG image templates. |
| app/components/OgImage/Default.takumi.vue | Implements default OG card template layout for non-session pages. |
| app/components/OgImage/Session.takumi.vue | Implements session OG card template layout (title/speakers/room/time). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Dokploy Preview Deployment
|
Generate a branded OG image per route at build time with nuxt-og-image (Takumi renderer). Sessions render a card with title, speakers, room, and time; every other page uses a Default template. Session images are prerendered for both zh and en. - Add @nuxt/fonts with Noto Sans SC/TC/JP/KR (weight 400) for CJK glyph coverage. SC is primary: Takumi selects one font per script run rather than per glyph, and SC has the widest Han coverage (Simplified and Traditional, each in its correct form). - Add @iconify-json/noto for full emoji coverage (the module bundles only ~100 by default). - Raise the build heap to 8 GB via cross-env for 4 CJK fonts + ~670 images. - Set nitro.prerender.failOnError: false to tolerate transient Pretalx 500s. - Drop the static site-wide og:image/twitter:image meta; the module now injects both per page. - Share the colors, font-family chain, logo path, and base card layout across both templates via a small app/components/OgImage/theme.ts module.
Unbounded parallel prerendering spiked to ~12.6GB RSS during the session OG card render burst, OOM-killing the 16GB CI runner non-deterministically. Capping concurrency to 4 bounds the peak to ~10.2GB (independent of session count) while keeping build time flat.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4003c3cb20
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| publicDir: process.env.NUXT_OUTPUT_DIR || '.output/public', | ||
| }, | ||
| prerender: { | ||
| failOnError: false, |
There was a problem hiding this comment.
Keep prerender failures blocking deploys
This site is uploaded as a static GitHub Pages artifact, so there is no Nitro runtime to recover if a page or one of the new generated /_og/s/... image routes fails during pnpm build. With failOnError: false, the deploy workflow can still publish .output/public after an OG render/API prerender error, leaving missing social images or routes in production instead of failing the build; prefer keeping this strict and handling flaky Pretalx calls with retries or targeted fallbacks.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
如果不使用 failOnError: true 的話,一個 Pretalx 錯誤或是一個 OG Image 失敗渲染就會讓整個網站無法部署。現在失敗的 OG Image 會自動回退到預設圖片。大家認為應該要優先部屬穩定還是優先內容正確?
變更內容
Closes #127.
在建置階段為每個路由產生專屬的 Open Graph 預覽圖。
nuxt-og-image(Takumi renderer)在nuxt generate時輸出 PNG。字型與 CJK
@nuxt/fonts載入 Noto Sans SC / TC / JP / KR (皆 weight 400)。@iconify-json/noto完整支援 emoji(模組預設只內建約 100 個)。建置
cross-env將 heap 提高到 8 GB (4 套 CJK 字型 + 約 670 張圖片)。nitro.prerender.failOnError: false容忍 Pretalx API 偶發 500。og:image/twitter:image,改由模組逐頁注入。建置過程會出現
Could not resolve font "Segoe UI" for OG images.等找不到字體的錯誤,這是因為 UnoCSSpreset-wind4包含這些字體,但nuxt-og-image的isSystemFont()誤以為他們是外部字體而不是系統 fallback。這類警告可以安全的忽略。樣式為何止於 inline style + 常數 (無法再進一步重構)
兩個樣板共用的色彩、字型、Logo path 與基礎版面已抽到
app/components/OgImage/theme.ts,以 inline:style套用。Takumi renderer 的限制讓 CSS class 或共用 CSS 檔無法運作。實測結果::style+theme.ts常數bg-primary-800)<style src="./og.css"><script setup>中import './og.css'原因:
unocss-preset-theme以 CSS 變數(var(--primary-800))定義主題色,但靜態 renderer 取不到變數定義而卡住逾時;且 Takumi 只讀 inline:style、inline<style>文字與編譯後的 utility class,從不讀取外部或 JS 匯入的 CSS 檔。因此唯一同時「能共用又能正確渲染」的方式就是 JS/TS 常數。驗證
一些範例: