Zid Docs
AppsThemes
Payments
AppsThemes
Payments
Help Center
Slack
  1. Features
  • Getting Started
    • Introduction
    • Theme Development
    • Vitrin Changelog
    • Creating and Managing Theme Presets
    • Legacy Theme Migration
      • Store Settings Mapping
      • Moving to Vitrin Using LLMs
      • Twig to Jinja
      • Breaking Changes
  • Key Concepts
    • Architecture
    • Templates
      • Overview
      • Overridable Templates
      • Legacy Templates
      • Template Replacements
      • Templates Library
        • home.jinja
        • product.jinja
        • cart.jinja
        • category.jinja
        • products.jinja
        • categories.jinja
        • page.jinja
        • blogs.jinja
        • blog.jinja
        • faqs.jinja
        • reviews.jinja
        • questions.jinja
        • shipping_payment.jinja
        • 404_not_found.jinja
    • Settings
      • Schema files
      • Input Settings
      • Media Settings
      • Form Controls Settings
      • Products Settings
      • Additional Settings
      • Conditional Visibility
      • Migrating twig settings schema
    • Localization
      • localization (jinja v. twig)
    • Theme Editor
      • Overview
  • Building with Vitrin
    • Jinja Basics
    • Vitrin's Jinja Extensions
  • Vitrin CLI
    • Introduction
    • CLI Commands
  • Tips & Tricks
    • Performance
  • JS Integration
    • Supporting both Vitrin and Legacy themes
    • Responses & Errors
    • Cart
    • Products
    • Categories
    • Store
    • Account
    • Blogs
    • Options
    • Events
  • Features
    • SDK Popups – Integration Guidelines
    • Custom Styles Guide
    • Gift Card as a Popup
    • Addresses as a Popup
    • Login as a Popup
    • Checkout as a Popup
    • Apple Pay Quick Checkout
    • Region & Language Popup
    • Dynamic Bundle Products
    • Progressive Discounts
    • Customer Wallet & Cashback
    • Add Preorder Support to Your Theme
  • Mobile Apps
    • Scripts
  • API's
    • Authentication
      • Logout
      • Login Status
      • SMS Login
      • Verify SMS Login
      • WhatsApp Login
      • Verify WhatsApp Login
      • Email Login
      • Verify Email Login
      • Register
      • Register Guest
    • Products
      • List Products
      • Search Products
      • Calculate Product Options Price
      • Notify Product Stock Availability
      • Fetch Bundle Offers
      • Fetch Bundle Offers for a Product
      • List My Product Reviews
      • List Product Reviews
      • Create Product Review
      • Update Product Review
      • Delete Product Review
      • List Product Questions
      • Create Product Question
      • Get Product by Slug
      • Get Selection Groups
    • Categories
      • List Categories
    • Checkout
      • Get Cart
      • Remove Cart
      • Duplicate Cart
      • Add Cart Item
      • Empty Cart
      • Update Cart Item
      • Remove Cart Item
      • Upload Cart Input Field
      • Add Gift Card
      • Remove Gift Card
      • Apply Coupon
      • Remove Coupon From Cart
      • Check Coupon Validity
      • Apply Loyalty Points
      • Remove Loyalty Points
      • Preview Rewarded Points
      • List Redemption Methods for Cart
      • Customer’s Loyalty Wallet
      • Customer’s Current Points Balance
    • Account
      • Get Profile
      • Delete Account
      • Update Customer Profile
      • Get Addresses
      • Create an Address
      • Get an Address by ID
      • Update an Existing Address
      • Delete Address
      • Get Orders
      • Get Shareable Wishlist Link
      • Get Wishlist
      • Add Products to Wishlist
      • Remove Product from Wishlist
      • Get Address Form Schema
      • Check Product Purchase Status
    • Storefront
      • Store Scripts
      • Pages
      • Blogs
    • Countries
      • Get Countries
      • Get Cities By Country
  1. Features

Add Preorder Support to Your Theme

The Preorder Campaign feature allows merchants to sell selected products through a preorder flow before they are available through the normal purchase flow.
This guide explains how theme developers can update storefront templates to support preorder campaigns correctly.
The integration covers two storefront areas:
1.
Product details page
2.
Product cards
After completing this integration, preorder products can display:
A preorder badge
A countdown or release note component
A preorder specific button label
Correct availability behavior when the product or selected variant is preorderable

Before You Start#

Preorder configuration is managed by the merchant from the dashboard.
Path:
Products → Preorder Campaign → Create/Edit
preorder within product mwnu.png
The merchant can configure the following campaign details:
FieldPurpose
Campaign nameInternal name used to identify the preorder campaign.
Campaign periodStart and end dates for the preorder campaign.
Show/hide countdown timerControls whether the countdown timer appears on the storefront.
Order limitOptional maximum number of preorder units.
Stock behaviorControls whether preorder works only when in stock or also when out of stock.
Order statusInitial order status for preorder orders.
Cart mixingAllows or prevents mixing preorder products with normal products.
Badge text and messagingText displayed on the storefront.
ProductsProducts included in the preorder campaign.

Create_Edit Preorder Campaign full form.png
As a theme developer, you do not need to rebuild these settings in the theme. Your work is to read the preorder fields available on the product object and render the correct storefront behavior.

Integration Overview#

Preorder support has two main surfaces.

1. Product Details Page#

On the product details page, the theme should:
Detect whether the product has a preorder campaign
Detect whether the selected product can be preordered
Render the preorder badge
Render the preorder countdown or release note
Show the purchase button when preorder is available
Replace the regular add to cart label with Preorder now
Hide Buy Now for preorder products
Handle variant changes correctly

2. Product Cards#

On product cards, the theme should:
Detect whether the product has an active preorder campaign
Show the preorder badge
Replace the card button text with Preorder now
Avoid showing preorderable products as out of stock

Product Details Page Integration#

Product details page showing badge, countdown_release note, and Preorder now button.png
Use the following steps to update the product details page.

Step 1: Prepare the Preorder State#

At the top of the product details content, calculate the preorder state once.
This makes the rest of the template easier to maintain because the same variables can be reused for badges, buttons, stock behavior, and JavaScript handling.
{% if product %}
    {% set selected_product = selected_product if selected_product is defined else product.selected_product %}
    {% set preorder_campaign = product.effective_preorder_campaign %}
    {% set is_preorder = preorder_campaign is not none %}
    {% set can_preorder = product.can_be_preordered %}
    {% set preorder_stock_behavior = product.preorder_stock_behavior %}
    {% set can_buy = (selected_product and (selected_product.in_stock or can_preorder)) %}
    {% set add_to_cart_label = _("Preorder now") if is_preorder else _("add to cart") %}
{% else %}
    {% set preorder_campaign = none %}
    {% set is_preorder = false %}
    {% set can_preorder = false %}
    {% set preorder_stock_behavior = '' %}
    {% set can_buy = false %}
    {% set add_to_cart_label = _("add to cart") %}
{% endif %}

What These Variables Do#

VariableDescription
selected_productStores the currently selected product or variant. If selected_product already exists, it uses that value. Otherwise, it falls back to product.selected_product.
preorder_campaignStores the effective preorder campaign for the product.
is_preorderReturns true when the product has a preorder campaign.
can_preorderReturns whether the current product can be preordered.
preorder_stock_behaviorStores the stock behavior configured for the preorder campaign.
can_buyReturns whether the selected product can be bought through normal stock availability or preorder availability.
add_to_cart_labelSets the CTA label to Preorder now when preorder is active. Otherwise, it uses the normal add to cart label.
Use these variables throughout the product details template instead of repeating preorder checks in multiple places.

Step 2: Add Preorder Data Attributes to the Product Wrapper#

Expose the preorder state on the product wrapper so JavaScript can access it when product options or variants change.
<section class="product products-details-page"
         data-preorder-active="{{ 'true' if is_preorder else 'false' }}"
         data-preorder-available="{{ 'true' if can_preorder else 'false' }}"
         data-preorder-stock-behavior="{{ preorder_stock_behavior or '' }}">

Why This Is Needed#

When a customer changes a product option, the page needs to update the purchase state.
For example, the theme may need to decide whether to:
Show the product buttons
Hide the out of stock section
Change the button label to Preorder now
Show Option not available
The data attributes make preorder information available to the variant handling script.
Data AttributeValue
data-preorder-activetrue when the product has a preorder campaign.
data-preorder-availabletrue when the product can be preordered.
data-preorder-stock-behaviorContains the preorder stock behavior value.
[Screenshot placeholder: Add a screenshot of the product details page wrapper or storefront product page after preorder is active.]

Step 3: Render the Preorder Badge#

The preorder badge should be displayed when the product is part of a preorder campaign.
Badge text:release note fields.png
The badge text configured by the merchant is used by the preorder badge component. If no badge text is provided, the badge falls back to the translated Preorder label.
Place the preorder badge near the product title, usually after the regular product badge.
{% if product.badge %}
   {% include 'vitrin:products/badge.jinja' %}
{% endif %}

{% if is_preorder %}
    {% include 'vitrin:products/preorder_badge.jinja' %}
{% endif %}

Badge Display Logic#

The badge include handles the displayed label.
It renders:
product.preorder_campaign.badge_text when badge text is available
The translated Preorder label when badge text is not available
[Screenshot placeholder: Add a screenshot showing the preorder badge near the product title.]

Step 4: Render the Countdown and Release Note#

Add the preorder countdown component near the product purchase information.
Recommended placement areas include:
Near the price
Near payment widgets
Above the product action buttons
Near other purchase decision information
<div>
    {% include 'vitrin:products/preorder_countdown.jinja' %}
</div>

Component Visibility#

You only need to include the component. The visibility conditions are handled inside the kit.
The component renders only when the product has a preorder campaign and either:
product.preorder_campaign.show_countdown is enabled
product.preorder_campaign.release_note has content
When countdown is enabled and the campaign has a valid end_date, the SDK shows:
Days
Hours
Minutes
When a release note exists, it appears as a note inside the same card.
[Screenshot placeholder: Add a screenshot showing the preorder countdown or release note component.]

Step 5: Update Out of Stock and Button Visibility#

A preorderable product should not be treated as unavailable only because the selected product is out of stock.
Use can_buy and can_preorder to decide whether the out of stock section or product buttons should appear.
<div class="section-out-of-stock-notify-me {% if not can_buy %}d-block{% else %}d-none{% endif %}">
    ...
</div>

<div class="product-buttons {% if can_preorder or product.selected_product.in_stock %}d-block{% else %}d-none{% endif %}">
    ...
</div>

Expected Behavior#

ConditionExpected Storefront Behavior
Selected product is in stockShow product buttons.
Selected product can be preorderedShow product buttons.
Selected product is not in stock and cannot be preorderedShow out of stock state.
This prevents preorderable products from incorrectly showing only the out of stock or notify me section.

Step 6: Change the Add to Cart Button Label#

Use the preorder label when the product has an active preorder campaign.
<button class="btn btn-add-to-cart" type="button" onclick="productAddToCart()">
    <span>
        {{ add_to_cart_label }}
    </span>
</button>
The add_to_cart_label variable was prepared earlier.
{% set add_to_cart_label = _("Preorder now") if is_preorder else _("add to cart") %}

Expected Label#

Product StateButton Label
Normal productadd to cart
Preorder productPreorder now
[Screenshot placeholder: Add a screenshot showing the Preorder now CTA on the product details page.]

Step 7: Hide Buy Now for Preorder Products#

For preorder campaigns, the flow should use the preorder CTA only.
Hide the Buy Now button when is_preorder is true.
{% if not safeget(store, 'settings.general.availability.closed_now') and not is_preorder %}
    <button class="btn btn-buy-now d-none" type="button" onclick="zidProductBuyNow()">
        ...
    </button>
{% endif %}

Expected Behavior#

Product TypeAdd to Cart CTABuy Now CTA
Normal productShow normal add to cart CTACan be shown based on theme logic
Preorder productShow Preorder nowHidden

Variant Handling#

If the product has variants, the theme should update the purchase state when the selected variant changes.
The logic should check both:
Variant stock
Preorder availability
Use the preorder data attributes added to the product wrapper.

How the Variant Logic Works#

The function follows this flow:
1.
Selects the product details wrapper.
2.
Reads preorder data from the wrapper dataset.
3.
Checks whether preorder is active.
4.
Checks whether preorder is available.
5.
Reads the stock behavior value.
6.
Checks whether the selected product is buyable.
7.
Shows or hides product buttons.
8.
Shows or hides the out of stock notify section.
9.
Updates the add to cart button label.

Stock Behavior Handling in Variants#

The stock behavior affects how the selected variant should be treated.

Behavior Explanation#

Stock BehaviorLogic
IN_STOCK_ONLYThe selected product must be in stock.
Other preorder behaviorThe selected product can be buyable if it is in stock or preorder is available.
This ensures that the selected variant follows the preorder campaign stock behavior.
[Screenshot placeholder: Add a screenshot or GIF showing variant selection and CTA behavior.]

Preorder Product Fields#

The following fields are available for preorder integration.
FieldMeaning
product.preorder_campaignCampaign directly attached to the product. Use this to render the badge and countdown.
product.effective_preorder_campaignCampaign from the product or its parent. Useful on product cards and variants.
product.preorder_stock_behaviorCampaign stock rule. Current values include IN_STOCK_ONLY and OUT_OF_STOCK_ONLY.
product.can_be_preorderedFinal theme safe flag for whether the selected product can be preordered. It considers slots, stock behavior, and selected variant stock.
product.preorder_slots_availableTrue when a campaign slot exists and is not exhausted.

Field Usage Guide#

Use the fields based on the type of decision you are making.
DecisionRecommended Field
Show preorder badgeproduct.preorder_campaign or product.effective_preorder_campaign
Show countdown or release noteproduct.preorder_campaign
Decide if the product button should be visibleproduct.can_be_preordered
Decide if product card should show out of stock stateproduct.can_be_preordered
Read preorder stock behaviorproduct.preorder_stock_behavior
Check preorder slot availabilityproduct.preorder_slots_available

Important Rule#

Use:
product.can_be_preordered
for button visibility and availability decisions.
Use:
product.preorder_campaign
or:
product.effective_preorder_campaign
for display decisions such as badges, countdowns, and preorder labels.

Product Card Integration#

product card.png
Product cards need a smaller preorder integration than the product details page.
The card should know whether the product is preorderable and whether the normal out of stock state should be shown.

Step 1: Prepare Product Card Preorder State#

Add the preorder state inside the product card template.
{% set preorder_campaign = product.effective_preorder_campaign %}
{% set is_preorder = preorder_campaign is not none %}
{% set can_preorder = product.can_be_preordered %}
{% set product_card_cta = _("Preorder now") if is_preorder else _("add to cart") %}

{% set is_out_of_stock = (product.is_infinite == false and product.quantity <= 0) and not can_preorder %}

What This Does#

VariableDescription
preorder_campaignStores the effective preorder campaign for the product card.
is_preorderChecks whether the product has a preorder campaign.
can_preorderChecks whether the product can be preordered.
product_card_ctaSets the product card button text.
is_out_of_stockChecks whether the product should be shown as out of stock.
The important part is:
and not can_preorder
This prevents a preorderable product from being shown as out of stock on the product card.

Step 2: Render the Product Card Badge#

Render the preorder badge inside the product card.
You can place it where it fits your theme layout, such as:
Near the product title
Near the price
In the product card footer
Above the product card button
{% if is_preorder %}
  <div style="margin-bottom: 8px; text-align: start;">
      {% set preorder_badge_variant = 'product_card' %}
      {% include 'vitrin:products/preorder_badge.jinja' %}
  </div>
{% endif %}
The preorder_badge_variant line is only needed because the shared badge include supports more than one visual variant.
If your theme uses one badge style everywhere, you can omit the variant and include the badge directly.
{% if is_preorder %}
    {% include 'vitrin:products/preorder_badge.jinja' %}
{% endif %}
[Screenshot placeholder: Add a screenshot showing the preorder badge on a product card.]

Step 3: Update the Product Card CTA#

Use product_card_cta for the product card action label.
{% if is_out_of_stock %}
    <a href="/products/{{ product.slug }}" class="btn btn-primary btn-product-card-out-of-stock">
        <span>{{ _("Notify me when available") }}</span>
    </a>
{% elif (product.has_options or product.has_fields or product.product_class == 'dynamic_bundle') %}
    <a class="btn btn-primary btn-product-card-select-variant" href="/products/{{ product.slug }}">
        {{ product_card_cta }}
    </a>
{% else %}
    <a class="btn btn-primary product-card-add-to-cart" onclick="event.preventDefault(); event.stopPropagation(); productCartAddToCart(this,'{{ product.id }}')">
        {{ product_card_cta }}
    </a>
{% endif %}

CTA Behavior#

Product ConditionExpected CTA
Product is out of stock and cannot be preorderedNotify me when available
Product has options, fields, or is a dynamic bundleLink to product details page with Preorder now or add to cart label
Product can be added directly from the cardAdd product to cart with Preorder now or add to cart label
[Screenshot placeholder: Add a screenshot showing the Preorder now CTA on a product card.]

Badge Styling#

The following CSS is the Vitrin default badge style.
This CSS is not required as is. Use it as a starting point and adjust it to match the theme design.

Styling Notes#

You can customize:
padding
border-radius
font-weight
background-color
color
margin-bottom
For product cards, the class below provides a separate badge style:
Use this class if the product card badge needs different spacing or radius from the product details badge.
[Screenshot placeholder: Add a screenshot showing the preorder badge styling on product details page and product card.]

Countdown Customization#

The countdown is a Zid SDK component.
The component key is:
If the theme uses the Zid SDK Custom Styles system, register customization under this key.
For complete Custom Styles documentation, see the Custom Styles Guide for Theme Developers:
https://docs.zid.sa/custom-styles-guide-1702191m0
[Screenshot placeholder: Add a screenshot showing the countdown component after styling customization.]

Translations#

Add these translation keys to the theme locale files if they are not already available.
msgid "Preorder"
msgstr "الطلب المسبق"

msgid "Preorder now"
msgstr "اطلب مسبقاً"

Translation Usage#

Translation KeyUsed For
PreorderDefault preorder badge text
Preorder nowProduct details page and product card CTA
Make sure the keys are available in all supported theme languages.

Implementation Checklist#

Use this checklist to confirm that preorder support has been added correctly.

Product Details Page#

Preorder state is prepared at the top of the product details template.
Product wrapper includes preorder data attributes.
Preorder badge is rendered when preorder is active.
Countdown and release note component is included.
Out of stock section uses can_buy.
Product buttons stay visible when can_preorder is true.
Add to cart label uses add_to_cart_label.
Buy Now button is hidden when is_preorder is true.
Variant handling checks stock and preorder availability.
Variant handling updates button visibility and label.

Product Cards#

Product card uses product.effective_preorder_campaign.
Product card uses product.can_be_preordered.
Out of stock state excludes preorderable products.
Preorder badge is rendered on product cards.
Product card CTA uses product_card_cta.
Product cards with options, fields, or dynamic bundles link to the product details page.
Direct add to cart product cards use the preorder CTA when preorder is active.

Styling and Localization#

Preorder badge style matches the theme.
Product card badge spacing works correctly.
Countdown component appears correctly when enabled.
Release note appears when provided.
Preorder translation key is added.
Preorder now translation key is added.

Final Expected Behavior#

After completing the integration:
Products with an active preorder campaign show a preorder badge.
Products with countdown enabled show the countdown component.
Products with a release note show the release note inside the countdown component.
Product details page CTA changes from add to cart to Preorder now.
Product card CTA changes from add to cart to Preorder now.
Preorderable products are not incorrectly shown as out of stock.
Variant selection updates the product availability state correctly.
Buy Now is hidden for preorder products.
Theme translations support preorder labels in English and Arabic.
Modified at 2026-05-11 08:37:30
Previous
Customer Wallet & Cashback
Next
Scripts
Built with