Product hero section
for Dawn and Horizon.
This two-column product hero works on any Shopify template, like your homepage, a landing page, or a dedicated campaign page. Pick a product in the theme editor and configure the layout. It renders the image, price, add to cart button, plus an optional badge and trust line. It runs without a paid app or third-party scripts.
Preview the product hero before editing code.
Tune the visible product copy, price state, trust line, accent, and column order. The section file below uses Shopify product data and theme-editor settings for the live store.
Best seller
Barrier Repair Cream
$72$58
A focused hero for one product, with price, proof, and a single add-to-cart action.
Free shipping over $100 / 30-day returns
{% comment %}
Jelonyx · Product Hero Section
Compatible with Dawn 12+, Horizon, and most OS 2.0 themes
Source: jelonyx.com/shopify/sections/product-hero
{% endcomment %}
{%- assign hero_product = section.settings.product -%}
{%- if hero_product != blank -%}
<section
id="jlx-ph-{{ section.id }}"
class="jlx-ph{% if section.settings.layout == 'image_right' %} jlx-ph--reverse{% endif %}"
>
<div class="jlx-ph__inner">
<div class="jlx-ph__media">
{%- if hero_product.featured_image != blank -%}
{{
hero_product.featured_image
| image_url: width: 1200
| image_tag:
width: 600,
height: 600,
class: 'jlx-ph__img',
alt: hero_product.featured_image.alt | escape,
loading: 'eager',
fetchpriority: 'high'
}}
{%- endif -%}
</div>
<div class="jlx-ph__content">
{%- if section.settings.badge != blank -%}
<span class="jlx-ph__badge">{{ section.settings.badge }}</span>
{%- endif -%}
{%- if section.settings.subtitle != blank -%}
<p class="jlx-ph__subtitle">{{ section.settings.subtitle }}</p>
{%- endif -%}
<h2 class="jlx-ph__title">{{ hero_product.title }}</h2>
<p class="jlx-ph__price">
{%- if hero_product.compare_at_price > hero_product.price -%}
<s class="jlx-ph__compare">{{ hero_product.compare_at_price | money }}</s>
{%- endif -%}
<span>{{ hero_product.price | money }}</span>
</p>
{%- if section.settings.description != blank -%}
<p class="jlx-ph__desc">{{ section.settings.description }}</p>
{%- elsif hero_product.description != blank -%}
<p class="jlx-ph__desc">{{ hero_product.description | strip_html | truncate: 200 }}</p>
{%- endif -%}
{%- form 'product', hero_product, id: 'jlx-ph-form-{{ section.id }}', class: 'jlx-ph__form' -%}
<input type="hidden" name="id" value="{{ hero_product.selected_or_first_available_variant.id }}">
<button
type="submit"
name="add"
class="jlx-ph__btn"
{%- unless hero_product.selected_or_first_available_variant.available -%}disabled{%- endunless -%}
>
{%- if hero_product.selected_or_first_available_variant.available -%}
{{ section.settings.button_label | default: 'Add to cart' }}
{%- else -%}
Sold out
{%- endif -%}
</button>
{%- endform -%}
{%- if section.settings.trust_line != blank -%}
<p class="jlx-ph__trust">{{ section.settings.trust_line }}</p>
{%- endif -%}
</div>
</div>
</section>
<style>
#jlx-ph-{{ section.id }} {
padding: clamp(40px, 8vw, 80px) 20px;
background: var(--color-background, #ffffff);
}
.jlx-ph__inner {
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: clamp(32px, 6vw, 80px);
align-items: center;
}
.jlx-ph--reverse .jlx-ph__media { order: 2; }
.jlx-ph--reverse .jlx-ph__content { order: 1; }
.jlx-ph__img {
width: 100%;
height: auto;
display: block;
border-radius: 8px;
aspect-ratio: 1 / 1;
object-fit: cover;
}
.jlx-ph__content {
display: flex;
flex-direction: column;
gap: 16px;
}
.jlx-ph__badge {
display: inline-block;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
background: var(--color-button, #1a1a1a);
color: var(--color-button-text, #ffffff);
padding: 4px 10px;
border-radius: 2px;
align-self: flex-start;
}
.jlx-ph__subtitle {
font-size: 13px;
color: var(--color-foreground-secondary, #6b6b6b);
margin: 0;
}
.jlx-ph__title {
font-size: clamp(24px, 4vw, 40px);
font-weight: 700;
line-height: 1.15;
color: var(--color-foreground, #1a1a1a);
margin: 0;
}
.jlx-ph__price {
font-size: 20px;
font-weight: 600;
color: var(--color-foreground, #1a1a1a);
display: flex;
align-items: baseline;
gap: 10px;
margin: 0;
}
.jlx-ph__compare {
font-size: 15px;
font-weight: 400;
color: var(--color-foreground-secondary, #6b6b6b);
}
.jlx-ph__desc {
font-size: 15px;
line-height: 1.65;
color: var(--color-foreground-secondary, #6b6b6b);
margin: 0;
}
.jlx-ph__form { margin-top: 4px; }
.jlx-ph__btn {
width: 100%;
background: var(--color-button, #1a1a1a);
color: var(--color-button-text, #ffffff);
border: 1px solid transparent;
border-radius: 4px;
padding: 16px 32px;
font-size: 15px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: opacity 0.15s ease;
}
.jlx-ph__btn:hover { opacity: 0.85; }
.jlx-ph__btn:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.jlx-ph__trust {
font-size: 13px;
color: var(--color-foreground-secondary, #6b6b6b);
text-align: center;
margin: 0;
}
@media (max-width: 720px) {
.jlx-ph__inner { grid-template-columns: 1fr; }
.jlx-ph--reverse .jlx-ph__media,
.jlx-ph--reverse .jlx-ph__content { order: unset; }
}
</style>
{%- else -%}
{%- if request.design_mode -%}
<div style="padding: 60px 20px; text-align: center; border: 2px dashed rgba(0,0,0,0.12); border-radius: 8px;">
<p style="color: #888; font-size: 14px; margin: 0;">Select a product in the section settings to preview.</p>
</div>
{%- endif -%}
{%- endif -%}
{% schema %}
{
"name": "Product hero",
"tag": "section",
"class": "section",
"settings": [
{
"type": "product",
"id": "product",
"label": "Product"
},
{
"type": "select",
"id": "layout",
"label": "Layout",
"options": [
{ "value": "image_left", "label": "Image left" },
{ "value": "image_right", "label": "Image right" }
],
"default": "image_left"
},
{
"type": "text",
"id": "badge",
"label": "Badge text",
"placeholder": "New arrival"
},
{
"type": "text",
"id": "subtitle",
"label": "Subtitle",
"placeholder": "The summer collection"
},
{
"type": "textarea",
"id": "description",
"label": "Custom description",
"info": "Leave blank to use the product description automatically."
},
{
"type": "text",
"id": "button_label",
"label": "Button label",
"default": "Add to cart"
},
{
"type": "text",
"id": "trust_line",
"label": "Trust line",
"placeholder": "Free shipping over $100 · 30-day returns"
}
],
"presets": [
{
"name": "Product hero",
"category": "Products"
}
]
}
{% endschema %}How to add the section
- 01Open your theme code editor.
In Shopify Admin, go to Online Store → Themes. On your active theme, click the three-dot menu and select Edit code.
- 02Create a new section file.
Under the Sections folder, click Add a new section. Name it
jlx-product-heroand click Done. - 03Paste the full section code.
Delete any placeholder content in the new file, paste the entire code block above, and save.
- 04Add the section to a template.
Open the theme editor (Customize). Navigate to the template where you want the hero, like a homepage or landing page. Click Add section and select Product hero.
- 05Select a product and configure.
In the section settings panel on the left, pick the product to feature. Set the layout, badge text, button label, and trust line to match your store. Save.
Schema settings
All settings are editable from the theme editor. No code changes are needed after install.
productproductThe product to feature. Required. The section renders nothing without one.layoutselectImage left or image right. Controls column order.badgetextOptional pill label above the title. e.g. "New arrival", "Best seller".subtitletextOptional line above the product title. Good for collection or campaign context.descriptiontextareaOverride text. Leave blank to pull the product description automatically (truncated to 200 chars).button_labeltextButton copy. Defaults to "Add to cart". Becomes "Sold out" automatically when the variant is unavailable.trust_linetextSmall line below the button. e.g. "Free shipping over $100 · 30-day returns".How it works
The section uses {% form 'product', hero_product %} to generate a standard Shopify product form. Clicking the button adds the product to the cart using your theme's existing cart behaviour (cart drawer, cart page, or mini cart) without any additional JavaScript.
Scoped CSS uses #jlx-ph-{{ section.id }} so padding and background can be set per-instance without conflicts. The two-column layout and the image class (.jlx-ph__ prefix) apply globally, so multiple instances on the same page share those rules.
The image is rendered with loading="eager" and fetchpriority="high" since a product hero is typically above the fold. Change these to loading="lazy" if you place the section further down the page.
In the theme editor, when no product is selected, the section renders a dashed placeholder box via request.design_mode. On the live storefront it renders nothing. You won't see any empty space or a broken layout.
Compatibility
Tested against Dawn 12+ and Horizon. Both themes define the standard CSS variables the section reads (--color-background, --color-button, --color-button-text, --color-foreground), so the hero picks up your store's brand colours automatically.
On themes that do not define these variables, the section falls back to neutral values (white background, dark button, dark text). Override the .jlx-ph__btn and .jlx-ph__badge classes in the section CSS to hard-code colours for your theme.
Limitations
- No variant picker: the section always adds the first available variant. If your featured product has multiple variants, add a variant select to the form or link the section to a single-variant product. A variant-aware version is a more involved build.
- Single product per instance: the section features one product. Add multiple instances to the template to feature several products. Each instance has its own settings panel.
- Static image: only the featured image is used. For a multi-image gallery or image zoom, that requires additional JavaScript and markup.
- Headless storefronts: this is a Liquid section and does not apply to Hydrogen or other headless setups.
Need this built for your store?
If you want this section styled to match your brand, extended with a variant picker or gallery, or built into a larger landing page, we can scope and deliver that.