Files
ComfyUI_frontend/apps/website/scripts
imick-io 39157f2375 Feat/models page (#12429)
## Summary

Add a new `/models` landing page (EN + zh-CN) for the marketing site,
plus supporting tweaks: a generator-side mechanism for old→new
model-slug 301 redirects, spacing/CTA polish on shared sections, and a
per-item layout option on GalleryCard.

## Changes

- **What**:
- New `/models` and `/zh-CN/models` pages composed of a hero (autoplay
video, modelName + i18n CTA), a creations gallery, and the shared
`AIModelsSection`.
- New `ModelsHeroSection.vue` and `ModelCreationsSection.vue`
components; localised strings under `models.list.*` / `models.hero.*` in
`translations.ts`.
- Reused `AIModelsSection` on the models page (replaces the duplicated
showcase markup that previously lived under `models/`) so the same
component now powers both the cloud product page and the models page.
- `generate-models.ts`: renamed the `grok` provider to **Grok Imagine**
(`grok-imagine` slug) and added a `LEGACY_SLUG_REDIRECTS` constant that
emits stub entries so the existing `canonicalSlug` mechanism in
`[slug].astro` issues a 301 from old slugs (`grok-image` →
`grok-imagine`).
- `model-metadata.ts`: renamed the metadata key from `grok-image` to
`grok-imagine` (hub slug unchanged).
- `GalleryCard.vue`: added per-item `objectFit` / `objectPosition`
overrides so individual gallery entries can opt out of the default
`cover` crop.
- `ModelsHeroSection.vue`: dropped the empty-string default on
`videoAriaLabel` and omit `aria-label` (with `aria-hidden="true"`) when
no label is provided — addresses the CodeRabbit accessibility note.
- Minor vertical-spacing tightening on `ModelCreationsSection` and the
shared `AIModelsSection`.
- **Breaking**: None. Old `/p/supported-models/grok-image` URLs 301 to
the new slug.
- **Dependencies**: None.

## Review Focus

- The `LEGACY_SLUG_REDIRECTS` constant in
`apps/website/scripts/generate-models.ts` is the new source of truth for
renamed slugs — future slug renames should follow the same pattern so
the redirect survives regeneration of `generated-models.json`.
- The shared `AIModelsSection` is now used in two places; confirm the
spacing tweak (`py-24 → py-16`, `mt-24 → mt-16 lg:mt-24`) still looks
correct on the cloud product page.
- `generated-models.json` is fully regenerated by `pnpm generate:models`
— diff size is large but mechanical.

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-06-09 20:14:03 +00:00
..
2026-06-09 20:14:03 +00:00

Website Scripts

refresh-ashby-snapshot.ts

Pulls the latest job postings from Ashby and writes src/data/ashby-roles.snapshot.json. Invoked by the Release: Website GitHub Actions workflow; also runnable locally via pnpm --filter @comfyorg/website ashby:refresh-snapshot.

process-videos.sh

Generates multi-resolution VP9/WebM + H.264/MP4 variants and a poster frame for marketing videos using ffmpeg. Run locally before uploading the outputs to media.comfy.org; this is not wired into CI.

apps/website/scripts/process-videos.sh \
  ./video-sources \
  ./dist/videos \
  "640 960 1280 1920"

Output

For each source video at ./video-sources/foo.mp4, you get:

foo-640.webm   foo-640.mp4
foo-960.webm   foo-960.mp4
foo-1280.webm  foo-1280.mp4
foo-1920.webm  foo-1920.mp4
foo-poster.jpg

The naming convention is enforced by buildVideoSources() in src/utils/video.ts, which the <SiteVideo> Vue component uses to emit <source> URLs.

Pairing with <SiteVideo>

Once the assets are uploaded, render them with:

<SiteVideo
  name="foo"
  base-url="https://media.comfy.org/website/marketing"
  :width="1280"
  :formats="['webm', 'mp4']"
  poster="https://media.comfy.org/website/marketing/foo-poster.jpg"
  autoplay
  loop
/>

<SiteVideo> vs <VideoPlayer>

  • SiteVideo — lightweight multi-source <video> for decorative or autoplay marketing clips. No custom controls, no captions UI.
  • VideoPlayer — full-featured player with custom scrubber, mute, fullscreen, and caption toggles. Use this for content with subtitles or user-driven playback.

If you need both responsive sources and the rich VideoPlayer chrome, the two are not yet combined; either pick one or extend VideoPlayer to accept a source list.

Encoder choices

  • VP9/WebM at CRF 32 — preferred by Chrome and Firefox; smaller files.
  • H.264/MP4 at CRF 23, High profile, +faststart — universal fallback, required for Safari iOS.
  • Poster JPG at q4 — extracted from t=1s when the clip is long enough, otherwise t=0; scaled to 1280w. Use this as the poster attribute so the video shows something while loading.

Why a single resolution per video

<source media="..."> inside <video> is unreliable across browsers (Safari ignores it). The simplest correct strategy is to ship one well-sized resolution and let CSS scale it down on smaller viewports. The script generates multiple widths so you can pick a different one per page (e.g. 1280w for a hero, 640w for a thumbnail), or wire up JavaScript-based selection later if metrics demand it.