---
categories: true
carousel: {{theme_settings.homepage_show_carousel}}
products:
new:
limit: {{theme_settings.homepage_new_products_count}}
featured:
limit: {{theme_settings.homepage_featured_products_count}}
top_sellers:
limit: {{theme_settings.homepage_top_products_count}}
blog:
recent_posts:
limit: {{theme_settings.homepage_blog_posts_count}}
summary: 300
brands:
shop_by_brand:
limit: 10
gql: "query HomeMakers { site { brands(first: 12) { edges { node { name path defaultImage { url(width: 320) } } } } } }"
---
{{#partial "hero"}}
{{!-- BigCommerce Marketing Banners (Control Panel > Marketing > Banners).
Platform auto-filters by page + position + visibility + date rule,
so the theme only needs to render them. Independent of yen-topbar.
Rendered at the very top of the page (above the hero carousel) so the
"top" banner position is consistent with category/brand/search pages. --}}
{{#if banners.top}}
{{#each banners.top}}
{{{this}}}
{{/each}}
{{/if}}
{{{region name="home_below_menu"}}}
{{!-- Ember Theme: Hero Carousel (3-slide, content-synced) --}}
{{assignVar 'yenPills' theme_settings.yen-hero-pills}}{{assignVar 'yenPill1' theme_settings.yen-hero-pill-1}}{{assignVar 'yenPill2' theme_settings.yen-hero-pill-2}}{{assignVar 'yenPill3' theme_settings.yen-hero-pill-3}}{{> components/common/promise-pill-vars}}
{{!-- The editorial preset brings its own photographs and copy: the classic ones are
furniture, which is what made the Fashion variation read as the Home store. --}}
{{assignVar 'yenHeroKey' 'homepage.hero_slide'}}{{assignVar 'yenCtaKey' 'homepage.hero_slide'}}{{assignVar 'yenHeroDir' 'img/yen-theme/'}}
{{#if theme_settings.yen-layout-preset '===' 'editorial'}}{{assignVar 'yenHeroKey' 'homepage.editorial_slide'}}{{assignVar 'yenHeroDir' 'img/yen-theme/editorial/'}}{{/if}}
{{!-- The Food variation keeps the classic layout but not its furniture: its content
set brings food photographs and copy. --}}
{{#if theme_settings.yen-content-set '===' 'food'}}{{assignVar 'yenHeroKey' 'homepage.food_slide'}}{{assignVar 'yenCtaKey' 'homepage.food_slide'}}{{assignVar 'yenHeroDir' 'img/yen-theme/food/'}}{{/if}}
{{!-- Classic slides 2 and 3 sell bedrooms and patios, so on a store of its own they keep only
their Page Builder region, and yen-theme.js drops a slide whose region is empty; the
demo stores (hidden yen-demo-content) keep the sample slides. yenHeroCount 1 marks that. --}}
{{assignVar 'yenHeroCount' 3}}
{{#if carousel.slides}}{{assignVar 'yenHeroCount' carousel.slides.length}}{{else if (getVar 'yenHeroKey') '===' 'homepage.hero_slide'}}{{#unless theme_settings.yen-demo-content}}{{assignVar 'yenHeroCount' 1}}{{/unless}}{{/if}}
{{!-- Every slide shares one box, so the first Control Panel photograph's shape sets
how tall it grows on a wide screen (editorial and market). --}}
{{#if carousel.slides}}
{{!-- Control Panel > Storefront > Carousel. Requested by the front matter only while
homepage_show_carousel is on, so with it off -- or with no slides -- the theme's
own slides below render instead. Same markup and classes as those, so the
presets, the phone layout and yen-theme.js treat both alike. Text is escaped. --}}
{{!-- On the storefront the root context is out of reach inside this loop (the slide
count rendered as "undefined"), so what the slides read from the page is copied in first. --}}
{{assignVar 'yenCpTotal' carousel.slides.length}}{{assignVar 'yenCpPreset' theme_settings.yen-layout-preset}}{{assignVar 'yenCpFocus1' theme_settings.yen-hero-1-focus}}{{assignVar 'yenCpFocus2' theme_settings.yen-hero-2-focus}}{{assignVar 'yenCpFocus3' theme_settings.yen-hero-3-focus}}{{assignVar 'yenCpContainer' theme_settings.yen-container-width}}
{{#each carousel.slides}}
{{!-- A button with no link is left out, so it does not earn the slide a text column. --}}
{{assignVar 'yenCpCta' ''}}{{#if button_text}}{{#if url}}{{assignVar 'yenCpCta' 'y'}}{{/if}}{{/if}}
{{#or heading text (getVar 'yenCpCta')}}
{{#if heading}}
{{heading}}
{{/if}}
{{#if text}}
{{text}}
{{/if}}
{{!-- A button with no link has nowhere to go, so it is left out. --}}
{{#if button_text}}{{#if url}}
{{/or}}
{{!-- `sizes` is the theme slides' hint: the box is the same, only the photo differs. An
image-only classic slide fills the container instead of the 7fr column. --}}
{{/each}}
{{else}}
{{!-- Slide 1 — Page Builder region. Merchants drop a Banner widget
(image + heading + subheading + CTA) into this slot via Page Builder.
Falls back to default content below if no widget is placed (so the
demo store and freshly-installed themes still look complete). --}}
{{{region name="home_hero_slide_1"}}}
{{!-- Slide 1 only. It is the LCP element on the home page, and
loading="eager" alone just means "do not defer" -- the browser
still queues it behind whatever it discovered first.
fetchpriority="high" says this is the one image worth contending
for. Slides 2 and 3 stay lazy: they are off-screen until the
carousel advances, and marking them high would compete with the
slide actually being looked at. --}}
{{!-- Fallback CTAs use BC's universal /categories/ route (the
"All Categories" index page that exists on every BC store by
default). Never point a fallback CTA at a demo-store category
slug — it 404s on a freshly installed store. All three slides
follow the same pair: primary -> /categories/, secondary ->
the blog, so no slide ships two buttons with one destination.
For real production sites, merchants should override this
slide via Page Builder Banner widget with their preferred
category/page URL. --}}
{{lang (concat (getVar 'yenCtaKey') '_1_cta')}} →
{{#if blog.url}}{{lang (concat (getVar 'yenCtaKey') '_1_cta_alt')}}{{/if}}
{{> components/home/hero-pills}}
{{!-- Hero renditions are theme assets, so getImageSrcset cannot build
this srcset — it resolves a BigCommerce image object, and a file the
theme ships has none. The widths come from
scripts/images/build-hero-variants.js.
`sizes` mirrors the layout by hand: the image column is 7fr of the
5fr/7fr grid in _yen-theme.scss inside a container capped at 1400px,
which is the 732px Lighthouse measured, and it steps down as those
columns even out and then stack. On phones the photo covers a box
shorter than its 2.13:1 (classic up to 640px, editorial and market up
to 800px), so the hint there is the cropped width, box height x 2.13,
and yen-hero--focus picks the crop. Change the grid and this has to
move with it, on all three slides — a stale hint picks the wrong rendition
silently, costing sharpness or bytes rather than failing. --}}
{{!-- One slide: no dots, and yen-theme.js starts no autoplay, so no pause button either. --}}
{{#unless carousel.slides.length '===' 1}}
{{#if carousel.slides}}
{{#each carousel.slides}}
{{/each}}
{{else}}
{{/if}}
{{!-- Hidden until yen-theme.js shows it: without scripts there is no autoplay to stop. --}}
{{/unless}}
{{{region name="home_below_carousel"}}}
{{!-- Market preset: the trust claims as a slim strip here, instead of the tiles below. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{> components/home/market/trust-strip}}{{/if}}
{{/partial}}
{{#partial "page"}}
{{!-- Promotion notices sit on the page gutter like every other block, not edge to edge. --}}
{{#if shipping_messages}}
{{!-- Shop by Category --}}
{{#if categories.length}}
{{lang 'categories.shop_by'}}
{{!-- Five framed cards fill the classic row; the market preset sets its aisles
four to a row as photographs, so it shows eight in two rows. --}}
{{assignVar 'yenCatCount' 5}}{{#if theme_settings.yen-layout-preset '===' 'market'}}{{assignVar 'yenCatCount' 8}}{{/if}}
{{/if}}
{{!-- Promo Banner. The market preset pairs it with the Lookbook further down instead
(components/home/market/offers.html). --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{else}}
{{#if theme_settings.yen-show-promo-banner}}
{{> components/home/promo-url}}
{{#if (getVar 'yenViewallUrl')}}
{{#if (getVar 'yenPill1Shows')}}{{#or (trim theme_settings.yen-trust-shipping-title) (if (getVar 'yenPillThr') '>' 0)}}
{{#if theme_settings.yen-trust-shipping-title}}{{theme_settings.yen-trust-shipping-title}}{{else if (getVar 'yenPillThr') '>' 0}}{{lang 'homepage.trust_shipping_title'}}{{/if}}
{{!-- The store's own threshold, restated in the shopper's currency by
convertThresholds(), as in the header's topbar sentence. Left out
when the store has no threshold. --}}
{{#if theme_settings.yen-cart-show-shipping-progress}}{{#if theme_settings.yen-cart-free-shipping-threshold '>' 0}}' 1}} data-yen-threshold-pending{{/if}}>{{lang 'homepage.trust_shipping_note' amount=(concat settings.money.currency_token theme_settings.yen-cart-free-shipping-threshold)}}{{/if}}{{/if}}
{{/or}}{{/if}}
{{#if (getVar 'yenPill2Shows')}}
{{#if theme_settings.yen-trust-returns-title}}{{theme_settings.yen-trust-returns-title}}{{else}}{{lang 'homepage.trust_returns_title'}}{{/if}}
{{#if (trim theme_settings.yen-trust-returns-note)}}{{trim theme_settings.yen-trust-returns-note}}{{else}}{{lang 'homepage.trust_returns_note'}}{{/if}}
{{/if}}
{{#if (getVar 'yenPill3Shows')}}
{{#if theme_settings.yen-trust-secure-title}}{{theme_settings.yen-trust-secure-title}}{{else}}{{lang 'homepage.trust_secure_title'}}{{/if}}
{{lang 'homepage.trust_secure_note'}}
{{/if}}
{{/or}}{{/if}}
{{#if theme_settings.yen-promo-banner-image}}
{{!-- Below the fold on every viewport, and decorative — the banner's
words are live text beside it, not baked into the picture. The
three sibling images further down already defer; this one was
the outlier, and Lighthouse measured 112 KiB of it blocking the
first screen for nothing.
A merchant upload has unknown proportions, so it gets no
width/height (a guessed pair would distort it; the layout
reserves the box in CSS) and no renditions. The two banners the
theme ships come in 400-1200px renditions; the photo covers a
box about 400px tall, so it is drawn ~853px wide (1167px at
769-999px, where the box is taller). Hidden on phones. --}}
{{#if theme_settings.yen-promo-banner-image '===' 'img/yen-theme/promo-banner.jpg'}}
{{> components/common/yen-theme-picture src='img/yen-theme/promo-banner.jpg' width='1600' height='750' wide=true sizes='(min-width: 1000px) 853px, 1167px' classname='yen-promo-banner__image'}}
{{else if theme_settings.yen-promo-banner-image '===' 'img/yen-theme/food/promo-banner.jpg'}}
{{> components/common/yen-theme-picture src='img/yen-theme/food/promo-banner.jpg' width='1600' height='750' wide=true sizes='(min-width: 1000px) 853px, 1167px' classname='yen-promo-banner__image'}}
{{else}}
{{/if}}
{{else}}
{{#if theme_settings.yen-promo-banner-img1}}
{{/if}}
{{/if}}
{{/if}}
{{/if}}
{{/if}}
{{!-- Product Tabs: Featured / Best Sellers / New Arrivals. The market preset shows
the feeds as shelves instead, below the flash sale; its `home_above_products`
region moves with them, so it is always directly above the first product feed. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{else}}{{{region name="home_above_products"}}}{{/if}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{else}}{{> components/home/product-tabs}}{{/if}}
{{!-- Trust/Promo Badges. The market preset has them as the strip under the hero. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{else}}
{{#if theme_settings.yen-show-trust-badges}}
{{!-- Each badge only while its hero pill shows and it has a title (promise-pill-vars). --}}
{{> components/common/promise-pill-vars}}
{{#or (getVar 'yenPill1Shows') (getVar 'yenPill2Shows') (getVar 'yenPill3Shows')}}
{{/or}}
{{/if}}
{{/if}}
{{!-- Flash Sale / Countdown. Rendered only when the chosen source has products: Fashion
flags none as featured, and with the source on Featured the band drew its title and
timer over an empty grid. --}}
{{assignVar 'yenFlash' ''}}
{{#if theme_settings.yen-flash-sale-products '==' 'featured'}}{{#if products.featured}}{{assignVar 'yenFlash' 'featured'}}{{/if}}{{else if theme_settings.yen-flash-sale-products '==' 'new'}}{{#if products.new}}{{assignVar 'yenFlash' 'new'}}{{/if}}{{else}}{{#if products.top_sellers}}{{assignVar 'yenFlash' 'top'}}{{/if}}{{/if}}
{{!-- Only discounted products are a sale: the band shows those and nothing without one. --}}
{{assignVar 'yenFlashHit' 0}}
{{#if (getVar 'yenFlash') '===' 'featured'}}{{#each products.featured}}{{> components/home/flash-discount}}{{/each}}{{else if (getVar 'yenFlash') '===' 'new'}}{{#each products.new}}{{> components/home/flash-discount}}{{/each}}{{else if (getVar 'yenFlash') '===' 'top'}}{{#each products.top_sellers}}{{> components/home/flash-discount}}{{/each}}{{/if}}
{{#if theme_settings.yen-show-flash-sale}}{{#if (getVar 'yenFlashHit')}}
{{/if}}{{/if}}
{{!-- Market preset: the new arrivals, this week's deal beside the Lookbook, then the
best sellers and the makers. The new-arrivals shelf went with the deli take and
came back: without it the page had too little to buy (Giao, 2026-10-01). The
region the tabs carry comes along. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}
{{assignVar 'yenLookDir' 'img/lookbook/'}}
{{#if theme_settings.yen-content-set '===' 'food'}}{{assignVar 'yenLookDir' 'img/lookbook/food/'}}{{/if}}
{{{region name="home_above_products"}}}
{{> components/home/market/shelf products=products.new title=(lang 'products.new') category="New Arrivals" sort="newest" viewall=(lang 'homepage.view_all_new')}}
{{> components/home/market/offers}}
{{> components/home/market/shelf products=products.top_sellers title=(lang 'products.top') category="Best Sellers" sort="bestselling" viewall=(lang 'homepage.view_all_top')}}
{{> components/home/market/makers}}
{{{region name="home_below_featured_products"}}}
{{/if}}
{{{region name="home_below_top_products"}}}
{{!-- What Customers Say: the merchant's own quotes, with no rating or "verified" mark the
theme cannot know. Off by default, and nothing at all without a quote. --}}
{{#if theme_settings.yen-show-testimonials}}{{#or theme_settings.yen-testimonial-1-quote theme_settings.yen-testimonial-2-quote theme_settings.yen-testimonial-3-quote}}
{{/or}}{{/if}}
{{!-- Brand Story / Video. Not on the market preset, whose page is products first. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{else}}
{{#if theme_settings.yen-show-brand-story}}
{{/if}}
{{!-- Resolved from the merchant's own "About Us" Web Page: the theme
cannot create that page, and a hardcoded /about-us 404s on a
store that never made one, so the button is dropped instead.
A duplicate page name renders the button twice, which is
cosmetic — the href stays intact because {{#filter}} wraps the
whole element here rather than sitting inside an attribute. --}}
{{#filter pages "About Us" property="name"}}
{{#if ../theme_settings.yen-brand-story-btn}}{{../theme_settings.yen-brand-story-btn}}{{else}}{{lang 'homepage.brand_story_btn'}}{{/if}} →
{{/filter}}
{{!-- getImage resolves only a preset or a setting holding a size, so the literal
'600x400' this used to pass fetched the original (~100-120 KB per card).
The photo is cropped to cover its box, so a ~3:2 thumbnail (the common
shape) is drawn 1.5x the box height wide whenever that beats the box
width: 1.125x the width of the 4:3 frame, and 423px in market's 148x282
tile at 801px. --}}
{{#if theme_settings.yen-layout-preset '===' 'market'}}{{assignVar 'yenBlogSizes' '(min-width: 801px) 423px, (min-width: 468px) 470px, calc(113vw - 56px)'}}{{else}}{{assignVar 'yenBlogSizes' '(min-width: 1600px) 569px, (min-width: 768px) calc(38vw - 30px), (min-width: 468px) 470px, calc(113vw - 56px)'}}{{/if}}
{{!-- The control panel's own summary (Email marketing > Show newsletter summary) wins over the theme text. --}}
{{#all settings.show_newsletter_summary settings.newsletter_summary}}{{settings.newsletter_summary}}{{else if theme_settings.yen-footer-newsletter-desc}}{{theme_settings.yen-footer-newsletter-desc}}{{else if theme_settings.yen-demo-content}}{{lang 'newsletter.subscribe_intro'}}{{else}}{{lang 'newsletter.subscribe_intro_plain'}}{{/all}}
{{lang 'newsletter.privacy_note'}}
{{/if}}
{{!-- As Seen In / Press Logos --}}
{{#if theme_settings.yen-show-press}}