Home
Wiki
Home
Wiki
  1. 3. Reusables
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ShoppingListsButton
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Shipping
      • ShoppingLists
      • ShoppingListsNavbar
      • Toast
      • Users
      • VariantContent
      • WishlistButton
      • Services
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • Overview
        • theme.js
      • Css / Scss
        • Overview
        • ThemeClasses
    • 5. SDK
      • Overview
      • LiquidGlobals
      • ServicesSDK
  1. 3. Reusables

Shipping

Purpose#

The Shipping reusable renders the shipping carrier selection step in checkout. It lists available carriers, persists the selected shipping line to the checkout via the SDK, and (when a BoxNow carrier is available) integrates the BoxNow locker selection widget.

Where it's rendered#

This reusable is rendered from Components/Checkout/Default.liquid:
{% render 'Reusables\\Shipping\\Default', carriers: carriers %}

Inputs (Liquid render parameters)#

Liquid parameters#

carriers
Used only for optional informational text about free shipping thresholds (carriers.globalConfig.freeAtPrice/freeAtWeight).

Model shape (storefront example)#

Sanitized real storefront example (provided by the user) focusing on the fields used by this reusable.
Notes:
The reusable reads most runtime values from $store.checkout.data.shippingOptions (not from the carriers Liquid parameter).
This example includes both:
carriers (for globalConfig + the initial carrier list)
checkout.checkout (to show where shippingLine gets persisted)
{
  "status": "Start",
  "checkout": {
    "finalPrice": 168,
    "finalPriceText": "168,00 €",
    "shippingAddress": {
      "id": "Address Id",
      "firstName": "Sample text",
      "lastName": "Sample text",
      "phoneNumber": "Sample text",
      "address1": "Sample text",
      "city": "Sample text",
      "state": "Sample text",
      "country": "Sample text",
      "countryCode": "GR",
      "postalCode": "Sample text",
      "email": "sample@example.com"
    }
  },
  "carriers": {
    "globalConfig": {
      "freeAtPriceText": "Sample text",
      "freeAtWeightText": "Sample text"
    },
    "list": [
      {
        "carrierId": "Carrier Id",
        "carrierCode": "sample",
        "title": "Sample text",
        "type": "Manual",
        "totalAmount": 0,
        "totalAmountText": "0,00 €",
        "logo": {
          "id": "Image Id",
          "link": "https://example.com/sample"
        }
      },
      ...
    ]
  }
}

Required fields#

To render the list the template requires the checkout store to have:
$store.checkout.data.shippingOptions: array
Each entry is expected to expose:
carrier.id
carrier.type (or shippingLine.type) (used to detect BoxNow)
carrier.logo.link (optional)
shippingLine object with:
carrierId
carrierCode
title
type
netPrice
totalAmount, totalAmountText
vatLines
To display the “free shipping” hint text (optional), the Liquid param carriers should include:
carriers.globalConfig.freeAtPrice and/or carriers.globalConfig.freeAtWeight
carriers.globalConfig.freeAtPriceText and/or carriers.globalConfig.freeAtWeightText

Optional fields#

carrier.logo.link (when present, an image is rendered)
carrier.boxNowPartnerId (when present, sets window._bn_map_widget_config.partnerId for the BoxNow widget)

Template behavior (Liquid + Alpine)#

Mounted with:
x-data="shippingreusabledefault.initComponent(shippingBoxNowErrorMessage, shippingErrorMessage)"
Uses $store.checkout.canShowDetails('shipping') to decide whether to show the step details.
Renders a radio choice per carrier in $store.checkout.data.shippingOptions.
The @change handler calls selectShipping(carrier).
When the selected carrier is BoxNow:
Renders extra UI to show the selected locker name/title.
A button triggers the hidden BoxNow widget launcher (#boxnow-widget-trigger).
If any BoxNow carrier exists in shipping options, renders the BoxNow widget container and defines the global widget config:
window._bn_map_widget_config
dispatches boxnow:locker-selected with detail: selected.

JavaScript#

Global object#

Global object: shippingreusabledefault (in Reusables/Shipping/Default.js).
Factory:
initComponent(shippingBoxNowErrorMessage, shippingErrorMessage)

State (returned object)#

BoxNow state:
boxNowLockerId
boxNowLockerTitle
boxNowLockerName
boxNowError
_pendingBoxNowCarrier
_bn_widget_loaded
Selection state:
selectedCarrierId

Methods (nested inside initComponent)#

init()#

Listens for the global event boxnow:locker-selected:
copies the selected locker fields into boxNowLocker*
clears boxNowError
if _pendingBoxNowCarrier is set, calls submitBoxNowShipping(...)
Watches $store.checkout.data:
when data.shippingOptions becomes available
if any BoxNow carrier exists, sets the widget partnerId (when possible) and eagerly loads the widget script (_loadBoxNowWidgetScript()).

_loadBoxNowWidgetScript()#

Ensures the BoxNow widget script is loaded only once.
Injects:
https://widget-cdn.boxnow.gr/map-widget/client/v5.js

isBoxNowCarrier(carrier)#

Returns true when carrier.carrier.type (or carrier.shippingLine.type) equals "BoxNow".

isBoxNowCarrierActive()#

Returns true when any shippingOptions entry is a BoxNow carrier.

isCarrierSelected(carrier)#

Compares selectedCarrierId against carrier.carrier.id.

submitBoxNowShipping(carrier, shippingBoxNowErrorMessage)#

Persists the selected BoxNow carrier + locker details to checkout:
Builds a shippingLine payload including:
carrier fields (id/code/title/type/prices/vatLines)
boxNowLockerId, boxNowLockerTitle, boxNowLockerName
Calls:
servicesreusabledefault.updateCheckout(updatedCheckoutData, 'shipping')
On error:
shows a toast using shippingBoxNowErrorMessage
sets boxNowError = true
On success:
sets Alpine.store('checkout').steps['shipping'].valid = true

selectShipping(carrier)#

Persists the selected carrier to checkout.
Sets selectedCarrierId.
If carrier is BoxNow:
sets partnerId (when possible)
loads widget script
resets BoxNow locker state
sets _pendingBoxNowCarrier = carrier
marks shipping step invalid (steps.shipping.valid = false)
forces the current step to remain shipping
returns without calling the SDK until a locker is selected
If carrier is not BoxNow:
clears pending BoxNow state
builds a shippingLine payload (without locker fields)
calls servicesreusabledefault.updateCheckout(updatedCheckoutData, 'shipping')
on error: toast with shippingErrorMessage
on success:
marks step valid
triggers GA4 addShippingInfo with items from prepareItemsForCheckoutProcess(...).

Global Alpine stores#

This reusable uses:
$store.checkout
data.shippingOptions
steps.shipping.valid
isUpdating, isReady
canShowDetails(step)
currentStep
$store.toast
removeAll()
add(message, icon, type)

Services / API calls#

servicesreusabledefault.updateCheckout(updatedCheckoutData, 'shipping')

Dependencies#

Liquid: Reusables/Shipping/Default.liquid
JS: Reusables/Shipping/Default.js
Translations: Reusables/Shipping/Default.json
Render sites:
Components/Checkout/Default.liquid
Alpine stores:
$store.checkout
$store.toast
External:
BoxNow map widget (loaded dynamically when a BoxNow carrier is available)

Notes#

The actual list rendered comes from $store.checkout.data.shippingOptions; the Liquid carriers parameter is only used for the free-shipping informational text.
For BoxNow carriers, the shipping selection is a two-step process:
1.
user selects the carrier
2.
user selects a locker
Only then is updateCheckout(..., 'shipping') called.
The template’s radio input has both disabled and :disabled bindings; runtime behavior is controlled by :disabled="Alpine.store('checkout').isUpdating || !Alpine.store('checkout').isReady".
Modified at 2026-04-14 13:18:56
Previous
Register
Next
ShoppingLists
Built with