Skip to content

Feat/comfyhub redesign#950

Open
MaanilVerma wants to merge 83 commits into
Comfy-Org:mainfrom
MaanilVerma:feat/comfyhub-redesign
Open

Feat/comfyhub redesign#950
MaanilVerma wants to merge 83 commits into
Comfy-Org:mainfrom
MaanilVerma:feat/comfyhub-redesign

Conversation

@MaanilVerma

@MaanilVerma MaanilVerma commented Jun 18, 2026

Copy link
Copy Markdown

Summary

End-to-end visual redesign of the ComfyHub site to the new Figma direction — a real marketing navbar, a much stronger search, a single browse toolbar replacing the sidebar/drawer filters, a featured carousel, and reworked cards and detail page. SEO and i18n are preserved across all 11 locales; the whole hub now reads as one consistent unit instead of a basic filtered grid.

Figma Link

Changes

What

  • Marketing navbar, ported from the current comfy.org nav so it matches upstream exactly: a desktop mega-menu (multi-column dropdowns with a featured image card per section, "NEW" badges, animated CTA pill) and a mobile slide-in sheet with drill-down sub-menus and a back button. Keeps the hub-only "Top creators" shortcut. Built on reka-ui navigation-menu/sheet primitives.
  • Search that stops silently failing. It used to intermittently return nothing and miss obvious matches. Index and query now share one tokenizer config so they can't drift; a failed first index fetch no longer poisons the cache (it retries and shows a clean empty state); the tokenizer splits hyphen and underscore terms so flux_image-to-video is found by "flux"/"image"/"video"; common abbreviations expand at query time ("txt2img" → text to image, "i2v" → image to video, "cn" → controlnet); fuzziness scales with term length so short queries stay tight and long typos still match; multi-word queries match all terms first and only fall back to any-term when that's empty. Real usage counts now feed ranking, so popular workflows surface.
  • Browse toolbar replaces the sidebar and the mobile filter drawer with one component (tabs + sort + facet filters), so filtering is the same on every screen size.
  • Featured carousel — a usage-ranked hero on the landing page.
  • Workflow card — 4:3 thumbnail with the title and provider logo overlaid on a scrim, a creator line, a circular CTA, and a tag row that scrolls with chevrons that only appear when the tags overflow. Author-name clipping is fixed, cards are a bit wider, and "Load more" matches Figma.
  • Detail page — a breadcrumb trail in place of the back button, an expandable description whose full text is always in the SSR DOM (so crawlers see it while it's collapsed), an accordion FAQ, and a "View all workflows" related grid.
  • SEO — FAQ and breadcrumb JSON-LD are escaped before injection (no script-breakout) and applied consistently across the workflow/category/tag/model pages; breadcrumb labels are localized and mirror the visible trail; collection pages carry an ItemList count.
  • Search a11y — wrapped in <form role="search">, Enter activates the highlighted (or first) result with no page reload, and a live region announces the result count.

Breaking

None. Protected infra is restyled around, never removed — SEOHead/HreflangTags, canonical {name}-{shareId} links, getCloudCtaUrl()/UTM params, and <Analytics /> are all intact, and the new JSON-LD matches what's rendered.

Review Focus

  • Search is the riskiest area — see the AND→OR fallback and the index-fetch recovery; both change behavior users will notice. The shared tokenizer config is the one file to read for why index and query stay in sync.
  • Navbar is a faithful port, not a fresh design — it intentionally mirrors the upstream comfy.org nav (mega-menu structure, mobile sheet, featured cards) so it stays in sync; the only deliberate addition is the hub's "Top creators" section in the mobile sheet.
  • Filter migration — the browse toolbar fully replaces the removed sidebar and mobile filter drawer; worth confirming facet-count and active-filter parity.
  • Island architecture held throughout — cross-island state via shared composables, no custom-event bridges, islands get plain data + locale and don't import i18n.

Testing

Search is the part most likely to regress silently, so it has the most coverage; the rest is verified by the type/lint gate plus manual passes against the Figma.

  • tests/unit/search-config.test.ts — tokenizer sub-parts, synonym expansion, length-aware fuzzy thresholds, and the AND→OR fallback (including the title-over-description ranking).
  • tests/unit/use-facets.test.ts — facet derivation and dedup from the template set.
  • tests/unit/featured.test.ts / tests/unit/provider-logos.test.ts / tests/unit/routes.test.ts — usage-ranked selection, word-boundary logo matching, and canonical slug composition.
  • Gate: pnpm run check (0 errors), pnpm test (168 passing), pnpm run lint, pnpm run build all green.
  • Manual (pnpm run dev): search txt2img / i2v / cn and flux; block the first search-index.json request once and search again to confirm it recovers; open a desktop dropdown and the mobile sheet drill-down; scroll a card's tag row via the chevrons; spot-check a /zh/… and the RTL /ar/… page for i18n + dir.

Screen Recording

Screen.Recording.2026-06-23.at.8.38.49.PM.mov

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR overhauls the hub site: it adds an Embla-powered featured carousel, rebuilds the site navigation (desktop dropdowns, mobile sheet drawer, GitHub star badge), introduces a BrowseToolbar with facet filter popover and sort cycling, refactors the template detail page with breadcrumbs/FAQ accordion/expandable text, centralizes MiniSearch configuration, and wires localized toolbar labels and structured-data helpers across all workflow route pages.

Changes

Hub Site Redesign: Carousel, Navigation, Browse Toolbar & Detail Page

Layer / File(s) Summary
Shared utilities, composables, design tokens, and i18n
site/src/lib/search-config.ts, site/src/lib/routes.ts, site/src/lib/provider-logos.ts, site/src/lib/featured.ts, site/src/lib/hub-api.ts, site/src/lib/github.ts, site/src/lib/structured-data.ts, site/src/lib/toolbar.ts, site/src/lib/social-links.ts, site/src/config/nav-routes.ts, site/src/composables/scrollLock.ts, site/src/composables/useHubStore.ts, site/src/composables/useFacets.ts, site/src/i18n/ui.ts, site/src/styles/..., site/src/components/ui/button/index.ts, site/src/components/ui/badge/..., site/src/components/ui/button-pill/..., site/src/components/ui/icons/...
Introduces all foundational utilities, composables, i18n keys (11 locales), design tokens, and extended button/badge/ButtonPill UI primitives that every higher layer depends on — the roots of the dependency tree!
Search configuration consolidation
site/src/lib/search-config.ts, site/src/lib/search.ts, site/scripts/lib/search/build-index.ts
Extracts shared MiniSearch config (field lists, tokenizer, query expansion, searchWithFallback) into search-config.ts; refactors the client and build-index script to consume it; adds usage data and fetch timeouts.
Site navigation system
site/src/config/main-navigation.ts, site/src/components/ui/navigation-menu/..., site/src/components/ui/sheet/..., site/src/components/hub/nav/..., site/src/composables/useCurrentPath.ts, site/src/components/hub/HubNavbar.astro
Builds a full responsive navigation system: navigation model types, NavigationMenu and Sheet UI primitives, NavColumn/NavFeaturedCard/NavLinkContent, NodeBadge/GitHubStarBadge, HeaderMainDesktop/HeaderMainMobile with scroll-lock, HeaderMain orchestrator, and HubNavbar refactored to a two-row header with GitHub stars.
Featured carousel and HubHero
site/package.json, site/src/components/hub/FeaturedCarousel.vue, site/src/components/hub/HubHero.astro
Adds Embla carousel dependencies and FeaturedCarousel (autoplay, RTL, video fallback, slide view-model) along with a HubHero that shows a localized template count — quite a carousel of changes! 🎠
Browse toolbar, WorkflowGrid refactor, and HubBrowse filter pipeline
site/src/components/hub/BrowseToolbar.vue, site/src/components/hub/TagScroller.vue, site/src/components/hub/WorkflowGrid.vue, site/src/components/hub/HubBrowse.vue
Adds BrowseToolbar with tab/filter-popover/sort controls wired to useHubStore/useFacets; adds TagScroller; refactors WorkflowGrid to use the shared toolbar and store-driven tab/sort/pagination; simplifies HubBrowse to badge-driven filteredTemplates.
HubWorkflowCard restyling and SearchPopover improvements
site/src/components/hub/HubWorkflowCard.vue, site/src/components/hub/SearchPopover.vue, site/src/components/ThumbnailDisplay.astro
Refactors HubWorkflowCard to shared path/logo helpers and a landscape layout with scrim overlay; updates SearchPopover to thumbnailPath, adds <form role="search"> submission and a screen-reader live region; refactors ThumbnailDisplay to a shared mediaClass.
Template detail page: Breadcrumbs, ExpandableText, FaqAccordion
site/src/components/template-detail/Breadcrumbs.astro, site/src/components/template-detail/ExpandableText.vue, site/src/components/template-detail/FaqAccordion.vue, site/src/components/template-detail/TemplateDetailPage.astro
Adds Breadcrumbs (matching JSON-LD), ExpandableText (animated max-height with ResizeObserver and prefers-reduced-motion), and FaqAccordion (reka-ui); refactors TemplateDetailPage to fixed media-frame layout with optional faqItems.
Workflow route pages: toolbarLabels, carousel, related workflows
site/src/pages/workflows/..., site/src/pages/[locale]/workflows/...
Wires all workflow route pages to pass buildToolbarLabels/buildFacetsConfig into grids, adds FeaturedCarousel and HubHero count to index pages, adds related workflows to detail pages, and switches all breadcrumb/FAQ structured data to shared helpers with serializeJsonLdForScript.
Unit tests and Vitest config
site/vitest.config.ts, site/tests/unit/featured.test.ts, site/tests/unit/provider-logos.test.ts, site/tests/unit/routes.test.ts, site/tests/unit/search-config.test.ts, site/tests/unit/use-facets.test.ts
Adds @ alias to Vitest config and unit/integration tests for getFeatured, featuredPreloadImage, getLogoPath/providerName, tagPath/creatorPath, tokenize/expandQuery/searchOptions/searchWithFallback, and useFacets reactivity and active-state helpers.

Sequence Diagram(s)

sequenceDiagram
  participant Page as workflows/index.astro
  participant Featured as getFeatured / featuredPreloadImage
  participant Carousel as FeaturedCarousel (client:load)
  participant Browse as HubBrowse (client:load)
  participant Toolbar as BrowseToolbar
  participant Store as useHubStore
  participant Grid as WorkflowGrid
  participant Facets as useFacets

  Page->>Featured: loadSerializedTemplates() → getFeatured(templates)
  Featured-->>Page: featured[], featuredLcpImage
  Page->>Carousel: templates=featured, labels, locale
  Carousel->>Carousel: initEmbla + autoplay plugin
  Page->>Browse: templates, facetsConfig, toolbarLabels
  Browse->>Grid: filteredTemplates, facetTemplates, facetsConfig, toolbarLabels
  Grid->>Toolbar: facetSource, facetsConfig, toolbarLabels
  Toolbar->>Store: setTab / cycleSort / toggleBadge
  Toolbar->>Facets: facetsByType, isBadgeActive, activeCountForType
  Store-->>Grid: activeTab, sortBy → sorted/filtered display
Loading
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@socket-security

socket-security Bot commented Jun 18, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm embla-carousel is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: site/pnpm-lock.yamlnpm/embla-carousel-vue@8.6.0npm/embla-carousel-autoplay@8.6.0npm/embla-carousel@8.6.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/embla-carousel@8.6.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@MaanilVerma MaanilVerma marked this pull request as ready for review June 18, 2026 15:10

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
site/src/components/hub/HubBrowse.vue (1)

63-67: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle dual mode badges as a union (not first-match wins).

At Line 65 and Line 66, when both app and nodeGraph are selected, the first if returns early and filters to apps only. In rhyme-time: two badges in, one badge out. Treat both-selected as “show all modes.”

🔧 Suggested fix
   if (modeBadges.length > 0) {
+    const includeApps = modeBadges.includes('app');
+    const includeNodeGraphs = modeBadges.includes('nodeGraph');
     result = result.filter((t) => {
-      if (modeBadges.includes('app')) return t.isApp;
-      if (modeBadges.includes('nodeGraph')) return !t.isApp;
+      if (includeApps && includeNodeGraphs) return true;
+      if (includeApps) return t.isApp;
+      if (includeNodeGraphs) return !t.isApp;
       return true;
     });
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/src/components/hub/HubBrowse.vue` around lines 63 - 67, The filter logic
in the modeBadges length check uses early return statements that cause only the
first matching condition to apply, so when both 'app' and 'nodeGraph' badges are
selected, only one mode is displayed. Modify the conditional logic to treat
multiple selected badges as a union by combining the conditions with OR logic
instead of separate if statements - return true if (modeBadges includes 'app'
AND t.isApp) OR (modeBadges includes 'nodeGraph' AND !t.isApp), ensuring that
when both badges are selected, items matching either criterion are included in
the results.
site/src/components/hub/SearchPopover.vue (1)

549-561: ⚠️ Potential issue | 🟠 Major

Verify thumbnail normalization cannot double-prefix local paths.

Lines 549-550 and line 560 always route thumbnails through thumbnailPath(file), but the function only guards against full HTTP/HTTPS URLs. If upstream data contains an already-prefixed path like /workflows/thumbnails/... or workflows/thumbnails/..., this produces broken doubled paths.

The same vulnerability exists in ThumbnailDisplay.astro (line 44) with an identical thumbUrl() helper.

Fix: Expand the URL check in both thumbnailPath() and thumbUrl() to reject paths that already start with /workflows/thumbnails/ or contain that segment:

export const thumbnailPath = (asset: string) =>
  asset.startsWith('http://') || asset.startsWith('https://') || asset.startsWith('/workflows/thumbnails/')
    ? asset
    : `/workflows/thumbnails/${asset}`;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/src/components/hub/SearchPopover.vue` around lines 549 - 561, The
`thumbnailPath()` function in SearchPopover.vue (used in lines 549-550 and 560)
and the identical `thumbUrl()` helper in ThumbnailDisplay.astro (line 44) only
guard against full HTTP/HTTPS URLs but fail to prevent double-prefixing when
paths already contain the `/workflows/thumbnails/` segment. Expand the URL check
in both functions to also reject paths that already start with
`/workflows/thumbnails/` by adding an additional condition to the existing
startsWith checks, so that upstream data containing already-prefixed paths will
be returned as-is instead of being double-prefixed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@site/src/components/hub/nav/MobileMenu.vue`:
- Around line 76-89: The watcher for the `open` property has a race condition
where if `open` changes before `await nextTick()` resolves, the stale branch can
still execute the focus and event listener attachment. Guard against stale
callbacks by adding a check after the `await nextTick()` in the isOpen branch to
verify that `isOpen` is still true before proceeding with the focus() call and
addEventListener('keydown', trapFocus) call. This ensures that if the menu was
closed while waiting for the next tick, the stale focus and event handling code
won't execute.
- Line 44: The template ref variable menuRef is initialized with ref<HTMLElement
| undefined>() but should follow the repository's convention of using
ref<HTMLElement | null>(null) for DOM element refs. Update the menuRef
declaration to change the type from HTMLElement | undefined to HTMLElement |
null, and explicitly initialize it with null as the default value to maintain
consistency with other template refs in the codebase like SearchPopover.vue and
HubWorkflowCard.vue.

In `@site/src/components/hub/nav/NavDesktopLink.vue`:
- Around line 48-50: The active navigation state detection in NavDesktopLink.vue
is comparing currentPath (a pathname) directly against href values (which may be
absolute URLs), causing the comparison to fail. Extract the pathname from the
href values before comparing them with currentPath to ensure the string equality
check works correctly. Apply this normalization to all three locations where
this comparison occurs: the ternary operator around line 48-50, the check around
line 66-68, and the condition around line 79-84.

In `@site/src/components/hub/nav/SiteNav.vue`:
- Around line 114-117: The closeMobileMenu function is forcing focus on the
hamburger element every time it is called, and since onNavigate calls
closeMobileMenu on every astro:after-swap route transition, this steals focus
from the user during normal navigation. Remove the hamburgerRef.value?.focus()
call from the closeMobileMenu function to prevent unwanted focus changes during
route transitions. If hamburger focus is needed for keyboard navigation
scenarios, consider conditionally focusing only when the menu is closed via
explicit user interaction rather than during automatic transitions.
- Line 112: The hamburgerRef variable declaration uses HTMLButtonElement |
undefined as the type without initializing the ref, which does not align with
the project convention. Change the hamburgerRef declaration to use
HTMLButtonElement | null as the type and explicitly initialize it with null
value, matching the pattern used in other components like HubWorkflowCard.vue
and SearchPopover.vue for consistency across the codebase.

In `@site/src/composables/useFacets.ts`:
- Around line 52-55: The counting logic in the nested loop where field(t) is
iterated currently counts duplicate values multiple times if they appear in the
same template, causing incorrect rankings. Deduplicate the values returned by
field(t) before counting by converting them to a Set first, then iterate through
the deduplicated Set to increment the counts in the counts map, ensuring each
unique value is counted only once per template regardless of how many times it
appears in that template.

In `@site/src/lib/github.ts`:
- Around line 21-23: The `inflight` cache stores request entries but never
removes them, causing transient failures or null results to be cached
permanently, preventing future retries. After setting the request in the
`inflight` map using `inflight.set(key, request)`, attach a handler to the
request promise that removes the entry from the `inflight` map when the request
settles (using `.finally()` or `.then()` combined with `.catch()`), ensuring
that future calls can retry the request instead of returning the cached failed
result.

In `@site/src/lib/provider-logos.ts`:
- Around line 42-45: The substring matching logic in the loop iterating through
MODEL_TO_LOGO entries is too greedy because it uses includes() to check if the
lowercase input contains the lowercase key, which matches partial substrings
unintentionally (e.g., "Swan AI" matches "Wan"). Replace this loose substring
matching with a more precise approach that checks for exact word boundaries or
exact matches, such as by splitting the input name into words and checking if
any word exactly matches the key, rather than using a simple includes() check.

In `@site/src/lib/structured-data.ts`:
- Around line 23-27: The faqItems mapping in the mainEntity section includes
unsanitized user-provided strings (item.question and item.answer) that flow into
JSON-LD script sinks. These strings could contain `</script>` sequences that
break out of the script tag context and enable markup/script injection. Create
or use a safe serializer function that escapes these potentially dangerous
characters in item.question and item.answer before they are included in the
acceptedAnswer object's text field and the name field to prevent script-breakout
attacks.

In `@site/src/pages/`[locale]/workflows/[slug].astro:
- Around line 226-227: The detailRelated variable assignment at line 226-227
lacks error handling for the listRelatedWorkflows function call. Wrap the
listRelatedWorkflows invocation in a try-catch block to gracefully handle Hub
API failures, returning an empty array in the catch block instead of allowing
the error to propagate and crash the entire detail page. This ensures the detail
page remains functional even when fetching related workflows fails, since this
is a non-critical section.
- Around line 265-267: The JSON-LD payload in the script block with `detailFaq`
and `set:html` is vulnerable to script-breakout XSS because the stringified JSON
is injected directly without escaping. Fix this by escaping the JSON string
before passing it to `set:html`, specifically escaping the `<` character (or
`</` sequence) in the JSON.stringify(detailFaq) result to prevent content from
breaking out of the JSON-LD script block. Replace the direct JSON.stringify call
with a safe serialization that escapes angle brackets or use a JSON
serialization method that produces XSS-safe output.

In `@site/src/styles/global.css`:
- Around line 194-197: The multi-line CSS comment starting with "Compact variant
for small controls" is missing required whitespace before the closing comment
delimiter `*/`. To fix this, add a space before `*/` at the end of the comment
block where it currently reads `breakpoints.*/` so it becomes `breakpoints. */`.
This will satisfy the stylelint whitespace requirement for comment closing
delimiters.

In `@site/tests/unit/provider-logos.test.ts`:
- Around line 20-22: Add regression test cases to the getLogoPath test suite to
prevent false-positive logo matches from short substring collisions. After the
existing test that checks for unknown providers using 'Totally Unknown Co', add
additional test cases that verify inputs like 'Swan AI' and 'Conflux Labs'
return null to ensure these provider names don't accidentally match against
shorter keys like 'Wan' or 'Flux' through substring matching.

In `@site/tests/unit/use-facets.test.ts`:
- Around line 34-40: The test for the useFacets function with the test case
"ranks tags by template count and counts each template once per tag" does not
actually verify the "once per template" behavior because the makeTemplates()
fixture never includes duplicate tags within the same template. Modify the test
fixture passed to useFacets (either by updating makeTemplates() or creating a
new specialized fixture) to include at least one template that contains
duplicate occurrences of the same tag, then add assertions to verify that the
tag count still reflects only one count per template even when duplicates exist
within that template.

---

Outside diff comments:
In `@site/src/components/hub/HubBrowse.vue`:
- Around line 63-67: The filter logic in the modeBadges length check uses early
return statements that cause only the first matching condition to apply, so when
both 'app' and 'nodeGraph' badges are selected, only one mode is displayed.
Modify the conditional logic to treat multiple selected badges as a union by
combining the conditions with OR logic instead of separate if statements -
return true if (modeBadges includes 'app' AND t.isApp) OR (modeBadges includes
'nodeGraph' AND !t.isApp), ensuring that when both badges are selected, items
matching either criterion are included in the results.

In `@site/src/components/hub/SearchPopover.vue`:
- Around line 549-561: The `thumbnailPath()` function in SearchPopover.vue (used
in lines 549-550 and 560) and the identical `thumbUrl()` helper in
ThumbnailDisplay.astro (line 44) only guard against full HTTP/HTTPS URLs but
fail to prevent double-prefixing when paths already contain the
`/workflows/thumbnails/` segment. Expand the URL check in both functions to also
reject paths that already start with `/workflows/thumbnails/` by adding an
additional condition to the existing startsWith checks, so that upstream data
containing already-prefixed paths will be returned as-is instead of being
double-prefixed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2d07f80f-17a8-47b8-a38d-816d4f639fdc

📥 Commits

Reviewing files that changed from the base of the PR and between d7d8394 and 8be464e.

⛔ Files ignored due to path filters (11)
  • site/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • site/public/brand/comfy-hub-logo.svg is excluded by !**/*.svg
  • site/public/icons/arrow-right.svg is excluded by !**/*.svg
  • site/public/icons/arrow-up-right.svg is excluded by !**/*.svg
  • site/public/icons/breadthumb.svg is excluded by !**/*.svg
  • site/public/icons/close.svg is excluded by !**/*.svg
  • site/public/icons/logomark.svg is excluded by !**/*.svg
  • site/public/icons/node-left.svg is excluded by !**/*.svg
  • site/public/icons/node-right.svg is excluded by !**/*.svg
  • site/public/icons/node-union.svg is excluded by !**/*.svg
  • site/public/icons/social/github.svg is excluded by !**/*.svg
📒 Files selected for processing (55)
  • site/package.json
  • site/scripts/lib/search/build-index.ts
  • site/src/components/ThumbnailDisplay.astro
  • site/src/components/hub/BrowseToolbar.vue
  • site/src/components/hub/FeaturedCarousel.vue
  • site/src/components/hub/HubBrowse.vue
  • site/src/components/hub/HubHero.astro
  • site/src/components/hub/HubNavbar.astro
  • site/src/components/hub/HubWorkflowCard.vue
  • site/src/components/hub/MobileFilterDrawer.vue
  • site/src/components/hub/SearchPopover.vue
  • site/src/components/hub/WorkflowGrid.vue
  • site/src/components/hub/nav/GitHubStarBadge.vue
  • site/src/components/hub/nav/MobileMenu.vue
  • site/src/components/hub/nav/NavDesktopLink.vue
  • site/src/components/hub/nav/NodeBadge.vue
  • site/src/components/hub/nav/SiteNav.vue
  • site/src/components/template-detail/Breadcrumbs.astro
  • site/src/components/template-detail/ExpandableText.vue
  • site/src/components/template-detail/FaqAccordion.vue
  • site/src/components/template-detail/TemplateDetailPage.astro
  • site/src/components/ui/button/index.ts
  • site/src/composables/scrollLock.ts
  • site/src/composables/useFacets.ts
  • site/src/composables/useHubStore.ts
  • site/src/config/nav-routes.ts
  • site/src/i18n/ui.ts
  • site/src/lib/featured.ts
  • site/src/lib/github.ts
  • site/src/lib/hub-api.ts
  • site/src/lib/provider-logos.ts
  • site/src/lib/routes.ts
  • site/src/lib/search-config.ts
  • site/src/lib/search.ts
  • site/src/lib/structured-data.ts
  • site/src/lib/toolbar.ts
  • site/src/pages/[locale]/workflows/[slug].astro
  • site/src/pages/[locale]/workflows/category/[type].astro
  • site/src/pages/[locale]/workflows/index.astro
  • site/src/pages/[locale]/workflows/model/[name].astro
  • site/src/pages/[locale]/workflows/tag/[tag].astro
  • site/src/pages/workflows/[slug].astro
  • site/src/pages/workflows/[username].astro
  • site/src/pages/workflows/category/[type].astro
  • site/src/pages/workflows/index.astro
  • site/src/pages/workflows/model/[name].astro
  • site/src/pages/workflows/tag/[tag].astro
  • site/src/styles/design-tokens.css
  • site/src/styles/global.css
  • site/tests/unit/featured.test.ts
  • site/tests/unit/provider-logos.test.ts
  • site/tests/unit/routes.test.ts
  • site/tests/unit/search-config.test.ts
  • site/tests/unit/use-facets.test.ts
  • site/vitest.config.ts
💤 Files with no reviewable changes (1)
  • site/src/components/hub/MobileFilterDrawer.vue

Comment thread site/src/components/hub/nav/MobileMenu.vue Outdated
Comment thread site/src/components/hub/nav/MobileMenu.vue Outdated
Comment thread site/src/components/hub/nav/NavDesktopLink.vue Outdated
Comment thread site/src/components/hub/nav/SiteNav.vue Outdated
Comment thread site/src/components/hub/nav/SiteNav.vue Outdated
Comment thread site/src/pages/[locale]/workflows/[slug].astro
Comment thread site/src/pages/[locale]/workflows/[slug].astro
Comment thread site/src/styles/global.css Outdated
Comment thread site/tests/unit/provider-logos.test.ts
Comment thread site/tests/unit/use-facets.test.ts
@dante01yoon

Copy link
Copy Markdown
Contributor

🚀 Preview deployed for this PR (head 2fcc956):

https://workflow-templates-h3x07jaod-comfyui.vercel.app

Deployed manually by a maintainer as a one-off preview. Note: built without the preview API env vars, so data-driven sections may render empty — the comfyhub redesign UI itself is fully viewable.

Going forward, fork PRs will get automatic previews once a maintainer adds the preview label (see #965).

@dante01yoon

Copy link
Copy Markdown
Contributor

Verify actual CI passed - failures happen due to token issue

@socket-security

socket-security Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​embla-carousel-vue@​8.6.010010010082100
Addednpm/​embla-carousel-autoplay@​8.6.010010010082100

View full report

@MaanilVerma

MaanilVerma commented Jun 25, 2026

Copy link
Copy Markdown
Author

Knit Picks Updated (It start from this Commit ID )

What we fixed:

  1. Author name now lines up neatly with the avatar on cards and the featured banner.
  2. Card tags now show only full, readable tags that fit, then a "+N" chip — no more clipped "Vi…" stubs.
    Hovering "+N" lists the remaining tags. Tags read in normal Title Case; the old scroll arrows are gone.
  3. Cards with no tags show a single fallback chip (Image / Video / Audio / 3D) so every card looks balanced.
  4. The featured banner is now fully clickable — clicking the title or empty area opens the workflow
    (the creator and tag links still go to their own pages).
  5. Navbar items no longer flash a white box on keyboard focus; they show a clean yellow focus ring instead.
  6. Card hover: the corner button starts as a chevron and smoothly reveals "TRY NOW" on hover.
  7. Search bar moved out of the header into the page, above the filters — it now sticks to the top once you
    scroll past it and drops back into place on scroll up. (Other pages keep the search in the header as before.)
  8. The filter toolbar no longer sticks (it scrolls away normally); only the search bar pins.
  9. Multiple model logos now show as a small overlapping stack (max 3) on the top-right of a card;
    hovering one brings it to the front.
  10. Removed the big circle handle from the before/after comparison slider on cards.

Under the hood:

  • Search dropdown badge labels (creators / categories / models) are now vertically centered.
  • Added a reusable tooltip + a "fit + overflow" tag component, with unit and e2e test coverage.
  • Removed duplicated types and dead scroll-shadow code; tightened comments.

@MaanilVerma MaanilVerma added the preview Maintainer opt-in: deploy a Vercel preview for this (fork) PR label Jun 25, 2026
@dante01yoon

Copy link
Copy Markdown
Contributor

🚀 Preview deployed: https://workflow-templates-9xscoj11g-comfyui.vercel.app

Manual prebuilt Vercel deploy of this PR's head (0d6ec85), built with SKIP_AI_GENERATION=true (content from synced collection). Home and /workflows verified 200.

@dante01yoon dante01yoon left a comment

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.

Re-review of the Knit-Picks round since my prior approval (13fba4f10d6ec856). The incremental changes are clean polish — TagScroller→TagRow fit+overflow, stacked model logos, ButtonPill reveal try-now, sticky in-body search, RTL/reduced-motion fixes, restored field boost, focus-ring fix.

Verified locally on the PR head:

  • astro check: 0 errors / 0 warnings.
  • vitest: 213 passing (both changed suites — search-config +30, provider-logos +29 — green).
  • No dangling refs after the renames/moves: TagScroller, the old tag-pills testid, and the local CreatorEntry export are all gone, with CreatorEntry now sourced from hub-api and consumed only by SearchPopover.
  • FeaturedCarousel "fully clickable" is sound: a real full-slide <a class="absolute inset-0 z-10"> sits behind the now-pointer-events-none overlay, and the creator/tag children re-enable pointer-events-auto with @click.stop.
  • ButtonPill reveal self-hover works (group/button-pill is on the cva base) and the card path uses group/pill-trigger.

Note on red checks: Lint & Format, SEO Audit, and preview fail only at their final "Comment on PR"/deploy step with 403 Resource not accessible by integration (fork-PR token), not on real checks — ESLint ✅, Prettier ✅, Sitemap ✅, SEO Audit ✅ all passed. Matches the maintainer note.

Approving. Two non-blocking nits inline.

Comment thread site/src/components/ui/button-pill/index.ts Outdated
Comment thread site/tests/e2e.spec.ts Outdated

@dante01yoon dante01yoon left a comment

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.

Re-review of the latest round since my prior approval (0d6ec856727d5c61). 5 files; both of my earlier nits are resolved and the navbar wordmark fix verified.

Nit follow-ups (both addressed):

  • buttonPillLabelVariants removed and inlined into ButtonPill.vue. The inline class set is byte-for-byte equivalent to the old buttonPillLabelVariants() default (open: false) output — same six utilities, only reordered — so the reveal animation is unchanged. No leftover references anywhere.
  • page.waitForNavigation()page.waitForURL(/\/workflows\/tag\/.+\//) using the same regex as the assertion below. astro check deprecation hints dropped 5 → 4, confirming the ts(6387) flag is gone.

Wordmark (SVG rebuild + HeaderMain sizing) — rendered to verify:

  • The SVG renders cleanly as "Comfy HUB" with no doubled/overlapping glyphs (I'd flagged a possible overlap between the original path and the new scale(0.6115) group — render confirms it's a single clean lockup).
  • Intrinsic 240×48 → at h-10 (40px) the image is 200px wide; new container max-w-56 (224px) fits it without clipping, where the old w-44 (176px) was cutting the HUB badge. Sizing math and the rendered in-context capture both confirm no clip.

Validation on 727d5c61: astro check 0 errors / 0 warnings; vitest 213 passing; CI ESLint ✅ / Prettier ✅ (Lint & Format / SEO Audit / preview still red only on the fork-token 403 Resource not accessible by integration comment/deploy step — not real failures).

No new findings. Approving.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Maintainer opt-in: deploy a Vercel preview for this (fork) PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants