Theme screenshots & assets¶
A theme ships two kinds of images, for two different audiences:
| Kind | Audience | Lives in | Ships as |
|---|---|---|---|
| Marketplace screenshots + thumbnail | Merchants browsing the theme store, reviewers | screenshots/ (repo root) |
screenshots/ inside theme.zip |
| Bundled static assets (banners, images) | The storefront, at render time | src/themes/custom/assets/ |
theme/assets/ inside theme.zip |
Marketplace images are only used to present the theme. Bundled assets are drawn by the theme's own components on the live storefront. Keep them separate.
1. Marketplace screenshots & thumbnail¶
These are the preview images on the theme's store listing — a square thumbnail for the gallery card plus full previews for the detail page.
Declare them in theme.config.json¶
{
// …name, slug, version, author, description…
"thumbnail": "./screenshots/thumbnail.png",
"screenshots": {
"desktop": "./screenshots/desktop.png",
"tablet": "./screenshots/tablet.png",
"mobile": "./screenshots/mobile.png",
"dark": "./screenshots/dark-mode.png" // include if the theme supports darkMode
}
}
Drop the matching files in the root screenshots/ folder.
Recommended files & sizes¶
| File | Purpose | Recommended size |
|---|---|---|
thumbnail.png |
Gallery card (square) | 800 × 800 |
desktop.png |
Full homepage, desktop | 1600 × 1000 |
tablet.png |
Homepage, tablet | 1024 × 1366 |
mobile.png |
Homepage, mobile | 750 × 1334 |
dark-mode.png |
Dark scheme (if features.darkMode) |
1600 × 1000 |
Formats: .png, .jpg, .webp. All keys are optional, but a theme with no
thumbnail or screenshots lists without preview images — npm run validate warns
for each declared image that is missing, and for a theme that declares none.
npm run build stages screenshots/ into dist/screenshots/; npm run package
adds it to theme.zip under screenshots/.
2. Bundled static assets (banners & images)¶
Images the theme itself renders — hero/marketing banners, section artwork, illustrations, icons, default placeholders. They live inside the theme and ship in the built theme.
Where they go¶
src/themes/custom/assets/
├── banners/ # marketing / hero banners
└── images/ # everything else
The whole assets/ folder is copied into the built theme (dist/theme/assets/) and
ships in theme.zip.
Reference them from components¶
Use the @assets webpack alias, or a relative import:
import homeHero from "@assets/banners/home-hero.jpg";
// or
import homeHero from "./assets/banners/home-hero.jpg";
<Image src={homeHero} alt="Season sale" />
Because assets are bundled, they resolve the same in the local preview and on the live storefront — no S3 upload, no media slug.
Optional manifest¶
List reusable banners/images in theme.config.json so the platform (and merchants)
can discover and swap them. src is relative to the theme root and must live
under assets/:
{
"assets": {
"banners": [
{ "key": "home-hero", "src": "assets/banners/home-hero.jpg", "label": "Homepage hero", "alt": "Season sale" }
],
"images": [
{ "key": "about-team", "src": "assets/images/about-team.jpg", "label": "About page team photo" }
]
}
}
| Field | Required | Meaning |
|---|---|---|
key |
✔ | Stable id, unique across banners + images |
src |
✔ | Path under assets/, no .. — the file must exist |
label |
✔ | Human-readable name shown in the UI |
alt |
— | Default alt text |
The manifest is optional — files imported directly by components work without being listed. Use it for banners/images you want to be swappable or discoverable.
3. Validation¶
npm run validate (also run server-side on upload) checks:
- thumbnail / screenshots — declared files exist (warning if missing) and are image files
assets.banners[]/assets.images[]— each entry haskey,src,label;keyis unique;srcis underassets/with no..; and the file exists (a broken reference is a hard error)
Fix errors before packaging — the same gates run on the server at submission time.
See also¶
- Theme development — the full build → package → submit flow
- Custom theme widgets — widgets can expose their own
imagesettings - Header & footer builder — logo/image widgets that resolve a media slug at runtime