NORTH JS TECH
Skip to content
North Js Tech

Main Product Section

What it is / what it's for

This is the product detail page (PDP), the full page a shopper lands on when they open a single product. It shows the product's image gallery on one side and, on the other, a stack of information rows: title, price, variant pickers (colour/size), quantity, add‑to‑cart, description, and many optional extras.

It's built to be highly configurable: almost every part of the information column is a block you can add, remove, and reorder in the theme editor. The page also updates live when a shopper picks a different variant, the price, images, availability, and even the web address change without a full page reload.

Where it lives

PurposeFile
The section`sections/main-product.liquid`
Behaviour (variant changes, live updates)`assets/product-info.js`
Styling`assets/main-product.css` (source: `src/styles/scss/sections/main-product.scss`)
Image gallery`snippets/product-media-gallery.liquid`
The page template that loads it`templates/product.json`
main product page of cutline shopify theme

What it looks like / key parts

Two columns (which side the gallery is on is configurable):

  1. Media gallery — the product images, plus video, 3D models, and a zoom/lightbox.
  2. Information column — a reorderable stack of blocks. Common ones: Title, Price, Variant picker, Quantity, Buy buttons, Inventory, Description, Collapsible tabs, and more.

Extras that can appear: a sticky add‑to‑cart bar that follows the shopper as they scroll, size‑chart and info popups, and rich SEO data for search engines.

Settings you can change

Note

Where: In the theme editor, open a product page and select the Product information section. Settings are grouped below.

Layout

SettingWhat it does
**Desktop layout**Which side the media sits on (left/right).
**Desktop layout width**Column width ratio: equal, more room for content, or more room for media.
**Gallery/content gap**Space between the gallery and the information column.
**Sticky information**Keep the information column in view as the shopper scrolls (desktop).
**Content alignment (desktop & mobile)**Left / center / right alignment of the information text.
**Section padding (desktop & mobile)**Space above/below the section.
**Block spacing (desktop & mobile)**Gap between the information rows.
SettingWhat it does
**Desktop media layout**Thumbnail slider, stacked images, or a 2‑column grid.
**Thumbnail position**Left, bottom, or right of the main image.
**Slider arrows & pagination**Show arrows (chevron/arrow/caret) and dots/fraction; option to reveal arrows on hover.
**Image border radius**Rounded corners for the main image (desktop & mobile).
**Thumbnail shape**Round, circle, or custom‑radius thumbnails.
**Show thumbnails on mobile**Toggle the mobile thumbnail rail.
**Slide transition**Fade or slide between images.

Zoom / lightbox

SettingWhat it does
**Image zoom**Open a full‑screen gallery (lightbox) or disable zoom.
**What opens the lightbox**Clicking the image, or a dedicated button.
**Lightbox animation & speed**The open/close transition and its speed.
**Lightbox features**Toggles for counter, download, thumbnails, fullscreen, autoplay, rotate, share, zoom, etc.

Video

SettingWhat it does
**Autoplay / Mute / Loop / Controls**How product videos behave in the gallery.

Colours (light & dark mode)

SettingWhat it does
**Section background / text / error colour**Override colours for this section, with separate values for light and dark mode.
**Lightbox trigger button colours**Background/text of the zoom button.

Tip

Colours are only applied when you actually set one; left empty, the section inherits the global theme colours. Light and dark mode each have their own colour fields.

Blocks (the information rows)

The information column is entirely built from blocks. You add, remove, and reorder them in the theme editor. The most‑used blocks:

BlockWhat it shows / does
**Title**The product name (choose heading size, tag, colours).
**Vendor**The brand / vendor.
**Price**Price, sale & compare‑at price, unit price, tax/duty note, and payment‑installment messaging.
**Variant picker**The colour/size selectors — as swatches, buttons, or dropdowns.
**Quantity selector**A quantity stepper; can show volume/bulk pricing and per‑item price.
**Buy buttons**Add to cart + dynamic checkout (e.g. Shop Pay); options for pre‑order, gift‑card recipient, price‑in‑button.
**Inventory**Stock status message.
**SKU**The product/variant SKU.
**Rating**Star rating from review metafields.
**Description**The product description (optionally on a coloured background).
**Collapsible tab**An expandable section (e.g. Shipping, Returns).
**Selling plan**Subscription / selling‑plan selector (when the product offers subscriptions).
**Pickup availability**Local store pickup status.
**Size chart**A size‑chart popup.
**Popup**A custom info popup with a trigger link.
**Gift wrap**A gift‑wrap add‑on toggle.
**Product essentials**Highlighted feature tabs/accordion with its own popup/drawer.
**Sticky ATC bar**The sticky add‑to‑cart bar (separately toggled for desktop/mobile).
**Estimate delivery**Estimated delivery date message (with cut‑off times, excluded days, etc.).
**Nutrition facts**Nutrition info bar (from metafields).
**Payment methods**Accepted payment icons.
**Share**Social share buttons.
**Coupon code**Promotional coupon/offer.
**Video (UGC)**, **Social proof**, **Social reviews**Marketing/trust content.
**Banner**, **Icon with text**, **Text**, **Custom Liquid**Generic content rows.
**Personalization options**Custom inputs (e.g. engraving text) added to the line item.
**Product add‑ons**Up to 12 related/upsell products.
**Product benefits**A benefits highlight slider.

Tip

Most blocks can be used once; a few (like Nutrition facts, Icon with text, Personalization options) can be added multiple times.

What it depends on

Snippets it renders (see [Shared Product Components.md](./Shared%20Product%20Components.md) for the core ones): product-media-gallery, price, product-options, buy-buttons, inventory, quantity-input, selling-plan-selector, pickup-availability, plus many block‑specific snippets (estimate-delivery, collapsible-content, gift-wrap, product-essentials, product-popup, product-sticky-bar, nutrition-bar, coupon-offers, social-sharing, social-reviews, social-proof, video-ugc, personalization-options, product-add-ons, product-benefits, payment-methods, banner, icon-with-text, heading).

Smart loading: to keep the page fast, some files load only when needed — for example, gift‑wrap styles load only if a gift‑wrap block is present, pickup scripts only if a pickup block exists, and the 3D‑model viewer only if the product has a 3D model. The core behaviour script (product-info.js) always loads.

How it connects to the rest of the theme

  • It's the section configured in `templates/product.json`, so it powers every product page.
  • It shares the same building blocks (price, options, badges, inventory, buy buttons) as the [product card](./Product%20Cards.md) and the [Featured Product](./Featured%20Product.md) section — so pricing and variant pickers look and behave consistently.
  • The Featured Product section is essentially a portable copy of this one (see its doc for the differences).

Product data it uses

  • Variants — the selected/first‑available variant drives price, SKU, availability, quantity rules, and volume pricing.
  • Media — images, video, and 3D models from the product.
  • Metafields — review rating (for the Rating block) and nutrition data (for the Nutrition block).
  • Selling plans — subscriptions, when offered.
  • Inventory & pickup — stock levels and local pickup.
  • Structured data (SEO) — the page outputs machine‑readable product info for search engines.

Customization points & important notes

  • Build the page with blocks. Almost everything is a block — reorder/add/remove in the theme editor rather than editing code.
  • Colours respect light/dark mode and only apply when set; otherwise they inherit the theme defaults.
  • Editing styles: change src/styles/scss/sections/main-product.scss, not the compiled assets/main-product.css.
  • Performance: because assets load conditionally, removing unused blocks can make the page lighter.
  • This section expects to be on a product page (it uses the current product automatically). To feature a product elsewhere, use the Featured Product section instead.

Behind the scenes (for developers)

Root element. <product-info> (main-product.liquid:1-8) with data-section, data-product-id, data-url, and data-update-url="true". Driven by assets/product-info.js, which on variant change fetches the updated section HTML, updates price/media/inventory/quantity, and (because data-update-url is true) rewrites the browser URL/history.

Scoping & colours. section_id = 'main-product-section-id-' | append: section.id (main-product.liquid:9). The inline <style> block (main-product.liquid:10-416) emits CSS custom properties scoped to .{{ section_id }}, split into light (html:not(.dark-theme) …) and dark (.dark-theme …) selectors, and each colour is emitted only if the setting contains '#'. It also computes spacing/radius/alignment vars, sticky positioning, gallery/content gap padding, sticky‑bar visibility, and per‑block colour vars.

Conditional assets (main-product.liquid:418-442): always loads main-product.css, product-benefits.css, and product-info.js; conditionally loads gift-wrap.css (gift‑wrap block), pickup-availability.css/.js (pickup block), product-benefits-slider.js + splide-extension-auto-scroll.min.js (benefits block), and show-more.js (volume price breaks). Later: accordion.js (media/essentials present), product-essentials.js (essentials present), model-3d.js (3D media present).

Layout classes (main-product.liquid:444-483): a {% liquid %} block maps alignment and width settings to Tailwind class strings (desktop_media_width_class, desktop_info_width_class, etc.).

Block dispatch (main-product.liquid:494-1094): product_form_id = 'product-form-' | append: section.id, then a single {%- case block.type -%} renders each block, mostly delegating to snippets. Post‑loop (main-product.liquid:1098-1140) renders size‑chart/popup/essentials modals & drawers, the 3D‑model JSON (ProductJSON-<product.id>), structured data (product | structured_data), and the sticky bar.

Notable inline logic:

  • Price block (:532-653): size/weight via nested case, price snippet with use_variant: true, context: 'pdp', volume‑pricing note when product.quantity_price_breaks_configured?, tax/duty messaging, and an installment {% form 'product' %} emitting {{ form | payment_terms }}.
  • Quantity block (:723-942): cart | item_count_for_variant, quantity-input, <price-per-item> and <volume-pricing> from variant.quantity_price_breaks and quantity_rule.min/max/increment.
  • Rating block (:991-1028): reads product.metafields.reviews.rating(.value/.scale_max/.rating_count), computes a half‑star via modulo: 1, emits --rating, --rating-max, --rating-decimal.

Custom elements: <product-info> (root), <price-per-item>, <volume-pricing>, <show-more-button> (show-more.js); <variant-selects>/<media-gallery> live inside the rendered option/gallery snippets.

Schema notes: "tag": "section", "class": "section", no enabled_on/disabled_on/max_blocks, and "presets": [] (this section is template‑mapped, not preset‑insertable). ~35 block types are defined (@app + 34).

Last updated July 4, 2026

Let's talk