For the complete documentation index, see llms.txt. This page is also available as Markdown.
App functions
The application defines several functions to enable callbacks and customization everywhere.
* Calling functions correctly
To ensure the custom code always works, even if you uninstall the application, the added code will not affect the theme. This is very important!
// Always check if the application is installed before calling the app function.if(typeofGlobo!='undefined'&&typeofGlobo.Preorder!='undefined'){// code here}
Or you can also use try-catch blocks to wrap custom code to avoid exception errors.
try{// code here}catch (error) {}
1. Re-render in product page
In some cases, the app theme does not re-render after a variant change.
// after variant changed if(typeofGlobo!='undefined'&&typeofGlobo.Preorder!='undefined'){Globo.Preorder.initPreorder();}
2. Re-render in collection page
In some cases, the app theme does not re-render after collection filtering, sort, paginate
Suggest products in the footer, using this code similarly.
const chunkProducts = [
'id:"gid://shopify/Product/123"',
// ...,
'handle:"puma-runner"',
]
const products = await Globo.Preorder.searchProductByJson(chunkProducts)
if(products.length > 0){
// Push data to list product & re-render on collection page
const currentProductIds = new Set(
Globo.Preorder.settings.products.map(product => product.id)
);
const newProducts = products.filter(
product => product && !currentProductIds.has(product.id)
);
Globo.Preorder.settings.products.push(...newProducts);
Globo.Preorder.initCollection();
}
const profile = Globo.Preorder.getResolvedProfile(productJson, variantId);
if(!profile){
// The current product is not included any profile, or the profile status is draft.
} else if(profile && (typeof profile.isPreorder == 'undefined' || (!profile.isPreorder && (profile?.isComingSoon ?? false)))){
// profile is coming soon add to cart
} else {
// profile is pre-order and
if(!profile.isPreorder && profile.endedByCondition == 'date'){
// Product is ended preorder by date
} else if (!profile.isPreorder && profile.endedByCondition == 'quantity') {
// Product is ended preorder by quantity condition
} else if (!profile.isPreorder && profile.startCondition == 'date' ) {
// Product is preorder and coming soon preorder
} else if (!profile.isPreorder && (profile.startCondition == 'quantity' || profile.startCondition == 'stock')){
// Product is preorder and coming soon preorder
} else if (profile.isPreorder) {
// Product is preorder
}
}
const profile = Globo.Preorder.getResolvedProfile(productJson, variantId);
const message = profile.message;
// data message example
// {
// "preorderText": "Pre Order",
// "messageAboveText": "Don't miss out - Grab yours now before we sell out again!",
// "messageBellowText": "We will fulfill the item as soon as it becomes available",
// "naMessageText": "Not available for Pre order",
// "comingSoonText": "Coming soon",
// "comingSoonAddToCartText": "Coming soon",
// "soldoutText": "Sold out",
// "preorderLimitMessage": "Only :stock items left in stock",
// "outOfStockMessage": "Inventory level is :stock.It is less than you are trying to purchase. Some of the items will be pre-ordered. Continue?",
// "labelCountdownStart": "Coming soon",
// "labelCountdownEnd": "Pre-Order ending in",
// "labelCountdownDays": "Days",
// "labelCountdownHours": "Hours",
// "labelCountdownMinutes": "Minutes",
// "labelCountdownSeconds": "Second",
// "preorderBadge": "Pre Order",
// "preorderLabel": "Pre-order",
// "preorderedItemlabel": "Pre-order item",
// "preorderContactLink": "Reach out for more information →",
// "cartWarningTitle": "Warning: you have pre-order and in-stock in the same cart",
// "cartWarningContent": "Shipment of your in-stock items may be delayed until your pre-order item is ready for shipping.",
// "cartWarningCheckboxLabel": "Don't show this again",
// "partialPaymentLabel": "Payment option",
// "partialPaymentOptionFull": "Full Payment",
// "partialPaymentOptionPart": "Partial Payment",
// "preorderPrice": "PreOrder Price",
// "partialPaymentTitle": "Prepaid amount for {{product.title}} ({{variant.title}})",
// "cartWarningLimitMessage": "There are still :stock pre-order items that can be added to the cart",
// "cartWarningEndLimitMessage": "The number of products that can be pre-ordered has reached the limit",
// "cartWarningAlertMessage": "There are still :stock pre-order items that can be added to the cart. You can purchase up to :max products",
// "bisTextButton": "Email me when available",
// "bisTitleForm": "Email me when available",
// "bisHeaderContent": "Register your email address below to receive an email as soon as this becomes available again",
// "bisPlaceHolderEmail": "Enter your email",
// "bisSubscribeTextButton": "SUBSCRIBE",
// "bisFooterContent": "We will send you an email once the product becomes available. Your email address will not be shared with anyone else",
// "bisSubscribeSuccess": "Your notification has been registered",
// "bisSubscribeFail": "The email address you entered is invalid",
// "bisSubscribeRegistered": "Your email address is registered on this product",
// "bisSubscribeRequired": "The email address is required",
// "bisPhoneRegistered": "Your phone is registered on this product",
// "bisEmailAlertTitle": "Email",
// "bisSmsAlertTitle": "SMS",
// "partialPaymentSaveLavel": "Save",
// "emailPlaceholderBisForm": "Enter your email",
// "partialPaymentReleased": "You will be charged the remaining balance when the product is released on {{ released }}",
// "unsubscribeTitle": "<b>{{ email }}</b><br>will be unsubscribe from the <b>{{ shop_name }}</b> shop listings",
// "unsubscribeButton": "Unsubscribe",
// "unsubscribeSuccess": "You have successfully unsubscribed. Please re-register the product to receive notification",
// "unsubscribeProductUnsubscribed": "You have unsubscribed from this product"
// }