Skip to content

fix(home): discover showcase screenshots via a build-time virtual module - #652

Merged
kelsos merged 1 commit into
rotki:mainfrom
kelsos:fix/showcase-screenshots
Aug 4, 2026
Merged

fix(home): discover showcase screenshots via a build-time virtual module#652
kelsos merged 1 commit into
rotki:mainfrom
kelsos:fix/showcase-screenshots

Conversation

@kelsos

@kelsos kelsos commented Aug 4, 2026

Copy link
Copy Markdown
Member

The homepage showcase carousel renders nothing in production: no slides, the container collapsed to 2px, and the screenshot preloads reported as "preloaded but not used". The testimonial carousel on the same page, using the same swiper version, is fine.

Not swiper

AppShowcaseSlider built its slide list with

import.meta.glob('~~/public/img/screenshots/*.(png|jpe?g|webp)')

import.meta.glob cannot see into public/ — Vite deliberately keeps that directory out of the module graph. The dev server resolves such patterns off the filesystem, so it looks correct locally; the build has nothing to enumerate.

From the currently deployed bundle (AppShowcaseSlider-579d3be2.dAERDHky.js):

function C(){let e=Object.keys(Object.assign({}));}

The glob compiled to Object.assign({}) — an empty object. So images was [] and the carousel had no slides to render. Vite 7 still resolved the pattern, which is why this only appeared with the vite 8 upgrade (#649).

Fix

An app-screenshots Nuxt module reads the directory at build time and exposes it as virtual:app-screenshots, so the list stays auto-discovered rather than becoming a hand-maintained array someone has to remember to update.

  • Sorted with localeCompare(..., { numeric: true }), so a future 10-… sorts after 9-… instead of after 1-….
  • Only files directly in the folder count. The responsive/ subfolder holds pre-generated width variants of the first slide, not slides of its own.
  • The dev server watches the folder and invalidates the virtual module when a screenshot is added or removed.
  • If the folder resolves empty the build warns. The original failure was silent, which is the part worth fixing beyond the immediate bug.

Alt text stays in the component, keyed by filename, since it is copy rather than build data.

Verification

Against a real production build, comparing bundles:

deployed today with this change
screenshot paths in client chunk 0 7
screenshot paths in server chunk 0 7
Object.assign({}) empty-glob present gone

And in the browser: 7 slides, carousel 792px tall (was 2px), first screenshot visible, pagination and arrows working. Testimonial carousel unaffected at 14 slides.

typecheck clean, lint clean (68 pre-existing warnings, 0 errors), 502 tests pass.

Note for reviewers

pnpm generate currently fails on my machine with a nitro CSS-chunk placeholder error (Could not resolve "./entry-styles-3.mjs-<buildId>.!~{003}~.js"). That reproduces on unmodified main too and does not happen in CI, so it is environmental and unrelated to this change — but worth knowing if you hit it locally.

The homepage showcase carousel rendered nothing in production: no slides,
the container collapsed to 2px, and the screenshot preloads were reported as
unused. The testimonial carousel on the same page was fine.

Not a swiper problem. `AppShowcaseSlider` built its slide list with

    import.meta.glob('~~/public/img/screenshots/*.(png|jpe?g|webp)')

and glob cannot see into `public/`: Vite deliberately keeps that directory
out of the module graph. The dev server resolves such patterns off the
filesystem, so it looked correct locally, while the deployed bundle shows
the call compiled down to

    Object.keys(Object.assign({}))

an empty object, so `images` was `[]` and the carousel had nothing to render.
It only started failing with the vite 8 upgrade; vite 7 still resolved it.

Replaces the glob with an `app-screenshots` module that reads the directory
at build time and exposes it as `virtual:app-screenshots`, keeping the list
auto-discovered rather than hand-maintained. Files are sorted naturally so
`10-…` would follow `9-…`, only files directly in the folder count (the
`responsive/` subfolder holds width variants of the first slide, not slides),
and the dev server invalidates the module when a screenshot is added or
removed. If the folder is ever empty the build warns rather than silently
shipping an empty carousel, which is what made this so quiet.

Verified against a production build: the client and server bundles now both
contain all 7 screenshot paths, where the deployed ones contain none, and
`Object.assign({})` is gone. Confirmed in the browser: 7 slides, carousel
792px tall, first screenshot visible.
@kelsos
kelsos requested a review from a team as a code owner August 4, 2026 16:47
@codecov-commenter

codecov-commenter commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.93%. Comparing base (579d3be) to head (66d88f8).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...ebsite/app/components/common/AppShowcaseSlider.vue 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #652      +/-   ##
==========================================
+ Coverage   27.92%   27.93%   +0.01%     
==========================================
  Files         391      391              
  Lines       12456    12449       -7     
  Branches     1732     1732              
==========================================
  Hits         3478     3478              
+ Misses       8879     8872       -7     
  Partials       99       99              
Flag Coverage Δ
backend 56.55% <ø> (ø)
frontend 18.74% <0.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@kelsos
kelsos merged commit 66d88f8 into rotki:main Aug 4, 2026
9 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.

2 participants