Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 21 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Horizon

[B2B Assessment](#b2b-moq-technical-assessment) |
[Getting started](#getting-started) |
[Staying up to date with Horizon changes](#staying-up-to-date-with-horizon-changes) |
[Developer tools](#developer-tools) |
Expand All @@ -13,80 +14,34 @@ Horizon is the flagship of a new generation of first party Shopify themes. It in
- **Server-rendered:** HTML must be rendered by Shopify servers using Liquid. Business logic and platform primitives such as translations and money formatting don’t belong on the client. Async and on-demand rendering of parts of the page is OK, but we do it sparingly as a progressive enhancement.
- **Functional, not pixel-perfect:** The Web doesn’t require each page to be rendered pixel-perfect by each browser engine. Using semantic markup, progressive enhancement, and clever design, we ensure that themes remain functional regardless of the browser.

## Getting started

We recommend using the Skeleton Theme as a starting point for a theme development project. [Learn more on Shopify.dev](https://shopify.dev/themes/getting-started/create).

To create a new theme project based on Horizon:

```sh
git clone https://github.com/Shopify/horizon.git
```

Install the [Shopify CLI](https://shopify.dev/docs/storefronts/themes/tools/cli) to connect your local project to a Shopify store. Learn about the [theme developer tools](https://shopify.dev/docs/storefronts/themes/tools) available, and the suggested [developer tools](#developer-tools) below.
---

Please note that the `main` branch may include code for features not yet released. You may encounter Liquid API properties that are not publicly documented, but will be when the feature is officially rolled out.
## 🛠 B2B MOQ Technical Assessment

### Shopify Theme Store development
This fork includes the implementation for the **B2B Minimum Order Quantity (MOQ)** technical exercise.

If you're building a theme for the Shopify Theme Store, then do not use Horizon as a starting point. Themes based on, derived from, or incorporating Horizon are not eligible for submission to to the Shopify Theme Store. Use the [Skeleton Theme](https://github.com/Shopify/skeleton-theme) instead.
**Business Rules Implemented:**
* B2B customers must purchase at least 6 items (using a default fallback of 6 if the `shop.metafields.custom.b2b_moq` is empty).
* B2C customers have no minimum requirement.

## Staying up to date with Horizon changes
### How to Test This Feature
1. Connect to your development store: `shopify theme dev`
2. Create a test customer account on the storefront.
3. In the Shopify Admin, assign the tag `b2b` to this customer profile.
4. Log in as this customer on the storefront and navigate to the cart:
* **If cart has < 6 items:** A red error banner is displayed, and the Checkout button is physically disabled.
* **If cart has >= 6 items:** The banner disappears, and the Checkout button functions normally.
5. Log out or browse as a standard B2C customer to verify no restrictions apply.

Say you're building a new theme off Horizon but you still want to be able to pull in the latest changes, you can add a remote `upstream` pointing to this Horizon repository.
*Note: Please see the Pull Request description for my Loom video walkthrough and a brief architectural explanation regarding theme-level validation vs. Shopify Plus checkout extensibility.*

1. Navigate to your local theme folder.
2. Verify the list of remotes and validate that you have both an `origin` and `upstream`:
---

```sh
git remote -v
```

3. If you don't see an `upstream`, you can add one that points to Shopify's Horizon repository:
## Getting started

```sh
git remote add upstream https://github.com/Shopify/horizon.git
```
We recommend using the Skeleton Theme as a starting point for a theme development project. [Learn more on Shopify.dev](https://shopify.dev/themes/getting-started/create).

4. Pull in the latest Horizon changes into your repository:
To create a new theme project based on Horizon:

```sh
git fetch upstream
git pull upstream main
```

## Developer tools

There are a number of really useful tools that the Shopify Themes team uses during development. Horizon is already set up to work with these tools.

### Shopify CLI

[Shopify CLI](https://shopify.dev/docs/storefronts/themes/tools/cli) helps you build Shopify themes faster and is used to automate and enhance your local development workflow. It comes bundled with a suite of commands for developing Shopify themes—everything from working with themes on a Shopify store (e.g. creating, publishing, deleting themes) or launching a development server for local theme development.

You can follow this [quick start guide for theme developers](https://shopify.dev/docs/themes/tools/cli) to get started.

### Theme Check

We recommend using [Theme Check](https://github.com/shopify/theme-check) as a way to validate and lint your Shopify themes.

We've added Theme Check to Horizon's [list of VS Code extensions](/.vscode/extensions.json) so if you're using Visual Studio Code as your code editor of choice, you'll be prompted to install the [Theme Check VS Code](https://marketplace.visualstudio.com/items?itemName=Shopify.theme-check-vscode) extension upon opening VS Code after you've forked and cloned Horizon.

You can also run it from a terminal with the following Shopify CLI command:

```bash
shopify theme check
```

You can follow the [theme check documentation](https://shopify.dev/docs/storefronts/themes/tools/theme-check) for more details.

#### Shopify/theme-check-action

Horizon runs [Theme Check](#Theme-Check) on every commit via [Shopify/theme-check-action](https://github.com/Shopify/theme-check-action).

## Contributing

We are not accepting contributions to Horizon at this time.

## License

Copyright (c) 2025-present Shopify Inc. See [LICENSE](/LICENSE.md) for further details.
git clone [https://github.com/Shopify/horizon.git](https://github.com/Shopify/horizon.git)
28 changes: 27 additions & 1 deletion sections/main-cart.liquid
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
{% liquid
# Code for Detecting B2B Customer
assign is_b2b = false
if customer and customer.tags contains 'b2b'
assign is_b2b = true
endif

# Metafield with fallback
assign moq = shop.metafields.custom.b2b_moq.value | default: 6 | plus: 0
assign cart_qty = cart.item_count

# Logic
assign blocks_checkout = false
if is_b2b and cart_qty < moq
assign blocks_checkout = true
endif
%}

{% capture cart_page_more_blocks_content %}
<div class="cart-page__more-blocks">
{%- content_for 'blocks' -%}
Expand Down Expand Up @@ -47,6 +65,14 @@

{%- unless cart.empty? -%}
<div class="cart-page__summary">

{%- comment -%} B2B MOQ Error Banner Injected Here {%- endcomment -%}
{% if blocks_checkout %}
<div class="cart-error-banner" style="color: #721c24; background-color: #f8d7da; border: 1px solid #f5c6cb; padding: 12px; margin-bottom: 15px; border-radius: 4px;">
<strong>Minimum Order Requirement:</strong> As a B2B customer, you must purchase at least {{ moq }} items. You currently have {{ cart_qty }}.
</div>
{% endif %}

{%- content_for 'block', id: 'cart-page-summary', type: '_cart-summary' -%}
</div>
{%- endunless -%}
Expand Down Expand Up @@ -235,4 +261,4 @@
}
]
}
{% endschema %}
{% endschema %}
27 changes: 25 additions & 2 deletions snippets/cart-summary.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
@param {string} [section_id] - The section ID for cart discount component.
{%- enddoc -%}

{% liquid
assign is_b2b = false
if customer.tags contains 'b2b'
assign is_b2b = true
endif

assign b2b_moq = shop.metafields.custom.b2b_moq.value | default: 6 | plus: 0
assign moq_not_met = false

if is_b2b and cart.item_count < b2b_moq
assign moq_not_met = true
endif
%}

<div class="cart-totals">
{% # We need to keep this node in place to allow morphing to work properly # %}
<div class="cart-totals__original-container cart-primary-typography">
Expand Down Expand Up @@ -254,12 +268,21 @@
</div>

<div class="cart__ctas">
{% if moq_not_met %}
<div class="cart-error-banner form-message--error" role="alert" style="display: flex; align-items: center; gap: var(--gap-xs); padding: var(--padding-sm); background-color: var(--color-error-background, #fff0f0); border: 1px solid var(--color-error, #d20000); border-radius: var(--border-radius); color: var(--color-error, #d20000); margin-bottom: var(--margin-md);">
<span class="svg-wrapper" style="width: var(--icon-size-sm); height: var(--icon-size-sm); flex-shrink: 0;">
{{- 'icon-error.svg' | inline_asset_content -}}
</span>
<p style="margin: 0; font-size: var(--font-size--sm);">B2B customers must purchase at least {{ b2b_moq }} items. You currently have {{ cart.item_count }} item{% if cart.item_count != 1 %}s{% endif %}.</p>
</div>
{% endif %}

<button
type="submit"
id="checkout"
class="cart__checkout-button button"
name="checkout"
{% if cart == empty %}
{% if cart == empty or moq_not_met %}
disabled
{% endif %}
form="cart-form"
Expand All @@ -269,7 +292,7 @@
</span>
</button>

{% if additional_checkout_buttons and settings.show_accelerated_checkout_buttons %}
{% if additional_checkout_buttons and settings.show_accelerated_checkout_buttons and moq_not_met == false %}
<div
class="
additional-checkout-buttons
Expand Down