xt":"Save {{ discount }}","shopify_selling_plan_id":713071886719,"is_default":true,"type":"full","translations":{}}],"require_preorder_acknowledgement":false,"preorder_acknowledgement_text":"I acknowledge and agree to the preorder terms and conditions for this product.","disable_button_until_acknowledged":false,"preorder_min_quantity":null,"preorder_max_quantity":null,"countdown_timer_enabled":false,"countdown_timer_style":"text","countdown_timer_text_color":"#000000","countdown_timer_background_color":"#f5f5f5","countdown_timer_border_radius":8,"countdown_timer_format":"DHMS","countdown_timer_use_schedule_dates":true,"countdown_timer_custom_start_date":null,"countdown_timer_custom_end_date":null,"countdown_timer_starts_text":null,"countdown_timer_ends_text":null,"schedule_offer":false,"schedule_start_date":null,"schedule_end_date":null,"updated_at":"2025-08-19T10:05:43.042Z","allow_mixed_cart":true,"mixed_cart_error_message":"Preorders must be purchased separately from regular items. Please complete your cur226,45828849696994,45828849729762,45828849762530,45828849795298,45828849828066,45828849860834,45828849893602,45828849926370,45828849959138,45828849991906,45828850024674,45828850057442,45828850090210,45828850122978,45828850155746,45828850188514,45828850221282,45828850254050,45828850286818,45828873814242,45828873847010,45828873879778,45828873912546,45828873945314,45828873978082,45828874010850,45828874043618,45828886429922,45828886462690,45828886495458,45828886528226,45828894621922,45828894654690,45828894687458,45828941611234,45828941644002,45828941676770,45828941709538,45828941742306,45828974051554,45829018910946,45829033558242,45829033623778,45829052432610,45830783205602,45830783238370,45830795133154,45830795198690,45830795231458,45830795264226,45830795329762,45830795362530,45843552108770,45843552141538,45843552174306,45843552207074,45843552239842,45843552272610,45843552338146,45843552403682,45843552436450,45843552469218,45843590643938,45843590676706,45843590709474,45843590742242,45843615514850,45843615547618,
91391]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Small \/ Grey","public_title":"Small \/ Grey","options":["Small","Grey"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739634250111,"position":3,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_99f6a697-f15e-499c-92e4-19e7c8e6cbb5.webp?v=1741953624"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196411429247,"title":"Medium \/ Blue","option1":"Medium","option2":"Blue","option3":null,"sku":"YCB25167CMDPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358292447615,"product_id":14979885662591,"position":1,"created_at":"2025-03-14T12:00:24+00:00","updated_at":"2025-03-14T12:00:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/"preorder_button_description_shipping_text_prefix":"Shipping: ","delivery_exact_time":null,"delivery_after_n_intervals":null,"delivery_at":"2025-07-26T09:20:18.169Z","delivery_type":"asap","quantity_limit_text":"{{ quantity }} units available for preorder","preorder_button_description_show_shipping":true,"preorder_button_description_icons_enabled":true,"preorder_shipping_text":"Shipping: {{ date }}","shipping_applies_to_all_products":true,"shipping_text":"Estimated to ship within 2 months","payment_type":"full","billing_checkout_charge_type":"percentage","billing_checkout_charge_amount":null,"billing_checkout_charge_percentage":"100.0","pricing_type":"no_discount","pricing_amount":null,"pricing_percentage":null,"discount_text":"Save {{ discount }}","billing_title":"Full payment","billing_description":null,"enable_billing_widget":false,"inventory_provider":"stoq","preorder_badge_enabled":false,"preorder_badge_text":"Preorder","preorder_badge_text_color":"#FFFFFF","preorder_badge_background_color":"#000000","pr
:00:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_c057f993-2205-47da-b027-208f8ea2e99b.webp?v=1741953624","variant_ids":[55196411363711,55196411462015,55196411560319,55196411658623]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Medium \/ Black","public_title":"Medium \/ Black","options":["Medium","Black"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739634217343,"position":2,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_c057f993-2205-47da-b027-208f8ea2e99b.webp?v=1741953624"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196411494783,"title":"Medium \/ Grey","option1":"Medium","option2":"Grey","option3":null,"sku":"YCB25167CXLRGGDHC028701","requires_shipping":true,"tdgement":false,"preorder_acknowledgement_text":"I acknowledge and agree to the preorder terms and conditions for this product.","disable_button_until_acknowledged":false,"preorder_min_quantity":null,"preorder_max_quantity":null,"countdown_timer_enabled":false,"countdown_timer_style":"text","countdown_timer_text_color":"#000000","countdown_timer_background_color":"#f5f5f5","countdown_timer_border_radius":8,"countdown_timer_format":"DHMS","countdown_timer_use_schedule_dates":true,"countdown_timer_custom_start_date":null,"countdown_timer_custom_end_date":null,"countdown_timer_starts_text":null,"countdown_timer_ends_text":null,"schedule_offer":false,"schedule_start_date":null,"schedule_end_date":null,"updated_at":"2025-08-19T10:05:43.042Z","allow_mixed_cart":true,"mixed_cart_error_message":"Preorders must be purchased separately from regular items. Please complete your current order first, or clear your cart to continue.","b2b_enabled":true,"preorder_progress_bar_enabled":false,"preorder_progress_bar_text":"{{ so,{"id":55196411527551,"title":"Large \/ Blue","option1":"Large","option2":"Blue","option3":null,"sku":"YCB25167CLGPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358292447615,"product_id":14979885662591,"position":1,"created_at":"2025-03-14T12:00:24+00:00","updated_at":"2025-03-14T12:00:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1.webp?v=1741953624","variant_ids":[55196411330943,55196411429247,55196411527551,55196411625855]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Large \/ Blue","public_title":"Large \/ Blue","options":["Large","Blue"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739634184575,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1.webp?v=1741953624"}},"requires_selling_plan":false,"se_suffix":" units available for preorder","preorder_button_description_shipping_text_prefix":"Shipping: ","delivery_exact_time":null,"delivery_after_n_intervals":null,"delivery_at":"2025-07-26T09:20:18.169Z","delivery_type":"asap","quantity_limit_text":"{{ quantity }} units available for preorder","preorder_button_description_show_shipping":true,"preorder_button_description_icons_enabled":true,"preorder_shipping_text":"Shipping: {{ date }}","shipping_applies_to_all_products":true,"shipping_text":"Estimated to ship within 2 months","payment_type":"full","billing_checkout_charge_type":"percentage","billing_checkout_charge_amount":null,"billing_checkout_charge_percentage":"100.0","pricing_type":"no_discount","pricing_amount":null,"pricing_percentage":null,"discount_text":"Save {{ discount }}","billing_title":"Full payment","billing_description":null,"enable_billing_widget":false,"inventory_provider":"stoq","preorder_badge_enabled":false,"preorder_badge_text":"Preorder","preorder_badge_text_color":"#FFFFFF","preor
7,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_c057f993-2205-47da-b027-208f8ea2e99b.webp?v=1741953624"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196411593087,"title":"Large \/ Grey","option1":"Large","option2":"Grey","option3":null,"sku":"YCB25167CXLRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358292545919,"product_id":14979885662591,"position":3,"created_at":"2025-03-14T12:00:24+00:00","updated_at":"2025-03-14T12:00:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_99f6a697-f15e-499c-92e4-19e7c8e6cbb5.webp?v=1741953624","variant_ids":[55196411396479,55196411494783,55196411593087,55196411691391]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Large \/ Grey","public_title":"Large \/ Grey","options":["Large","Grey"],"price":679900,"weight":0,"compare_at_price":null,"inventory_managemeslations":{}}],"require_preorder_acknowledgement":false,"preorder_acknowledgement_text":"I acknowledge and agree to the preorder terms and conditions for this product.","disable_button_until_acknowledged":false,"preorder_min_quantity":null,"preorder_max_quantity":null,"countdown_timer_enabled":false,"countdown_timer_style":"text","countdown_timer_text_color":"#000000","countdown_timer_background_color":"#f5f5f5","countdown_timer_border_radius":8,"countdown_timer_format":"DHMS","countdown_timer_use_schedule_dates":true,"countdown_timer_custom_start_date":null,"countdown_timer_custom_end_date":null,"countdown_timer_starts_text":null,"countdown_timer_ends_text":null,"schedule_offer":false,"schedule_start_date":null,"schedule_end_date":null,"updated_at":"2025-08-19T10:05:43.042Z","allow_mixed_cart":true,"mixed_cart_error_message":"Preorders must be purchased separately from regular items. Please complete your current order first, or clear your cart to continue.","b2b_enabled":true,"preorder_progress_bar_enabled":Blue","public_title":"Extra Large \/ Blue","options":["Extra Large","Blue"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739634184575,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1.webp?v=1741953624"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196411658623,"title":"Extra Large \/ Black","option1":"Extra Large","option2":"Black","option3":null,"sku":"YCB25167CLGRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358292513151,"product_id":14979885662591,"position":2,"created_at":"2025-03-14T12:00:24+00:00","updated_at":"2025-03-14T12:00:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_1_c057f993-2205-47da-b027-208f8ea2e99b.webp?v=1741953624","variant_ids":[55196411363711,& !isNaN(planDate) && planDate > maxDate)) ? plan.updated_at : max;
}
return max;
}, '')
: null;
// Use cached if old array is empty/has no timestamps, or cached is newer
// Parse dates for comparison to handle format differences (+00:00 vs .000Z)
const cachedDate = new Date(cachedData.cached_at);
const maxDate = maxUpdatedAt ? new Date(maxUpdatedAt) : null;
const useCached = !maxUpdatedAt || (cachedDate && !isNaN(cachedDate) && (!maxDate || cachedDate > maxDate));
if (useCached) {
if (Array.isArray(cachedData.plans)) {
window._RestockRocketConfig.sellingPlans = cachedData.plans;
// Only use disabled_plan_ids when using cached plans
window._RestockRocketConfig.disabledSellingPlanIds = cachedData.disabled_plan_ids || [];
console.debug('[RR] Using selling plans from cachedSellingPlans (cached_at: ' + cachedData.cached_at + ')');
}
} else
kRocketConfig.obfuscateInventoryQuantity = false;window._RestockRocketConfig.product = {"id":14979885662591,"title":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike","handle":"yeti-cycles-sb165-c-series-c2-factory-29-27-5-bike","description":"\u003cdiv data-content-type=\"html\" data-appearance=\"default\" data-element=\"main\" data-decoded=\"true\"\u003e\n\u003cdiv class=\"Yeti-Text_Intro-BG\"\u003e\n\u003cdiv class=\"Yeti-Text_Intro-Text\"\u003e\n\u003cp\u003eWe said it already knows. And now it knows better. Proven worthy time and again at Rampage, reconfigured to fit the bill as Zero-Hesitation Go-To for whatever your pleasure. Un-rack it for all the park laps, pedal it on character-building epics, push it up spooky steep darksides “nobody†knows about. Whatever the question, unhard your decisions.\u003cspan\u003e \u003c\/span\u003e\u003cspan\u003eYOU ASK. IT GIVES.\u003c\/span\u003e.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Feature-Box-BG\"\3e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e63.5°\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eHEAD TUBE ANGLE\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e76.9°\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eEFF. SEAT ANGLE\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Highlights-BG_165MX\"\u003e\n\u003cdiv class=\"Yeti-Text_Highlights-Text\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eHIGHLIGHTS\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eFox Factory 38 Grip 2 and Fox Factory DHX2 shock\u003c\/li\u003e\n\u003cli\u003eFox Transfer dropper post\u003c\/li\u003e\n\u003cli\u003eMX DT Swiss EX1700 custom wheelset\u003c\/li\u003e\n\u003cli\u003e4 piston brakes\u003c\/li\u003e\n\
ocketConfig;
var _sqPlanEnabled = Array.isArray(_sqCfg.sellingPlans) &&
_sqCfg.sellingPlans.some(function (p) { return p && p.enabled; });
var _sqPreCount = ((_sqCfg.cachedPreorderVariantIds &&
_sqCfg.cachedPreorderVariantIds.preorder_variant_ids) || []).length;
_sqCfg.preordersConfigured = !!(_sqPlanEnabled && _sqPreCount);
} catch (e) { /* fail open */ }
// STOQ-1612: block (not hide) Buy Now / Shop Pay until our JS runs, so a tap in the
// load window can't bypass preorder. pointer-events via .stoq-buy-now-pending (no
// reflow); timeout releases; renderPreorderButton / featured_product.js lift it.
// Gated by the `block_accelerated_checkout` toggle (default OFF) for gradual rollout.
// Armed ONLY when we're sure preorder is in play — product page: THIS product has a
// preorder variant (never block a plain product's Shop Pay); featured: integration
// enabled for this page type. Rationale: PR #2784.
try {
var _sqc = window._RestockRocketConfig;
var _sqO
Zambia (GBP£)
*/ }
window._RestockRocketConfig.scriptUrlProduct = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection.js'
window._RestockRocketConfig.scriptUrlProductBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product-bis.js'
window._RestockRocketConfig.scriptUrlCollectionBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection-bis.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when pr
<
<
Zimbabwe (USD$)
che age
if (!liquidRenderedAt || typeof liquidRenderedAt !== 'number' || isNaN(liquidRenderedAt)) {
console.debug('STOQ - Invalid or missing liquidRenderedAt timestamp, assuming fresh');
window._RestockRocketConfig.isLiquidCacheFresh = true;
window._RestockRocketConfig.liquidCacheAge = null;
} else {
const now = Math.floor(Date.now() / 1000); // Current time in seconds
const liquidCacheAge = now - liquidRenderedAt; // Age in seconds
// Surfaced into funnel events: a stale cache means the app rendered with
// outdated inventory/selling-plan data — a real "had the opportunity but
// failed" cause. Negative (client clock ahead) clamps to 0.
window._RestockRocketConfig.liquidCacheAge = Math.max(0, liquidCacheAge);
// Handle client clock ahead of server
if (liquidCacheAge
0) {
console.debug(`STOQ - Client clock appears ahead of server by ${Math.abs(Math.round(liquidCacheAge / 60))} minutes, assuming cache fresh`);
window._RestockRocketConfig.isLiquidCacheFresh = true;
} else if (liquidCacheAge
= LIQUID_CACHE_MAX_AGE) {
console.debug(`STOQ - Liquid cache is fresh (${Math.round(liquidCacheAge / 60)} minutes old)`);
window._RestockRocketConfig.isLiquidCacheFresh = true;
} else {
console.debug(`STOQ - Liquid cache is stale (${Math.round(liquidCacheAge / 60)} minutes old, max ${Math.round(LIQUID_CACHE_MAX_AGE / 60)} minutes)`);
window._RestockRocketConfig.isLiquidCacheFresh = false;
}
}
function checkSettingsExpiry(settings) {
try {
if (!settings || !settings.updated_at) {
console.debug('STOQ - Invalid settings data structure');
return null;
}
if (!settings.cache) {
console.debug('STOQ - settings caching disabled');
return null;
}
// Check if translations are enabled but missing from cache
// This handles the backfill period where DB has translations but metafield doesn't
if (settings.multi_language_enabled) {
if (!settings.translations) {
// Translations enabled but no Kosovo (EUR€)
age = Date.now() - updatedAt.getTime();
if (age
SETTINGS_CACHE_DURATION) {
console.debug('STOQ - settings changed recently, skipping cache');
return null;
}
return settings;
} catch (error) {
console.debug('STOQ - Error checking settings cache:', error);
return null;
}
}
function createRestockRocketContainer() {
const restockRocketContainer = document.createElement('div');
restockRocketContainer.id = 'restock-rocket';
document.body.appendChild(restockRocketContainer);
}
function createRestockRocketScript(scriptUrl) {
const restockRocketScriptElement = document.createElement('script');
restockRocketScriptElement.setAttribute('defer', 'defer');
restockRocketScriptElement.src = scriptUrl;
document.body.appendChild(restockRocketScriptElement);
}
createRestockRocketContainer()
console.debug('STOQ - extension activated')
// Fire stoq_initialized once per page load so the funnel pipeline has a definitive
// "our code ran on this page" signal independent of any cus
ctedVariantId || '',
liquid_rendered_at: _stoqInitConfig.liquidRenderedAt || 0,
app_version: _stoqInitConfig.appVersion || '',
liquid_cache_age: _stoqInitConfig.liquidCacheAge,
// Selected variant's stock posture as our app saw it at render — explains
// whether we *should* have treated it as a preorder candidate.
inventory_policy: (_stoqInitConfig.variantsInventoryPolicy || {})[_stoqSelectedVariantId] || '',
inventory_quantity: (_stoqInitConfig.variantsInventoryQuantity || {})[_stoqSelectedVariantId],
});
} catch (e) {
console.debug('STOQ - stoq_initialized publish failed:', e);
}
// STOQ-1595: publish stoq_accelerated_checkout_clicked for every accelerated-checkout
// click (Buy Now / dynamic checkout / Shop Pay installments) on ALL surfaces, before our
// bundle loads, via one delegated capture-phase listener (catches late-rendered buttons).
// Only on shops with preorders configured (shared `preordersConfigured` signal from the
// derivati
st('form');
var vidEl = form && form.querySelector('[name="id"]');
var variantId = (vidEl && vidEl.value) || _sqTrack.selected_variant_id || '';
// The enabled STOQ selling plan the clicked variant belongs to (if any), found once and
// reused for in_enabled_plan / enrolled_plan_id / enrolled_plan_provider below.
var _sqVidNum = Number(variantId);
var _sqPlan = null;
// Array.isArray guard (not `|| []`) so a truthy non-array sellingPlans can't throw and
// silently drop the whole publish.
var _sqPlans = Array.isArray(_sqTrack.sellingPlans) ? _sqTrack.sellingPlans : [];
_sqPlans.forEach(function (pl) {
if (!_sqPlan && pl && pl.enabled && Array.isArray(pl.variant_ids) &&
pl.variant_ids.indexOf(_sqVidNum) !== -1) { _sqPlan = pl; }
});
Shopify?.analytics?.publish?.('stoq_accelerated_checkout_clicked', {
variant_id: variantId,
product_id: (_sqTrLatvia (EUR€)
a like-typed compare.
is_preorder_variant: (function () {
var vid = Number(variantId);
var has = function (a) { return Array.isArray(a) && a.indexOf(vid) !== -1; };
return has(_sqTrack.preorderVariantIds) ||
has(_sqTrack.cachedPreorderVariantIds &&
_sqTrack.cachedPreorderVariantIds.preorder_variant_ids);
})(),
// Narrow, authoritative preorder signal: enrolled in an ENABLED STOQ selling plan
// (is_preorder_variant above is the broad OOS+continue heuristic — non-STOQ too).
in_enabled_plan: !!_sqPlan,
// In-stock preorder signal: enrolled but currently IN STOCK (in the inStockVariantIds
// set, not the OOS preorderVariantIds set). Same live-OR-cached pattern as
// is_preorder_variant. is_preorder_variant OR is_instock_variant = "should sell via
// the plan" regardless of stock, so an in-stock preord
cceleratedGateArmed,
gate_active_at_click: !!(document.documentElement &&
document.documentElement.classList.contains('stoq-buy-now-pending')),
},
});
} catch (err) { /* never break checkout */ }
}, true);
}
} catch (e) { /* fail open */ }
function applyTranslations(settings) {
try {
// Skip translation logic entirely if multi-language is not enabled
if (!settings || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translations found, skipping translation');
return settings;
}
const normalizedLocale = window._RestockRocketConfig.normalizedLocale;
const translations = settings.translations;
if (!normalizedLocale) {
// No matching locale has translations; drop payload to save memory
console.debug('STOQ - No matching locale for translations. Available:', Object.keys(translations || {})
"settings") { value } } }';
fetch(
`https://${cfg.shop}/api/2025-07/graphql.json`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': cfg.storefrontAccessToken,
},
body: JSON.stringify({ query: query, variables: { namespace: cfg.metafieldNamespace } }),
}
)
.then(function(response) {
if (!response.ok) { throw new Error('Storefront API HTTP ' + response.status); }
return response.json();
})
.then(function(body) {
if (body && body.errors && body.errors.length) {
throw new Error('Storefront API errors: ' + body.errors.map(function(e) { return e && e.message; }).join(', '));
}
const value = body && body.data && body.data.shop && body.data.shop.metafield && body.data.shop.metafield.value;
if (!value) { throw new Error('Storefront API returned no settings metafield value'); }
cfg.sto
.
p'
};
if (window.Shopify?.theme?.role === 'main') {
headers['X-Shopify-Theme-Schema-Name'] = window.Shopify.theme.schema_name;
headers['X-Shopify-Theme-Schema-Version'] = window.Shopify.theme.schema_version;
headers['X-Shopify-Theme-Store-Id'] = window.Shopify.theme.theme_store_id;
}
fetch(
`${window._RestockRocketConfig.host}/api/v1/setting.json?translation_locale=${window._RestockRocketConfig.normalizedLocale}`,
{ headers }
)
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(settings) {
initializeScripts(settings);
})
.catch(function(error) {
// If request failed and we have cached settings (even if expired), use them as fallback
if (cachedSettings) {
console.debug('STOQ - using expired cached settings as fallback');
initializeScripts(cachedSettings);
} else {
console.error('S
endpoint + ':', applyError);
throw applyError;
}
})
.catch(function(error) {
console.debug(`STOQ - using cached ${endpoint}:`, error.message);
});
}
function initializeScripts(settings) {
settings = applyTranslations(settings);
window._RestockRocketConfig.settings = settings;
console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`);
// Stale-Liquid resilience (default-on, per-shop opt-out via the
// `disable_refresh_on_stale_liquid` Toggle, surfaced as the negative
// `disable_refresh_on_stale_liquid` flag in settings.json so that
// `undefined` -- in CDN-cached metafield payloads that predate this
// key -- reads as `!undefined === true` and gets default-on behavior
// immediately, no metafield rewrite required).
// When the Liquid CDN cache is older than LIQUID_CACHE_MAX_AGE the in-page
// selling_plans / integrations metafields can be wrong; refresh both from
// the API before launching scr
Powered by
}
}),
fetchEmbedConfig('integrations', function(data) {
if (Array.isArray(data)) {
window._RestockRocketConfig.integrations = data;
}
})
]),
new Promise(function(resolve) { setTimeout(resolve, 1000); })
]).then(function() { loadScripts(settings); });
return;
}
loadScripts(settings);
}
function loadScripts(settings) {
// Setup cart selling plan updater BEFORE loading any scripts to avoid race conditions
setupCartSellingPlanUpdater(settings);
if(settings.enable_app) {
const hijackIntegration = window._RestockRocketConfig.integrations.find(function(integration) {
return integration.type === 'hijack' && integration.enabled && integration.page_types.includes(window._RestockRocketConfig.pageType);
})
// STOQ-1520: serve the lean back-in-stock-only build (no preorder/hijack code)
// only to shops with NO preorder plans. Use the full build if preorder is oLiberia (GBP£)
Shopify
onPageTypes = ['collection', 'index', 'search', 'page'];
if(collectionPageTypes.indexOf(pageType) !== -1 && (settings[`show_button_on_${pageType}`] || settings[`preorder_${pageType}_enabled`])) {
createRestockRocketScript(collectionScriptUrl);
} else if(pageType === 'product') {
createRestockRocketScript(productScriptUrl);
} else if(hijackIntegration) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(usePreorderBuild) {
// cart/article/blog/list-collections: full build so the cart sweep runs.
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else {
console.debug(`STOQ - no scripts enabled for ${pageType}`);
}
// Dispatch custom event when app is loaded
// Cart selling plan updates will be triggered by stoq:inventory-data-loaded event
const appLoadedEvent = new CustomEvent('stoq:loaded', {
detail: {
pageType: window._RestockR
.
window._RestockRocketConfig = window._RestockRocketConfig || {}
// Stoq is the current name of the app (RestockRocket is the legacy name).
// Expose _Stoq / _StoqConfig as live aliases of the same objects so both names
// work. Done here, before the JS bundles run, and the bundles only ever do
// `window._RestockRocket = window._RestockRocket || {}` (never reassign), so
// every method/config added later is visible on both names.
window._RestockRocket = window._RestockRocket || {}
window._Stoq = window._RestockRocket
window._StoqConfig = window._RestockRocketConfig
// Helper function to normalize locale format from hyphen to underscore (e.g., 'en-US' -> 'en_us')
// This matches the backend's Mobility.normalize_locale behavior
// Returns empty string if locale is empty or invalid (matches original behavior)
function normalizeLocale(locale) {
if (!locale || locale.trim() === '') {
return '';
}
return locale.toString().toLowerCase().replace(/-/g, '_');
}
window._RestockRocketConfig.locale = 'en';
window._RestockRocketConfig.normalizedLocale = normalizeLocale('en');
window._RestockRocketConfig.shop = 'projektride.myshopify.com';
window._RestockRocketConfig.pageType = 'product';
window._RestockRocketConfig.liquidRenderedAt = 1783549812;window._RestockRocketConfig.marketId = 382140642;window._RestockRocketConfig.countryName = 'United Kingdom';
window._RestockRocketConfig.countryIsoCode = 'GB';window._RestockRocketConfig.cartInventoryQuantity = {};// cart.token falls back to the `cart` cookie when the Liquid context didn't carry one
// (some page types render with cart={} until first interaction).
if (!window._RestockRocketConfig.cartToken) {
try {
const m = document.cookie.match(/(?:^|;\s*)cart=([^;]+)/);
if (m && m[1]) window._RestockRocketConfig.cartToken = decodeURIComponent(m[1]);
} catch (e) { /* cookie unavailable */ }
}window._RestockRocketConfig.cachedSettings = {"id":38500,"shop_id":38436,"currency":"GBP","created_at":"2025-07-26T09:13:57.337Z","updated_at":"2025-12-28T14:44:23.508Z","enable_app":true,"enable_signup_widget":false,"storefront_button_text":"Notify me when available","storefront_button_text_color":"#FFFFFF","storefront_button_background_color":"#202223","storefront_form_header":"Notify me","storefront_form_description":"Get a notification as soon as this product is back in stock by signing up below!","storefront_form_button_text":"Notify me when available","storefront_form_button_text_color":"#FFFFFF","storefront_form_button_background_color":"#202223","storefront_form_terms":"Promise we won't spam. You'll only receive notifications for this product.","storefront_form_error":"Please enter a valid email address","storefront_form_success":"Thank you! We will notify you when the product is available.","enable_powered_by":true,"show_button_on_preorder":true,"sms_enabled":false,"email_enabled":true,"storefront_button_disable_tag":"rocket-hide","theme_config":{"disableDebugLoggingForNonPreorderItem":false},"storefront_form_email_placeholder":"Email address","storefront_form_phone_placeholder":"SMS","storefront_form_phone_label":"Phone number","storefront_form_email_label":"Email","storefront_form_phone_error":"Please enter a valid phone number","storefront_form_customer_name_placeholder":"Name","storefront_form_customer_name_error":"Please enter your name","storefront_form_did_you_mean_error":"Did you mean %{suggested_email}? Or use %{current_email}","form_customer_name_enabled":false,"form_customer_name_required":false,"css_config":"","js_config":null,"collect_promotion_consent":false,"storefront_form_promotion_consent_label":"Notify me about other news, sales, discounts & offers too","show_button_on_collection":false,"sms_default_country":"us","sms_allowed_countries":[],"sms_restrict_country":false,"sms_default_channel":true,"optin_required":false,"optin_success_text":"Registration confirmed! You'll receive an alert when the product is restocked.","storefront_button_border_radius":0,"storefront_button_disable_tag_hides_button":true,"storefront_button_disable_tag_enabled":false,"quantity_required":false,"storefront_form_quantity_label":"Quantity","enable_alerts":true,"sms_allowed":false,"email_allowed":true,"collect_promotion_consent_default":true,"insert_button_after_selector":null,"insert_button_after_selector_type":"afterend","storefront_button_position_type":"float-right","storefront_form_duplicate_error":"You've already subscribed for alerts to this product.","storefront_mixed_cart_error":"This item needs to be purchased separately. Please check out or clear your cart before adding this item.","storefront_error_heading":"Error","default_locale":"en","collection_page_button_text_color":"#FFFFFF","collection_page_button_background_color":"#202223","show_button_if_any_out_of_stock":false,"show_button_if_any_variant_out_of_stock_collection":false,"show_button_on_index":false,"insert_button_after_selector_collection":null,"insert_button_after_selector_index":null,"push_enabled":false,"push_allowed":false,"storefront_form_push_label":"Push","storefront_form_push_description":"Click 'Allow' to be notified via push notification","storefront_form_push_error":"Permission rejected! Please review notification settings and try again","storefront_font_family":"OpenSans","insert_button_after_selector_collection_type":"afterend","show_channel_selector":false,"storefront_form_empty_error":"Please fill in one or more of the options above","storefront_form_push_input":"Send notification to your browser","insert_button_after_selector_page":null,"show_button_on_page":false,"insert_button_after_selector_search":null,"show_button_on_search":false,"app_proxy_path_prefix":"/apps/restockrocket-production","collection_link_selector":"","index_link_selector":"","page_link_selector":"","search_link_selector":"","collection_check_link_visibility":true,"collection_buttons_container":null,"index_buttons_container":null,"page_buttons_container":null,"search_buttons_container":null,"extension_enable_url_variant_detection":true,"extension_enable_value_variant_detection":true,"extension_value_variant_selector":"[name='id']","resubscribe_text":"This product is out of stock. Get notified when it's restocked again by entering your details below!","preorder_enabled":true,"preorder_buy_button_selector":null,"preorder_add_to_cart_button_selector":"","preorder_badge_selector":"","preorder_button_out_of_stock_text":"Out of stock","preorder_button_add_to_cart_text":"Add to cart","preorder_form_selector":"form[action*=\"/cart/add\"]","preorder_collection_enabled":false,"preorder_collection_form_selector":"form[action*=\"/cart/add\"]","preorder_collection_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_index_enabled":false,"preorder_index_form_selector":"form[action*=\"/cart/add\"]","preorder_index_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_page_enabled":false,"preorder_page_form_selector":"form[action*=\"/cart/add\"]","preorder_page_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_search_enabled":false,"preorder_search_form_selector":"form[action*=\"/cart/add\"]","preorder_search_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_collection_badge_selector":null,"preorder_index_badge_selector":null,"preorder_page_badge_selector":null,"preorder_search_badge_selector":null,"preorder_badge_selector_type":"afterend","preorder_collection_badge_selector_type":"afterend","preorder_button_child_selector":"span","preorder_button_disclaimer_insert_selector":"","preorder_button_disclaimer_insert_selector_type":"afterend","preorder_payment_insert_selector":"","preorder_payment_insert_selector_type":"afterend","preorder_price_container_selector":"","preorder_price_container_selector_insert_type":"afterend","preorder_terms_insert_selector":"","preorder_terms_insert_selector_type":"afterend","preorder_original_price_selector":"","preorder_price_format":"{{amount}} {{currency}}","show_badge_if_any_variant_is_preorder":false,"enable_console_debug":false,"inline_form_enabled":false,"inline_form_selector":null,"inline_form_selector_type":"afterend","storefront_form_prefill_customer":true,"storefront_form_show_image":false,"storefront_form_text_color":"#202223","storefront_form_background_color":"#FFFFFF","storefront_form_border_radius":0,"market_setup_type":"single_market","shopify_app_id":5940125,"preorder_progress_bar_insert_selector":null,"preorder_progress_bar_insert_selector_type":"beforebegin","countdown_timer_insert_selector":null,"countdown_timer_insert_selector_type":"afterend","cache":true,"cached_at":"2026-01-08T16:12:13.364Z","multi_language_enabled":false,"translation_locale":"en"};// STOQ shop-metafield namespace. `production` is substituted at build time
// (webpack CopyPlugin), so this is correct for every environment.
window._RestockRocketConfig.metafieldNamespace = 'restockrocket_production';window._RestockRocketConfig.cachedPreorderVariantIds = {"preorder_variant_ids":[42140096102626,42167799447778,43916521013474,43934694998242,43934695031010,43934695620834,43935975440610,43935975473378,43935989399778,43935989432546,43935990284514,43935994118370,43935995625698,43935995855074,43936000835810,43936003195106,43936003227874,43936008012002,43936008044770,43936022757602,43936022790370,43936022823138,43936022855906,43936056115426,43936061030626,43936064930018,43936070631650,43936078037218,43936078069986,43936088195298,43936093470946,43936101138658,43936107266274,43936124076258,43936124109026,43936124141794,43936124174562,43936129941730,43936129974498,43936130007266,43936142393570,43936142426338,43936142459106,43936152060130,43936152092898,43936152125666,43936193118434,43936250429666,43936255803618,43936266682594,43936266715362,43936293978338,43936294011106,43936316424418,43936316457186,43936320880866,43936320913634,43936320946402,43936327041250,43936327074018,43936327106786,43936331661538,43936332349666,43936351224034,43936353714402,43936362889442,43936362922210,43936388153570,43936389333218,43936395526370,43936398508258,43936401522914,43936408568034,43936414400738,43936700727522,43936706101474,43936706134242,43936706167010,43936706199778,43936706232546,43936706265314,43938298233058,43938298265826,43938298298594,43938298331362,43938298364130,43938298396898,43938298429666,43938298462434,43938299805922,43938299838690,43938299871458,43938299904226,43938299936994,43938299969762,43938300002530,43938308587746,43938308653282,43938308718818,43938308751586,43938308784354,43938308817122,43938322612450,43938322645218,43938322677986,43981336051938,43981336084706,43981336117474,43981336150242,43981345587426,43981345620194,43981345652962,43981345685730,43981357580514,43981357613282,43981362462946,43981362495714,43981362528482,43981369016546,43981369049314,43981374914786,43981374947554,43981374980322,43981392806114,43981392904418,43981392937186,43981695844578,43981695877346,43981695910114,43981695942882,43981986070754,43981987938530,44052906967266,44052907327714,44052907360482,44052907393250,44052907426018,44052907458786,44052907491554,44052909097186,44052909129954,44140279791842,44140279824610,44140279857378,44140279890146,44140279922914,44140292047074,44140292079842,44140292112610,44140293685474,44140302434530,44140302500066,44140302532834,44140302565602,44140302598370,44140302631138,44140302827746,44140302893282,44140302926050,44140315050210,44140317016290,44140321636578,44140335792354,44140335825122,44140335857890,44140339953890,44140339986658,44140340150498,44140340248802,44140340281570,44140340543714,44140340707554,44140340740322,44140340773090,44140345065698,44140352438498,44140388155618,44140388188386,44140397756642,44140404441314,44140404474082,44195991847138,44195991945442,44329993437410,44329993470178,44329993502946,44329993535714,44329993568482,45068753961186,45068753993954,45069622640866,45069622903010,45069622968546,45069750730978,45069750763746,45353010921698,45353010954466,45353010987234,45353018261730,45353018294498,45353018327266,55569712382335,55569712415103,55569712447871,55569712480639,55570017616255,55604008976767,55638316908927,55638316941695,55638316974463,56220814967167,56220814999935,56220815032703,56270279606655,56270279639423,56270279672191,56314171064703,56314171097471,56398983725439,56398983758207,56398983790975,56399322251647,56565020721535,56565020754303,56565020787071],"updated_at":"2026-07-08T22:13:28Z","market_locations_enabled":false,"market_id":382140642,"preorder_location_filter_enabled":false,"preorder_location_filter_ids":[],"collection_id":null,"bulk_operation":true};window._RestockRocketConfig.cachedInStockVariantIds = {"in_stock_variant_ids":[43590980075746,43934695653602,43935991955682,43935991988450,43935992742114,43936017449186,43936088228066,43936177291490,43936177324258,43936177357026,43936177389794,43936184271074,43936328843490,43936328876258,43936328909026,43936408535266,43936709837026,43936709869794,43938308620514,43938308686050,43938318811362,43938318844130,43938318876898,43938318909666,43938322579682,43981357514978,43981357547746,43981362430178,43981364887778,43981368951010,43981368983778,43981374882018,43981382320354,43981382353122,43981382385890,43981382418658,43981392773346,43981392838882,43981392871650,43981989085410,43981989118178,43981989150946,43981990887650,43981990920418,43981990953186,44195991879906,44195991912674,44195991978210,44195992010978,44196019929314,44196019962082,44199623721186,44199654424802,45068753731810,45068753764578,45068753797346,45068753830114,45068753862882,45068753895650,45068753928418,45068754026722,45068754059490,45069281657058,45069281689826,45069622771938,45069750534370,45069750567138,45069750599906,45069750632674,45069750665442,45069750698210,45070032535778,45070032568546,45073853972706,45073854005474,55570017550719,55570017583487,42133734097122,42133760966882,42133779153122,42133782364386,42133808021730,42133855994082,42133857042658,42133920153826,42133943910626,42134012788962,42134028943586,42134056698082,42134144581858,42134169092322,42134186557666,42140055666914,42140055797986,42156834128098,42156852216034,42156944425186,42156975751394,42157276561634,42157476085986,42157681082594,42157845184738,42161483514082,42161483546850,42161703092450,42161703125218,42161769218274,42162395414754,42162395447522,42163244171490,42163247939810,42165834744034,42165834776802,42166810804450,42167775494370,42167775527138,42167775559906,42170449199330,42170867777762,42170877313250,42170946879714,42170967982306,42205154181346,42205161849058,42205166207202,42205172990178,42205173022946,42205173055714,42205173088482,42205173121250,42205174989026,42205175021794,42205175054562,42205176430818,42205176463586,42205176496354,42205176529122,42205177118946,42205177151714,42205177184482,42205177217250,42205201694946,42205201727714,42207124095202,42207132156130,42211700244706,42211700277474,42211700375778,42211813359842,42211813392610,42211813425378,42211813458146,42211813490914,42215353909474,42215353942242,42215353975010,42215354007778,42309115412706,42354619154658,42354619482338,42354619547874,42354669093090,42452285784290,42500482498786,42514860802274,42514860835042,42514860867810,42543702376674,42562562490594,42577999888610,42603186749666,42603186782434,42603337056482,42603347476706,42627516039394,42695182942434,42804934377698,43000663933154,43000791630050,43010895675618,43010895708386,43010900459746,43010957902050,43012307353826,43012307386594,43012307419362,43012486594786,43017325641954,43064942461154,43064942493922,43064951341282,43067643855074,43067643887842,43067668627682,43067673215202,43107806445794,43169620263138,43182366949602,43414855287010,43525453676770,43525453742306,43525453775074,43525453807842,43525453840610,43525453938914,43557711020258,43590980108514,43724401049826,43725342146786,43725342212322,43725342245090,43725371703522,43725531349218,43725531578594,43725531611362,43727258845410,43727342207202,43727599304930,43766825386210,43766825418978,43766825451746,43766825484514,43847032570082,43852281676002,43852281708770,43852281774306,43852281807074,43854809104610,43854820016354,43854833746146,43861164490978,43866540015842,43866540048610,43866540081378,43916542247138,43933115220194,43933117382882,43933117415650,43933117448418,43934683922658,43934711349474,43934711382242,43936656326882,43936656392418,43936656425186,43936664879330,43936664912098,43936665010402,43936684310754,43936684343522,43936684409058,43936684441826,43936694763746,43936694796514,43936694829282,43936694862050,43936694894818,43936694927586,43936694960354,43936694993122,43981329137890,43981329170658,44049903780066,44049911185634,44049932779746,44049932878050,44049933041890,44140579160290,44199623688418,44199668023522,44199668056290,44199668089058,44199675560162,44199675592930,44199675625698,44199689257186,44199689289954,44202699653346,44202699686114,44215801413858,44393934487778,44441822789858,44441822822626,44441826590946,44455205372130,44455223132386,44455241941218,44459099455714,44566556410082,44566558343394,44566559719650,44566560735458,44566561521890,44891525611746,44891526463714,44891531313378,44891532951778,44891533869282,44891533902050,44891533934818,44891533967586,44891534164194,44891534229730,44891534262498,44891534819554,44891535376610,44891535474914,44891535540450,44891535573218,44891535638754,44891535671522,44891535704290,44891535802594,44891536031970,44915183288546,44915183321314,44915183386850,44915183419618,44915183452386,45099922391266,45099922424034,45099922456802,45099922489570,45099922522338,45610939089122,45610939121890,45610939154658,45610939187426,45610939220194,45610939252962,45610952196322,45610952229090,45610952261858,45610952294626,45610952327394,45610952360162,45610963206370,45610963239138,45610963271906,45610963304674,45610963337442,45610963370210,45661684203746,45661712974050,45661713006818,45661753213154,45661771923682,45661795647714,45661795680482,45661809443042,45662670389474,45662670422242,45662670455010,45662670487778,45662687166690,45662691066082,45662746804450,45662746837218,45662746869986,45662746902754,45662746935522,45662746968290,45662747001058,45662747033826,45662747066594,45662747099362,45662747132130,45662747164898,45662747197666,45662784782562,45662784815330,45662784848098,45662784880866,45662784913634,45662788518114,45662788550882,45662788583650,45662788616418,45662788649186,45662860017890,45662860050658,45662860083426,45662860116194,45662860148962,45662860181730,45662860214498,45662860247266,45662860280034,45662860312802,45662860345570,45662860378338,45662860411106,45662934728930,45662934761698,45662934794466,45662934827234,45662934860002,45662934892770,45662934925538,45662934958306,45662975295714,45662975328482,45662975361250,45662975394018,45662975426786,45662975459554,45662975492322,45662975525090,45662975557858,45662975590626,45662975623394,45662975656162,45663035818210,45663035850978,45663035883746,45663035916514,45663035949282,45663035982050,45663036047586,45663036080354,45663036113122,45663036145890,45663059575010,45664124010722,45664124043490,45664124109026,45664132563170,45664132595938,45664155533538,45664159236322,45664159301858,45671617593570,45671617659106,45671617691874,45671617724642,45671617790178,45671618805986,45671618838754,45671619920098,45671619952866,45671620640994,45671621034210,45671621066978,45671621099746,45671621132514,45671622246626,45671622279394,45671622312162,45671622344930,45694278959330,45694281089250,45694283186402,45694284103906,45694284890338,45694285021410,45694288822498,45694290297058,45694290821346,45694291968226,45694292197602,45694293475554,45694293803234,45694293836002,45696083656930,45696083689698,45696083722466,45760534905058,45760534937826,45760534970594,45760537592034,45760542474466,45760542507234,45760550535394,45760550568162,45760557711586,45760558268642,45760558596322,45760559087842,45764606394594,45764607803618,45764613308642,45764615897314,45764617928930,45764620157154,45764621664482,45764621697250,45767010451682,45767010484450,45767010517218,45767010549986,45767010746594,45767270531298,45767273513186,45767291371746,45767298482402,45767298711778,45767301726434,45767307264226,45767310868706,45767318601954,45817747276002,45817747308770,45817749143778,45817751470306,45817751503074,45817751535842,45817751568610,45817766117602,45817769459938,45817769525474,45817769591010,45817770279138,45817770311906,45817770344674,45817770377442,45817770410210,45817780633826,45817780732130,45820457779426,45820457812194,45820457844962,45820457877730,45820457910498,45820457943266,45820457976034,45820458008802,45820514762978,45820514795746,45820517220578,45820519121122,45820519153890,45820527444194,45820527476962,45820546908386,45820546941154,45820547006690,45820551495906,45820551528674,45820551561442,45820551594210,45820575875298,45820575908066,45820575940834,45820590981346,45820591014114,45820624994530,45820625027298,45820630040802,45820633120994,45820633153762,45820633186530,45820633219298,45823204065506,45823204098274,45823204131042,45823204163810,45823204196578,45823204229346,45823204262114,45823204294882,45823204327650,45823204360418,45823204393186,45823204425954,45823219564770,45823219597538,45823219630306,45823219663074,45823219695842,45823219728610,45823219761378,45823219794146,45823219826914,45823219859682,45823219892450,45823219925218,45823222808802,45823222841570,45823222874338,45823222907106,45823222939874,45823222972642,45823223005410,45823223038178,45823223070946,45823223103714,45823223136482,45823223169250,45823223202018,45823223234786,45823223267554,45823223300322,45823223333090,45823223365858,45823223398626,45823223431394,45823223496930,45823223529698,45823223562466,45823223595234,45823223628002,45823223660770,45823223693538,45823223726306,45823223759074,45823223824610,45823229001954,45823229165794,45823229755618,45823231361250,45823231754466,45823231787234,45823231820002,45823231852770,45823231885538,45823231918306,45823231951074,45823231983842,45823232016610,45823232049378,45823232082146,45823232114914,45823232147682,45823232180450,45823232213218,45823232278754,45823232311522,45823232344290,45823232377058,45823232409826,45823232442594,45823232475362,45823233786082,45823233818850,45823233851618,45823233884386,45823233917154,45823233949922,45823233982690,45823234015458,45823234048226,45823234080994,45823234113762,45823234146530,45823768559842,45823768592610,45823768625378,45823768658146,45823768690914,45823768723682,45823768756450,45823768789218,45823768821986,45823768854754,45823768887522,45823768920290,45823768953058,45823768985826,45823769018594,45823769051362,45823769084130,45823769116898,45823769149666,45823769182434,45823769215202,45823769247970,45823769280738,45823769313506,45823769379042,45823769411810,45823769444578,45823769477346,45823769510114,45823769542882,45823769575650,45823865815266,45823865848034,45823865880802,45823865913570,45823865946338,45823865979106,45823866011874,45823866044642,45823866077410,45823866110178,45823866142946,45823866175714,45823866208482,45823866241250,45823866274018,45823866306786,45823866339554,45823866372322,45823866405090,45823866437858,45824032440546,45824032473314,45824032506082,45824032538850,45824032571618,45824032604386,45824032637154,45824032669922,45824032702690,45824132153570,45824132186338,45824132219106,45824132251874,45824132284642,45824132317410,45824132350178,45824132382946,45824132415714,45824132448482,45824132481250,45824132514018,45824132546786,45824132579554,45824132612322,45824132645090,45824132677858,45824132710626,45824132743394,45824132776162,45824132808930,45824132841698,45824132874466,45824132907234,45824132940002,45824132972770,45824133005538,45824133038306,45824133071074,45824133103842,45824133136610,45824133169378,45824133202146,45824133234914,45824133267682,45824133300450,45824133333218,45824133365986,45824133398754,45824133431522,45824133464290,45824133497058,45824133529826,45824133562594,45824133595362,45824191791330,45824191824098,45824191856866,45824191889634,45824191922402,45824191955170,45824191987938,45824192020706,45824192053474,45824192086242,45824192119010,45824192151778,45824198705378,45824198738146,45824198770914,45824207978722,45824208011490,45824208044258,45824208077026,45824208109794,45824208142562,45824208175330,45824208208098,45824208240866,45824374767842,45824374800610,45824374833378,45824374866146,45824374898914,45824374931682,45824374964450,45824374997218,45824375029986,45824375062754,45824375095522,45824375128290,45824375161058,45824375193826,45824375226594,45824375259362,45824375292130,45824375324898,45824384434402,45824384467170,45824384499938,45824384532706,45824384565474,45824384598242,45824384631010,45824384663778,45824384696546,45824385515746,45824385548514,45824385581282,45824385614050,45824385646818,45824385679586,45824385712354,4582438
requires_shipping":true,"taxable":true,"featured_image":{"id":74358276227455,"product_id":14979883729279,"position":1,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:23+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","variant_ids":[55196404285823,55196404318591,55196404351359,55196404384127]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw \/ Medium","public_title":"Raw \/ Medium","options":["Raw","Medium"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621962111,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404351359,"title":"Raw \/ Large","optior_button_description_show_quantity_limit":false,"preorder_button_description_quantity_limit_suffix":" units available for preorder","preorder_button_description_shipping_text_prefix":"Shipping: ","delivery_exact_time":null,"delivery_after_n_intervals":null,"delivery_at":"2025-07-26T09:20:18.169Z","delivery_type":"asap","quantity_limit_text":"{{ quantity }} units available for preorder","preorder_button_description_show_shipping":true,"preorder_button_description_icons_enabled":true,"preorder_shipping_text":"Shipping: {{ date }}","shipping_applies_to_all_products":true,"shipping_text":"Estimated to ship within 2 months","payment_type":"full","billing_checkout_charge_type":"percentage","billing_checkout_charge_amount":null,"billing_checkout_charge_percentage":"100.0","pricing_type":"no_discount","pricing_amount":null,"pricing_percentage":null,"discount_text":"Save {{ discount }}","billing_title":"Full payment","billing_description":null,"enable_billing_widget":false,"inventory_provider":"stoq","preorder_badge_e
437
n1":"Raw","option2":"Large","option3":null,"sku":"YCB25167CXLRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276227455,"product_id":14979883729279,"position":1,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:23+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","variant_ids":[55196404285823,55196404318591,55196404351359,55196404384127]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw \/ Large","public_title":"Raw \/ Large","options":["Raw","Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621962111,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"maxnabled":false,"preorder_badge_text":"Preorder","preorder_badge_text_color":"#FFFFFF","preorder_badge_background_color":"#000000","preorder_discounted_price_enabled":null,"payment_line_item_property_enabled":false,"shipping_line_item_property_enabled":true,"custom_line_item_property_text":null,"preorder_button_text_color":"#ffffff","preorder_button_background_color":"#565557","preorder_button_colors_enabled":true,"markets_enabled":false,"market_id":13779632354,"shopify_market_ids":[],"use_shopify_selling_plan":true,"use_simplified_shipping_text":false,"translations":{},"payment_options":[{"billing_type":"no_remaining_balance","billing_checkout_charge_type":"percentage","billing_checkout_charge_amount":null,"billing_checkout_charge_percentage":"100.0","billing_at":"2025-07-26T09:20:38.472Z","billing_after_n_intervals":7,"billing_after_interval_type":"day","pricing_type":"no_discount","pricing_amount":null,"pricing_percentage":null,"billing_title":"Full payment","billing_description":null,"discount_text":"Save {
":null,"increment":1}},{"id":55196404384127,"title":"Raw \/ Extra Large","option1":"Raw","option2":"Extra Large","option3":null,"sku":"YCB25167CXLRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276227455,"product_id":14979883729279,"position":1,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:23+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","variant_ids":[55196404285823,55196404318591,55196404351359,55196404384127]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw \/ Extra Large","public_title":"Raw \/ Extra Large","options":["Raw","Extra Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621962111,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v={ discount }}","shopify_selling_plan_id":713071886719,"is_default":true,"type":"full","translations":{}}],"require_preorder_acknowledgement":false,"preorder_acknowledgement_text":"I acknowledge and agree to the preorder terms and conditions for this product.","disable_button_until_acknowledged":false,"preorder_min_quantity":null,"preorder_max_quantity":null,"countdown_timer_enabled":false,"countdown_timer_style":"text","countdown_timer_text_color":"#000000","countdown_timer_background_color":"#f5f5f5","countdown_timer_border_radius":8,"countdown_timer_format":"DHMS","countdown_timer_use_schedule_dates":true,"countdown_timer_custom_start_date":null,"countdown_timer_custom_end_date":null,"countdown_timer_starts_text":null,"countdown_timer_ends_text":null,"schedule_offer":false,"schedule_start_date":null,"schedule_end_date":null,"updated_at":"2025-08-19T10:05:43.042Z","allow_mixed_cart":true,"mixed_cart_error_message":"Preorders must be purchased separately from regular items. Please complete your current order
Cyprus (EUR€)
1741953563"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404416895,"title":"Spruce \/ Small","option1":"Spruce","option2":"Small","option3":null,"sku":"YCB25167CSMPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276260223,"product_id":14979883729279,"position":2,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","variant_ids":[55196404416895,55196404449663,55196404482431,55196404515199]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Spruce \/ Small","public_title":"Spruce \/ Small","options":["Spruce","Small"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621994879,"position":2,"preview_first, or clear your cart to continue.","b2b_enabled":true,"preorder_progress_bar_enabled":false,"preorder_progress_bar_text":"{{ sold }} of {{ total }} claimed","preorder_progress_bar_fill_color":"#000000","preorder_progress_bar_background_color":"#e5e5e5","preorder_progress_bar_text_color":"#FFFFFF","preorder_progress_bar_border_radius":4,"preorder_progress_bar_show_percentage":false}],"disabled_plan_ids":[713813721471,713176482175,714631872895],"cached_at":"2026-04-09T09:16:46Z"};
if (cachedData && typeof cachedData === 'object' && cachedData.cached_at) {
// Find the maximum updated_at from all items in old array
const oldPlans = window._RestockRocketConfig.sellingPlans;
const maxUpdatedAt = Array.isArray(oldPlans) && oldPlans.length > 0
? oldPlans.reduce(function(max, plan) {
// Parse dates for proper comparison (handles mixed ISO formats)
if (plan.updated_at) {
const planDate = new Date(plan.updated_at);
image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404449663,"title":"Spruce \/ Medium","option1":"Spruce","option2":"Medium","option3":null,"sku":"YCB25167CMDPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276260223,"product_id":14979883729279,"position":2,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","variant_ids":[55196404416895,55196404449663,55196404482431,55196404515199]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Spruce \/ Medium","public_title":"Spruce \/ Medium","options":["Spruce","Medium"],"pconst maxDate = max ? new Date(max) : null;
return (!maxDate || (planDate && !isNaN(planDate) && planDate > maxDate)) ? plan.updated_at : max;
}
return max;
}, '')
: null;
// Use cached if old array is empty/has no timestamps, or cached is newer
// Parse dates for comparison to handle format differences (+00:00 vs .000Z)
const cachedDate = new Date(cachedData.cached_at);
const maxDate = maxUpdatedAt ? new Date(maxUpdatedAt) : null;
const useCached = !maxUpdatedAt || (cachedDate && !isNaN(cachedDate) && (!maxDate || cachedDate > maxDate));
if (useCached) {
if (Array.isArray(cachedData.plans)) {
window._RestockRocketConfig.sellingPlans = cachedData.plans;
// Only use disabled_plan_ids when using cached plans
window._RestockRocketConfig.disabledSellingPlanIds = cachedData.disabled_plan_ids || [];
console.debug('[RR] Using selling plans from 439
Sudan (GBP£)
rice":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621994879,"position":2,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404482431,"title":"Spruce \/ Large","option1":"Spruce","option2":"Large","option3":null,"sku":"YCB25167CLGPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276260223,"product_id":14979883729279,"position":2,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","variant_ids":[55196404416895,55196404449663,55196404482431,55196404515199]},"avacachedSellingPlans (cached_at: ' + cachedData.cached_at + ')');
}
} else {
// When using old format (stale cache), don't trust disabled_plan_ids
window._RestockRocketConfig.disabledSellingPlanIds = [];
console.debug('[RR] Using selling plans from old format (max updated_at: ' + maxUpdatedAt + ')');
}
}
})();window._RestockRocketConfig.enabledNotifyMeVariantIds = [];window._RestockRocketConfig.disabledNotifyMeVariantIds = [];window._RestockRocketConfig.backInStockTemplates = [];window._RestockRocketConfig.restockNotes = {};window._RestockRocketConfig.integrations = [{"id":"15c94526-b6b8-4de1-9bc1-23b1ca52ddb0","shop_id":38436,"enabled":true,"page_types":["product","collection","index","search","page","cart","list-collections","article","blog"],"configuration":{"toastDuration":10000,"toastPosition":"bottom-right","enableXHRHijack":true,"enableFetchHijack":true,"quantityLimitDisabled":false},"type":"hijack","css_config":null,"js_config":null,"crea
ilable":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Spruce \/ Large","public_title":"Spruce \/ Large","options":["Spruce","Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621994879,"position":2,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404515199,"title":"Spruce \/ Extra Large","option1":"Spruce","option2":"Extra Large","option3":null,"sku":"YCB25167CXLPSUDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276260223,"product_id":14979883729279,"position":2,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uted_at":"2025-07-26T09:16:04.076Z","updated_at":"2025-07-26T09:16:04.076Z"}];window._RestockRocketConfig.obfuscateInventoryQuantity = false;window._RestockRocketConfig.product = {"id":7485176316130,"title":"Continental Road Race 700c 20mm-25mm) Presta Inner Tube - 42mm valve","handle":"continental-race-700c-20mm-25mm-presta-inner-tube-42mm-valve","description":"\u003cp\u003eContinental Inner Tube\u003c\/p\u003e\n\u003cp\u003eSize - 700c 20mm\/25mm \u003c\/p\u003e\n\u003cp\u003eValve type - Presta 42mm\u003c\/p\u003e\n\u003cp\u003e\u003cmeta charset=\"utf-8\"\u003e\u003cspan\u003eI\u003c\/span\u003e\u003cspan\u003emages are for illustration purposes only.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cmeta charset=\"utf-8\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eThe new ContiTube\u003c\/strong\u003e\u003cspan data-mce-fragment=\"1\"\u003e bicycle tube program makes it easier for you to find the ideal tube for your cycling demands. They offer a selection of tube sizes, types, lengths and dimensi
k\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","variant_ids":[55196404416895,55196404449663,55196404482431,55196404515199]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Spruce \/ Extra Large","public_title":"Spruce \/ Extra Large","options":["Spruce","Extra Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739621994879,"position":2,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404547967,"title":"Raw Gloss \/ Small","option1":"Raw Gloss","option2":"Small","option3":null,"sku":"YCB25167CSMRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276292991,ons for MTB, Tour, Cross and Race tyres. Varying tube types can affect your tyres’ handling characteristics with little effort: the Standard tube, available in many dimensions, offers the best compromise for everyday cycling.\u003c\/span\u003e\u003c\/p\u003e","published_at":"2025-01-07T16:36:36+00:00","created_at":"2021-12-26T18:27:07+00:00","vendor":"Continental","type":"","tags":["spo-cs-disabled","spo-default","spo-disabled","spo-notify-me-disabled","tubes"],"price":699,"price_min":699,"price_max":699,"available":true,"price_varies":false,"compare_at_price":null,"compare_at_price_min":0,"compare_at_price_max":0,"compare_at_price_varies":false,"variants":[{"id":42205161849058,"title":"Default Title","option1":"Default Title","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Continental Road Race 700c 20mm-25mm) Presta Inner Tube - 42mm valve","public_title":null,"options":["Default Title"],"price":699,"weight":0,"compare_at_price"
:null,"inventory_management":"shopify","barcode":null,"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2021-12-26at18.29.09.png?v=1640543369"],"featured_image":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2021-12-26at18.29.09.png?v=1640543369","options":["Title"],"media":[{"alt":null,"id":28913814241506,"position":1,"preview_image":{"aspect_ratio":0.744,"height":850,"width":632,"src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2021-12-26at18.29.09.png?v=1640543369"},"aspect_ratio":0.744,"height":850,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/products\/Screenshot2021-12-26at18.29.09.png?v=1640543369","width":632}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003eContinental Inner Tube\u003c\/p\u003e\n\u003cp\u003eSize - 700c 20mm\/25mm \u003c\/p\u003e\n\u003cp\u003eValve type - Presta 42mm\u003c\/p\u003e\n\u003cp\
"product_id":14979883729279,"position":3,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564","variant_ids":[55196404547967,55196404580735,55196404613503,55196404646271]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw Gloss \/ Small","public_title":"Raw Gloss \/ Small","options":["Raw Gloss","Small"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739622027647,"position":3,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404580735,"title":"Raw Gloss \/ Medium","option1":"Raw Gloss","option2":"Medium","option3":null,"sku"u003e\u003cmeta charset=\"utf-8\"\u003e\u003cspan\u003eI\u003c\/span\u003e\u003cspan\u003emages are for illustration purposes only.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cmeta charset=\"utf-8\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eThe new ContiTube\u003c\/strong\u003e\u003cspan data-mce-fragment=\"1\"\u003e bicycle tube program makes it easier for you to find the ideal tube for your cycling demands. They offer a selection of tube sizes, types, lengths and dimensions for MTB, Tour, Cross and Race tyres. Varying tube types can affect your tyres’ handling characteristics with little effort: the Standard tube, available in many dimensions, offers the best compromise for everyday cycling.\u003c\/span\u003e\u003c\/p\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {42205161849058 : "deny",};
window._RestockRocketConfig.variantsInventoryQuantity = {42205161849058 : parseInt("4"),};
window._RestockRocketConfig.variantsPreorderCount = {42205161849058 : parseInt(""),
:"YCB25167CMDRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276292991,"product_id":14979883729279,"position":3,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564","variant_ids":[55196404547967,55196404580735,55196404613503,55196404646271]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw Gloss \/ Medium","public_title":"Raw Gloss \/ Medium","options":["Raw Gloss","Medium"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739622027647,"position":3,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id};
window._RestockRocketConfig.variantsPreorderCountForMarket = {42205161849058 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {42205161849058 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {42205161849058 : null,};
window._RestockRocketConfig.variantsShippingText = {42205161849058 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {42205161849058 : null,};
window._RestockRocketConfig.selected_variant_id = 42205161849058;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;// STOQ-1595/1612 shared signal, derived once here so both the accelerated-checkout block
// gate (STOQ-1612) and the click tracker (STOQ-1595) read one clearly-owned flag rather
// than a side effect buried in either consumer's try/catch: whether this shop has preorders
// configured
Czechia (CZKKč)
":55196404613503,"title":"Raw Gloss \/ Large","option1":"Raw Gloss","option2":"Large","option3":null,"sku":"YCB25167CLGRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276292991,"product_id":14979883729279,"position":3,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564","variant_ids":[55196404547967,55196404580735,55196404613503,55196404646271]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw Gloss \/ Large","public_title":"Raw Gloss \/ Large","options":["Raw Gloss","Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739622027647,"position":3,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"}},"requires_sel at all — an enabled selling plan plus at least one preorder variant id,
// independent of the block toggle. Fail-open: on error the flag stays unset and both
// consumers no-op.
try {
var _sqCfg = window._RestockRocketConfig;
var _sqPlanEnabled = Array.isArray(_sqCfg.sellingPlans) &&
_sqCfg.sellingPlans.some(function (p) { return p && p.enabled; });
var _sqPreCount = ((_sqCfg.cachedPreorderVariantIds &&
_sqCfg.cachedPreorderVariantIds.preorder_variant_ids) || []).length;
_sqCfg.preordersConfigured = !!(_sqPlanEnabled && _sqPreCount);
} catch (e) { /* fail open */ }
// STOQ-1612: block (not hide) Buy Now / Shop Pay until our JS runs, so a tap in the
// load window can't bypass preorder. pointer-events via .stoq-buy-now-pending (no
// reflow); timeout releases; renderPreorderButton / featured_product.js lift it.
// Gated by the `block_accelerated_checkout` toggle (default OFF) for gradual rollout.
// Armed ONLY when we're sure preorder is in play — product pag
ling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":55196404646271,"title":"Raw Gloss \/ Extra Large","option1":"Raw Gloss","option2":"Extra Large","option3":null,"sku":"YCB25167CLGRGGDHC028701","requires_shipping":true,"taxable":true,"featured_image":{"id":74358276292991,"product_id":14979883729279,"position":3,"created_at":"2025-03-14T11:59:24+00:00","updated_at":"2025-03-14T11:59:24+00:00","alt":null,"width":697,"height":833,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564","variant_ids":[55196404547967,55196404580735,55196404613503,55196404646271]},"available":true,"name":"Yeti Cycles SB165 C-Series C2 Factory 29\" \/ 27.5\" Bike - Raw Gloss \/ Extra Large","public_title":"Raw Gloss \/ Extra Large","options":["Raw Gloss","Extra Large"],"price":679900,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":null,"featured_media":{"alt":null,"id":64739622027647,"position":3,"preview_image":{"aspect_rate: THIS product has a
// preorder variant (never block a plain product's Shop Pay); featured: integration
// enabled for this page type. Rationale: PR #2784.
try {
var _sqc = window._RestockRocketConfig;
var _sqOn = !!(_sqc.cachedSettings && _sqc.cachedSettings.block_accelerated_checkout);
var _sqPre = (_sqc.cachedPreorderVariantIds &&
_sqc.cachedPreorderVariantIds.preorder_variant_ids) || [];
var _sqArm = false;
if (_sqOn && _sqc.preordersConfigured) {
if (_sqc.pageType === 'product' && _sqc.product && _sqc.product.variants) {
_sqArm = _sqc.product.variants.some(function (v) { return _sqPre.indexOf(Number(v.id)) !== -1; });
} else {
_sqArm = (_sqc.integrations || []).some(function (i) {
return i && i.type === 'featured_product' && i.enabled &&
Array.isArray(i.page_types) && i.page_types.indexOf(_sqc.pageType) !== -1;
});
}
}
if (_sqArm && document.documentElement) {
_sqc.acceleratedGateArmed = true;
F
Svalbard & Jan Mayen (GBP£)
io":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"}},"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}}],"images":["\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"],"featured_image":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","options":["Colour","Size"],"media":[{"alt":null,"id":64739621962111,"position":1,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563"},"aspect_ratio":0.837,"height":833,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_5.webp?v=1741953563","width":697},{"alt":null,"id":64739621994879,"posit document.documentElement.classList.add('stoq-buy-now-pending');
setTimeout(function () {
document.documentElement.classList.remove('stoq-buy-now-pending');
}, 6000);
}
} catch (e) { /* fail open */ }
window._RestockRocketConfig.scriptUrlProduct = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection.js'
window._RestockRocketConfig.scriptUrlProductBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product-bis.js'
window._RestockRocketConfig.scriptUrlCollectionBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection-bis.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketC
ion":2,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564"},"aspect_ratio":0.837,"height":833,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167cspru_1_87b8d739-bd95-4dc7-b4e6-9352d6a93e96.webp?v=1741953564","width":697},{"alt":null,"id":64739622027647,"position":3,"preview_image":{"aspect_ratio":0.837,"height":833,"width":697,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564"},"aspect_ratio":0.837,"height":833,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/ycb25167crawg_6.webp?v=1741953564","width":697}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cdiv class=\"product info detailed\"\u003e\n\u003cdiv class=\"product data items mage-tabs-disabled\" role=\"tablist\"\u003e\n\u003cdiv class=\"data item content\" aria-labelledby=\"tab-label-description\" id=\"description\" data-onfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when present, mirroring the same
// override in assets/js/api.js. cachedSettings is populated above. Falls
// back to the build-baked host for shops without the use_render_api_host
// toggle (or environments where THEME_EXTENSION_API_HOST is unset), so the
// setting.json + fetchEmbedConfig calls below route to the same host as the
// rest of the extension's API traffic instead of staying on the baked host.
window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://app.restockrocket.io'
// Deployed extension build number, read from the CDN asset host Shopify generates:
// https://cdn.shopify.com/extensions/
role=\"content\" role=\"tabpanel\" aria-hidden=\"false\"\u003e\n\u003cdiv class=\"product attribute description\"\u003e\n\u003cdiv class=\"value\"\u003e\n\u003cdiv data-content-type=\"html\" data-appearance=\"default\" data-element=\"main\" data-decoded=\"true\"\u003e\n\u003cdiv class=\"Yeti-Text_Intro-BG\"\u003e\n\u003cdiv class=\"Yeti-Text_Intro-Text\"\u003e\n\u003cp class=\"Yeti-Model\"\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cdiv class=\"yet-section yet-group\"\u003e\u003cpicture\u003e\u003csource type=\"image\/webp\" srcset=\"https:\/\/www.silverfish-uk.com\/media\/.renditions\/wysiwyg\/products\/Yeti\/TL-Rampage2022-32451.webp\" width=\"2000\" height=\"1333\"\u003e\u003cimg width=\"2000\" height=\"1333\" src=\"https:\/\/www.silverfish-uk.com\/media\/.renditions\/wysiwyg\/products\/Yeti\/TL-Rampage2022-32451.jpg\" alt=\"\" loading=\"lazy\"\u003e\u003c\/picture\u003e\u003c\/div\u003e\n\u003cbr\u003e\n\u003cp\u003eWe said it already knows. And now it knows better. Proven worthy time and again at Rampage, <
reconfigured to fit the bill as Zero-Hesitation Go-To for whatever your pleasure. Un-rack it for all the park laps, pedal it on character-building epics, push it up spooky steep darksides “nobody†knows about. Whatever the question, unhard your decisions.\u003cspan\u003e \u003c\/span\u003e\u003cspan\u003eYOU ASK. IT GIVES.\u003c\/span\u003e.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Feature-Box-BG\"\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e165\u003cspan\u003eMM\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eFRAME TRAVEL\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e170\u003cspan\u003eMM\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eFORK TRAVEL\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-uuid>/WHEELBASE
box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e29\"\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eFRONT WHEEL SIZE\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e27.5\"\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eREAR WHEEL SIZE\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e63.5°\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eHEAD TUBE ANGLE\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cspan\u003e \u003c\/span\u003e\n\u003cdiv class=\"feature-box\"\u003e\n\u003cp class=\"feature-box_value\"\u003e76.9°\u003cspan\u003e\u003c\/span\u003e\u003c\/p\u003e\n\u003cp class=\"feature-box_value-type\"\u003eEFF. SEAT ANGLE\u003c\/p\u003e\n\u003c\/div\u003e\n\<
u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Highlights-BG_165MX\"\u003e\n\u003cdiv class=\"Yeti-Text_Highlights-Text\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eHIGHLIGHTS\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003eFox Factory 38 Grip 2 and Fox Factory DHX2 shock\u003c\/li\u003e\n\u003cli\u003eFox Transfer dropper post\u003c\/li\u003e\n\u003cli\u003eMX DT Swiss EX1700 custom wheelset\u003c\/li\u003e\n\u003cli\u003e4 piston brakes\u003c\/li\u003e\n\u003cli\u003eODI Elite Pro grips\u003c\/li\u003e\n\u003cli\u003e220mm front and 200mm rear rotors\u003c\/li\u003e\n\u003cli\u003eMaxxis Assegai 2.5 and DHR II 2.4 EXO+ tyres\u003c\/li\u003e\n\u003cli\u003eSLS Coil Spring on frame only\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Frame-Highlights-BG_165MX\"\u003e\n\u003cdiv class=\"Yeti-Text_Frame-Highlights-Text\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eFRAME HIGHLIGHTS\u003c\/p\u003e\n\u003cul\u003e\n\u003cli\u003e63.5-degree head tube angle\u003c\/li\u00handle>-
Denmark (DKKkr.)
3e\n\u003cli\u003e76.9-degree seat tube angle\u003c\/li\u003e\n\u003cli\u003e165mm rear travel paired with a 170mm fork\u003c\/li\u003e\n\u003cli\u003eSizes: SM-XL\u003c\/li\u003e\n\u003cli\u003eThreaded bottom bracket\u003c\/li\u003e\n\u003cli\u003eHigh-clearance downtube\u003c\/li\u003e\n\u003cli\u003eDual-density downtube protection\u003c\/li\u003e\n\u003cli\u003eUniversal Derailleur Hanger (UDH)\u003c\/li\u003e\n\u003cli\u003eSecure, fully enclosed internal cable management\u003c\/li\u003e\n\u003cli\u003eCompatible with long dropper posts\u003c\/li\u003e\n\u003cli\u003e100% standard sealed Enduro Max bearings\u003c\/li\u003e\n\u003cli\u003eFloating collet axle pivot design\u003c\/li\u003e\n\u003cli\u003eCompact-wishbone shock extender\u003c\/li\u003e\n\u003cli\u003eBoost spacing\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Team-BG_165MX\"\u003e\n\u003cdiv class=\"Yeti-Text_Team-Text_165MX\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eYOU ASK. IT GIVES.\<
u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"Yeti-Text_Size-Guide-BG\"\u003e\n\u003cdiv class=\"Yeti-Text_Size-Guide-Text\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eSIZE GUIDE\u003c\/p\u003e\n\u003cdiv id=\"sizechart\"\u003e\n\u003ctable id=\"sizechart\"\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd id=\"sizechart\"\u003e\u003cstrong\u003eSMALL\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e5'1\" - 5'7\"\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd id=\"sizechart\"\u003e\u003cstrong\u003eMEDIUM\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e5'5\" - 5'11\"\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd id=\"sizechart\"\u0version>/assets/...
// Trailing digits (e.g. ".../restockrocket-1-521/assets/" -> "521"). Kept numeric to
// match ParseStoqData, so funnel app_version lines up with the order-attribution
// app_version. Reflects the ACTUAL deployed build. This is the SINGLE source of the
// parsed version — preorder.js getAppVersion() reads it back off config rather than
// re-parsing, so the regex lives in exactly one place.
try {
const _stoqVersionMatch = window._RestockRocketConfig.scriptHost.match(/(\d+)\/?(?:assets\/?)?$/);
window._RestockRocketConfig.appVersion = (_stoqVersionMatch && _stoqVersionMatch[1]) || '';
} catch (e) {
window._RestockRocketConfig.appVersion = '';
}
const SETTINGS_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds
const LIQUID_CACHE_MAX_AGE = 15 * 60; // 15 minutes in seconds
// Calculate Liquid cache freshness once at initialization
const liquidRenderedAt = window._RestockRocketConfig.liquidRenderedAt;
// Validate timestamp and calculate ca1207
Sweden (SEKkr)
03e\u003cstrong\u003eLARGE\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e5'10\" - 6'3\"\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003ctd id=\"sizechart\"\u003e\u003cstrong\u003eX-LARGE\u003c\/strong\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e\u003c\/td\u003e\n\u003ctd id=\"sizechart\"\u003e6'1\" - 6'7\"\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv data-content-type=\"html\" data-appearance=\"default\" data-element=\"main\" data-decoded=\"true\"\u003e\n\u003cp class=\"Yeti-Title\"\u003eSPECIFICATION\u003c\/p\u003e\n\u003cp class=\"Yeti-Spec_text\"\u003eC \/ Series carbon fibre frame, threaded bottom bracket, fuche age
if (!liquidRenderedAt || typeof liquidRenderedAt !== 'number' || isNaN(liquidRenderedAt)) {
console.debug('STOQ - Invalid or missing liquidRenderedAt timestamp, assuming fresh');
window._RestockRocketConfig.isLiquidCacheFresh = true;
window._RestockRocketConfig.liquidCacheAge = null;
} else {
const now = Math.floor(Date.now() / 1000); // Current time in seconds
const liquidCacheAge = now - liquidRenderedAt; // Age in seconds
// Surfaced into funnel events: a stale cache means the app rendered with
// outdated inventory/selling-plan data — a real "had the opportunity but
// failed" cause. Negative (client clock ahead) clamps to 0.
window._RestockRocketConfig.liquidCacheAge = Math.max(0, liquidCacheAge);
// Handle client clock ahead of server
if (liquidCacheAge
003e\n\u003ctd\u003eSADDLE\u003c\/td\u003e\n\u003ctd\u003eSILVERADO CUSTOM\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eBRAKES\u003c\/td\u003e\n\u003ctd\u003eSRAM CODE R\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eDERAILLEUR\u003c\/td\u003e\n\u003ctd\u003eSRAM GX EAGLE\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eCASSETTE\u003c\/td\u003e\n\u003ctd\u003eSRAM GX EAGLE 1275 10-52\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eCHAIN\u003c\/td\u003e\n\u003ctd\u003eSRAM GX EAGLE\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eSHIFTER\u003c\/td\u003e\n\u003ctd\u003eSRAM GX EAGLE\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eSEATPOST\u003c\/td\u003e\n\u003ctd\u003eONEUP DROPPER POST 31.6MM \/ SM: 150MM, MD: 180MM, LG-XL: 210MM\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eBASHGUARD\u003c\/td\u003e\n\u00<1242
3ctd\u003eMRP AMG SL BASH GUIDE\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003cbr\u003e\n\u003cp class=\"Yeti-Spec_text\"\u003e\u003ci\u003ePlease note: Specifications are subject to change without notice.\u003c\/i\u003e\u003c\/p\u003e\n\u003cbr\u003e\u003cbr\u003e\n\u003cp class=\"Yeti-Title\"\u003eGEOMETRY\u003c\/p\u003e\n\u003cp class=\"Yeti-Spec_text\"\u003eAll measurements are shown in millimetres.\u003c\/p\u003e\n\u003cdiv\u003e\u003cpicture\u003e\u003csource type=\"image\/webp\" srcset=\"https:\/\/www.silverfish-uk.com\/media\/.renditions\/wysiwyg\/products\/Yeti\/SB165_GEO_ART-2023.webp\" width=\"800\" height=\"591\"\u003e\u003cimg width=\"800\" height=\"591\" src=\"https:\/\/www.silverfish-uk.com\/media\/.renditions\/wysiwyg\/products\/Yeti\/SB165_GEO_ART-2023.png\" alt=\"\" loading=\"lazy\"\u003e\u003c\/picture\u003e\u003c\/div\u003e\n\u003cbr\u003e\n\u003cdiv id=\"overflowTable\"\u003e\n\u003ctable class=\"YetiGeo\"\u003e\n\u003ctbody\u003e\n\u003ctr class=\"c\"\= LIQUID_CACHE_MAX_AGE) {
console.debug(`STOQ - Liquid cache is fresh (${Math.round(liquidCacheAge / 60)} minutes old)`);
window._RestockRocketConfig.isLiquidCacheFresh = true;
} else {
console.debug(`STOQ - Liquid cache is stale (${Math.round(liquidCacheAge / 60)} minutes old, max ${Math.round(LIQUID_CACHE_MAX_AGE / 60)} minutes)`);
window._RestockRocketConfig.isLiquidCacheFresh = false;
}
}
function checkSettingsExpiry(settings) {
try {
if (!settings || !settings.updated_at) {
console.debug('STOQ - Invalid settings data structure');
return null;
}
if (!settings.cache) {
console.debug('STOQ - settings caching disabled');
return null;
}
// Check if translations are enabled but missing from cache
// This handles the backfill period where DB has translations but metafield doesn't
if (settings.multi_language_enabled) {
if (!settings.translations) {
// Translations enabled but no
u003e\n\u003ctd\u003e\u003c\/td\u003e\n\u003ctd\u003e180MM FORK\u003c\/td\u003e\n\u003ctd\u003eSM\u003c\/td\u003e\n\u003ctd\u003eMD\u003c\/td\u003e\n\u003ctd\u003eLG\u003c\/td\u003e\n\u003ctd\u003eXL\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eA\u003c\/td\u003e\n\u003ctd\u003eSEAT TUBE LENGTH\u003c\/td\u003e\n\u003ctd\u003e365\u003c\/td\u003e\n\u003ctd\u003e400\u003c\/td\u003e\n\u003ctd\u003e440\u003c\/td\u003e\n\u003ctd\u003e470\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eB\u003c\/td\u003e\n\u003ctd\u003eEFF. TOP TUBE LENGTH\u003c\/td\u003e\n\u003ctd\u003e573\u003c\/td\u003e\n\u003ctd\u003e604\u003c\/td\u003e\n\u003ctd\u003e625\u003c\/td\u003e\n\u003ctd\u003e653\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eC\u003c\/td\u003e\n\u003ctd\u003eHEAD TUBE ANGLE\u003c\/td\u003e\n\u003ctd\u003e63.5\u003c\/td\u003e\n\u003ctd\u003e63.5\u003c\/td\u003e\n\u003ctd\u003e63.5\u003c\/td\u003e\n\u003ctd\u003e63.5\u003c\/td\u003e\translation data in metafield
// Metafield hasn't been backfilled yet - force refresh
console.debug('STOQ - multi-language enabled but no translation data in cache, fetching fresh');
return null;
}
// Translations object exists in metafield - cache is valid
// If current locale isn't translated, applyTranslations will gracefully use default locale from base fields
if (window._RestockRocketConfig.normalizedLocale &&
!Object.prototype.hasOwnProperty.call(settings.translations, window._RestockRocketConfig.normalizedLocale)) {
console.debug('STOQ - locale not explicitly translated, will use default language from cache');
}
// Don't return null - continue using cache even for untranslated locales
}
const updatedAt = new Date(settings.updated_at);
if (isNaN(updatedAt.getTime())) {
console.debug('STOQ - Invalid updated_at date format in settings');
return null;
}
const
Djibouti (DJFFdj)
n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eD\u003c\/td\u003e\n\u003ctd\u003eEFF. SEAT TUBE ANGLE\u003c\/td\u003e\n\u003ctd\u003e76.8\u003c\/td\u003e\n\u003ctd\u003e76.9\u003c\/td\u003e\n\u003ctd\u003e76.9\u003c\/td\u003e\n\u003ctd\u003e76.9\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eE\u003c\/td\u003e\n\u003ctd\u003eCHAINSTAY LENGTH\u003c\/td\u003e\n\u003ctd\u003e433\u003c\/td\u003e\n\u003ctd\u003e435\u003c\/td\u003e\n\u003ctd\u003e437\u003c\/td\u003e\n\u003ctd\u003e439\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eF\u003c\/td\u003e\n\u003ctd\u003eWHEELBASE\u003c\/td\u003e\n\u003ctd\u003e1207\u003c\/td\u003e\n\u003ctd\u003e1242\u003c\/td\u003e\n\u003ctd\u003e1266\u003c\/td\u003e\n\u003ctd\u003e1298\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eG\u003c\/td\u003e\n\u003ctd\u003eESTIMATED BB HEIGHT\u003c\/td\u003e\n\u003ctd\u003e345\u003c\/td\u003e\n\u003ctd\u003e345\u003c\/td\u003e\n\u003ctd\u003e345age = Date.now() - updatedAt.getTime();
if (age
\u003c\/td\u003e\n\u003ctd\u003e345\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eH\u003c\/td\u003e\n\u003ctd\u003eSTANDOVER\u003c\/td\u003e\n\u003ctd\u003e730\u003c\/td\u003e\n\u003ctd\u003e738\u003c\/td\u003e\n\u003ctd\u003e744\u003c\/td\u003e\n\u003ctd\u003e750\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eI\u003c\/td\u003e\n\u003ctd\u003eHEADTUBE LENGTH\u003c\/td\u003e\n\u003ctd\u003e95\u003c\/td\u003e\n\u003ctd\u003e101\u003c\/td\u003e\n\u003ctd\u003e107\u003c\/td\u003e\n\u003ctd\u003e118\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eJ\u003c\/td\u003e\n\u003ctd\u003eFORK (AXLE TO CROWN)\u003c\/td\u003e\n\u003ctd\u003e588\u003c\/td\u003e\n\u003ctd\u003e588\u003c\/td\u003e\n\u003ctd\u003e588\u003c\/td\u003e\n\u003ctd\u003e588\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eK\u003c\/td\u003e\n\u003ctd\u003eFORK (OFFSET)\u003c\/td\u003e\n\u003ctd\u003e44\u003c\/td\u003e\n\u003ctd\u003e44\<1266
Switzerland (CHFCHF)
u003c\/td\u003e\n\u003ctd\u003e44\u003c\/td\u003e\n\u003ctd\u003e44\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eL\u003c\/td\u003e\n\u003ctd\u003eSTACK\u003c\/td\u003e\n\u003ctd\u003e620\u003c\/td\u003e\n\u003ctd\u003e625\u003c\/td\u003e\n\u003ctd\u003e630\u003c\/td\u003e\n\u003ctd\u003e640\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eM\u003c\/td\u003e\n\u003ctd\u003eREACH\u003c\/td\u003e\n\u003ctd\u003e430\u003c\/td\u003e\n\u003ctd\u003e460\u003c\/td\u003e\n\u003ctd\u003e480\u003c\/td\u003e\n\u003ctd\u003e505\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"a\"\u003e\n\u003ctd\u003eN\u003c\/td\u003e\n\u003ctd\u003eFRONT CENTER\u003c\/td\u003e\n\u003ctd\u003e774\u003c\/td\u003e\n\u003ctd\u003e807\u003c\/td\u003e\n\u003ctd\u003e829\u003c\/td\u003e\n\u003ctd\u003e859\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr class=\"b\"\u003e\n\u003ctd\u003eO\u003c\/td\u003e\n\u003ctd\u003eVERTICAL FORK TRAVEL\u003c\/td\u003e\n\u003ctd\u003e152\u003c\/td\u003e SETTINGS_CACHE_DURATION) {
console.debug('STOQ - settings changed recently, skipping cache');
return null;
}
return settings;
} catch (error) {
console.debug('STOQ - Error checking settings cache:', error);
return null;
}
}
function createRestockRocketContainer() {
const restockRocketContainer = document.createElement('div');
restockRocketContainer.id = 'restock-rocket';
document.body.appendChild(restockRocketContainer);
}
function createRestockRocketScript(scriptUrl) {
const restockRocketScriptElement = document.createElement('script');
restockRocketScriptElement.setAttribute('defer', 'defer');
restockRocketScriptElement.src = scriptUrl;
document.body.appendChild(restockRocketScriptElement);
}
createRestockRocketContainer()
console.debug('STOQ - extension activated')
// Fire stoq_initialized once per page load so the funnel pipeline has a definitive
// "our code ran on this page" signal independent of any cus
\n\u003ctd\u003e152\u003c\/td\u003e\n\u003ctd\u003e152\u003c\/td\u003e\n\u003ctd\u003e152\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"data item title\" data-role=\"collapsible\" id=\"tab-label-additional\" role=\"tab\" data-collapsible=\"true\" aria-controls=\"additional\" aria-selected=\"false\" aria-expanded=\"false\" tabindex=\"0\"\u003e\u003ca class=\"data switch\" data-toggle=\"trigger\" href=\"https:\/\/www.silverfish-uk.com\/yeti-cycles-sb165-c-series-c2-factory-29-quot-27-5-quot-bike.html#additional\" id=\"tab-label-additional-title\" tabindex=\"-1\"\u003eMore Information\u003c\/a\u003e\u003c\/div\u003e\n\u003cdiv class=\"data item title\" data-role=\"collapsible\" id=\"tab-label-reviews\" role=\"tab\" data-collapsible=\"true\" aria-controls=\"reviews\" aria-selected=\"false\" aria-expanded=\"false\" tabindex=\"0\"\u003e\u003ca class=\"data switch\" data-togtomer interaction.
// Detected variants: the variants present in this page's Liquid context (product page has them;
// collection/index/etc. don't expose variants from Liquid). Used to disambiguate "embed didn't
// load" vs "embed loaded but the variant wasn't a preorder/BIS candidate" in order debug.
try {
const _stoqInitConfig = window._RestockRocketConfig;
const _stoqDetectedVariantIds = (_stoqInitConfig.product && Array.isArray(_stoqInitConfig.product.variants))
? _stoqInitConfig.product.variants.map(function(v) { return v.id })
: [];
const _stoqSelectedVariantId = _stoqInitConfig.selected_variant_id;
Shopify?.analytics?.publish?.('stoq_initialized', {
cart_token: _stoqInitConfig.cartToken || '',
page_url: window.location.href,
page_type: _stoqInitConfig.pageType || '',
shop_domain: _stoqInitConfig.shop || '',
market_id: _stoqInitConfig.marketId || '',
detected_variant_ids: _stoqDetectedVariantIds,
selected_variant_id: _stoqSele
gle=\"trigger\" href=\"https:\/\/www.silverfish-uk.com\/yeti-cycles-sb165-c-series-c2-factory-29-quot-27-5-quot-bike.html#reviews\" id=\"tab-label-reviews-title\" tabindex=\"-1\"\u003eReviews\u003c\/a\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {55196404285823 : "deny",55196404318591 : "deny",55196404351359 : "deny",55196404384127 : "deny",55196404416895 : "deny",55196404449663 : "deny",55196404482431 : "deny",55196404515199 : "deny",55196404547967 : "deny",55196404580735 : "deny",55196404613503 : "deny",55196404646271 : "deny",};
window._RestockRocketConfig.variantsInventoryQuantity = {55196404285823 : parseInt("10"),55196404318591 : parseInt("10"),55196404351359 : parseInt("10"),55196404384127 : parseInt("10"),55196404416895 : parseInt("10"),55196404449663 : parseInt("10"),55196404482431 : parseInt("10"),55196404515199 : parseInt("10"),55196404547967 : parseInt("10"),55196404580735 : parseInt("10"),55196404613503 : parseInt("1ctedVariantId || '',
liquid_rendered_at: _stoqInitConfig.liquidRenderedAt || 0,
app_version: _stoqInitConfig.appVersion || '',
liquid_cache_age: _stoqInitConfig.liquidCacheAge,
// Selected variant's stock posture as our app saw it at render — explains
// whether we *should* have treated it as a preorder candidate.
inventory_policy: (_stoqInitConfig.variantsInventoryPolicy || {})[_stoqSelectedVariantId] || '',
inventory_quantity: (_stoqInitConfig.variantsInventoryQuantity || {})[_stoqSelectedVariantId],
});
} catch (e) {
console.debug('STOQ - stoq_initialized publish failed:', e);
}
// STOQ-1595: publish stoq_accelerated_checkout_clicked for every accelerated-checkout
// click (Buy Now / dynamic checkout / Shop Pay installments) on ALL surfaces, before our
// bundle loads, via one delegated capture-phase listener (catches late-rendered buttons).
// Only on shops with preorders configured (shared `preordersConfigured` signal from the
// derivati
0"),55196404646271 : parseInt("10"),};
window._RestockRocketConfig.variantsPreorderCount = {55196404285823 : parseInt(""),55196404318591 : parseInt(""),55196404351359 : parseInt(""),55196404384127 : parseInt(""),55196404416895 : parseInt(""),55196404449663 : parseInt(""),55196404482431 : parseInt(""),55196404515199 : parseInt(""),55196404547967 : parseInt(""),55196404580735 : parseInt(""),55196404613503 : parseInt(""),55196404646271 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderCountForMarket = {55196404285823 : null,55196404318591 : null,55196404351359 : null,55196404384127 : null,55196404416895 : null,55196404449663 : null,55196404482431 : null,55196404515199 : null,55196404547967 : null,55196404580735 : null,55196404613503 : null,55196404646271 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {55196404285823 : parseInt(""),55196404318591 : parseInt(""),55196404351359 : parseInt(""),55196404384127 : parseInt(""),55196404416895 : parseInt(""),55196404449663 : parseon block above) — nothing to bypass otherwise. variant_id is read per-clicked-button
// from its form so it's correct on collection/index/search too. block_accelerated_checkout
// context (STOQ-1612) rides in `properties` (forwarded verbatim by the pixel, no schema
// change): a buy_now click on a preorder variant while the gate was armed is a visible
// bypass signal for order debug. Also sends page_url (top-level, like the pixel's native
// events) and two preorder signals in properties (see below).
try {
var _sqTrack = window._RestockRocketConfig;
if (_sqTrack.preordersConfigured) {
document.addEventListener('click', function (e) {
try {
var t = e.target;
if (!t || !t.closest) return;
var host = t.closest('.shopify-payment-button, shopify-payment-terms');
if (!host) return;
var channel = host.matches && host.matches('shopify-payment-terms')
? 'shop_pay_installments' : 'buy_now';
var form = host.close1298
Int(""),55196404482431 : parseInt(""),55196404515199 : parseInt(""),55196404547967 : parseInt(""),55196404580735 : parseInt(""),55196404613503 : parseInt(""),55196404646271 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {55196404285823 : null,55196404318591 : null,55196404351359 : null,55196404384127 : null,55196404416895 : null,55196404449663 : null,55196404482431 : null,55196404515199 : null,55196404547967 : null,55196404580735 : null,55196404613503 : null,55196404646271 : null,};
window._RestockRocketConfig.variantsShippingText = {55196404285823 : "",55196404318591 : "",55196404351359 : "",55196404384127 : "",55196404416895 : "",55196404449663 : "",55196404482431 : "",55196404515199 : "",55196404547967 : "",55196404580735 : "",55196404613503 : "",55196404646271 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {55196404285823 : null,55196404318591 : null,55196404351359 : null,55196404384127 : null,55196404416895 : null,55196404449663 : null,5st('form');
var vidEl = form && form.querySelector('[name="id"]');
var variantId = (vidEl && vidEl.value) || _sqTrack.selected_variant_id || '';
// The enabled STOQ selling plan the clicked variant belongs to (if any), found once and
// reused for in_enabled_plan / enrolled_plan_id / enrolled_plan_provider below.
var _sqVidNum = Number(variantId);
var _sqPlan = null;
// Array.isArray guard (not `|| []`) so a truthy non-array sellingPlans can't throw and
// silently drop the whole publish.
var _sqPlans = Array.isArray(_sqTrack.sellingPlans) ? _sqTrack.sellingPlans : [];
_sqPlans.forEach(function (pl) {
if (!_sqPlan && pl && pl.enabled && Array.isArray(pl.variant_ids) &&
pl.variant_ids.indexOf(_sqVidNum) !== -1) { _sqPlan = pl; }
});
Shopify?.analytics?.publish?.('stoq_accelerated_checkout_clicked', {
variant_id: variantId,
product_id: (_sqTr
5196404482431 : null,55196404515199 : null,55196404547967 : null,55196404580735 : null,55196404613503 : null,55196404646271 : null,};
window._RestockRocketConfig.selected_variant_id = 55196404285823;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;// STOQ-1595/1612 shared signal, derived once here so both the accelerated-checkout block
// gate (STOQ-1612) and the click tracker (STOQ-1595) read one clearly-owned flag rather
// than a side effect buried in either consumer's try/catch: whether this shop has preorders
// configured at all — an enabled selling plan plus at least one preorder variant id,
// independent of the block toggle. Fail-open: on error the flag stays unset and both
// consumers no-op.
try {
var _sqCfg = window._RestockRocketConfig;
var _sqPlanEnabled = Array.isArray(_sqCfg.sellingPlans) &&
_sqCfg.sack.product && _sqTrack.product.id) || '',
channel: channel,
market_id: _sqTrack.marketId || '',
page_type: _sqTrack.pageType || '',
cart_token: _sqTrack.cartToken || '',
page_url: (window.location && window.location.href) || '',
properties: {
// Mirror the bundle's own preorder check (preorder.js checkInventoryProvider-
// WithCachedFallback): the live set config.preorderVariantIds (refreshed after
// page load by loadVariantInventoryData) OR the Liquid-injected
// cachedPreorderVariantIds — always present, so it covers clicks before the
// bundle loads (why this tracker is inline). ORing both (not preferring one)
// matches the bundle and is correct even if the live set is an empty array. Both
// hold integer ids; the click-time id comes off a DOM input (.value → string) or
// selected_variant_id, so coerce with Number for
Egypt (EGPج.م)
ellingPlans.some(function (p) { return p && p.enabled; });
var _sqPreCount = ((_sqCfg.cachedPreorderVariantIds &&
_sqCfg.cachedPreorderVariantIds.preorder_variant_ids) || []).length;
_sqCfg.preordersConfigured = !!(_sqPlanEnabled && _sqPreCount);
} catch (e) { /* fail open */ }
// STOQ-1612: block (not hide) Buy Now / Shop Pay until our JS runs, so a tap in the
// load window can't bypass preorder. pointer-events via .stoq-buy-now-pending (no
// reflow); timeout releases; renderPreorderButton / featured_product.js lift it.
// Gated by the `block_accelerated_checkout` toggle (default OFF) for gradual rollout.
// Armed ONLY when we're sure preorder is in play — product page: THIS product has a
// preorder variant (never block a plain product's Shop Pay); featured: integration
// enabled for this page type. Rationale: PR #2784.
try {
var _sqc = window._RestockRocketConfig;
var _sqOn = !!(_sqc.cachedSettings && _sqc.cachedSettings.block_accelerated_checkout);
var _sq a like-typed compare.
is_preorder_variant: (function () {
var vid = Number(variantId);
var has = function (a) { return Array.isArray(a) && a.indexOf(vid) !== -1; };
return has(_sqTrack.preorderVariantIds) ||
has(_sqTrack.cachedPreorderVariantIds &&
_sqTrack.cachedPreorderVariantIds.preorder_variant_ids);
})(),
// Narrow, authoritative preorder signal: enrolled in an ENABLED STOQ selling plan
// (is_preorder_variant above is the broad OOS+continue heuristic — non-STOQ too).
in_enabled_plan: !!_sqPlan,
// In-stock preorder signal: enrolled but currently IN STOCK (in the inStockVariantIds
// set, not the OOS preorderVariantIds set). Same live-OR-cached pattern as
// is_preorder_variant. is_preorder_variant OR is_instock_variant = "should sell via
// the plan" regardless of stock, so an in-stock preord
Pre = (_sqc.cachedPreorderVariantIds &&
_sqc.cachedPreorderVariantIds.preorder_variant_ids) || [];
var _sqArm = false;
if (_sqOn && _sqc.preordersConfigured) {
if (_sqc.pageType === 'product' && _sqc.product && _sqc.product.variants) {
_sqArm = _sqc.product.variants.some(function (v) { return _sqPre.indexOf(Number(v.id)) !== -1; });
} else {
_sqArm = (_sqc.integrations || []).some(function (i) {
return i && i.type === 'featured_product' && i.enabled &&
Array.isArray(i.page_types) && i.page_types.indexOf(_sqc.pageType) !== -1;
});
}
}
if (_sqArm && document.documentElement) {
_sqc.acceleratedGateArmed = true;
document.documentElement.classList.add('stoq-buy-now-pending');
setTimeout(function () {
document.documentElement.classList.remove('stoq-buy-now-pending');
}, 6000);
}
} catch (e) { /* fail open */ }
window._RestockRocketConfig.scriptUrlProduct = 'https://cdn.shopify.com/extensioner bypass is detectable too.
is_instock_variant: (function () {
var has = function (a) { return Array.isArray(a) && a.indexOf(_sqVidNum) !== -1; };
return has(_sqTrack.inStockVariantIds) ||
has(_sqTrack.cachedInStockVariantIds &&
_sqTrack.cachedInStockVariantIds.in_stock_variant_ids);
})(),
// The enrolled plan's Shopify selling-plan id + inventory_provider (stoq = STOQ tracks
// the OOS count; shopify = in-stock preorder). Tells order-debug what kind of preorder
// the Buy Now bypassed, without a downstream lookup.
enrolled_plan_id: (_sqPlan && (_sqPlan.shopify_selling_plan_id || _sqPlan.shopify_selling_plan_group_id)) || '',
enrolled_plan_provider: (_sqPlan && _sqPlan.inventory_provider) || '',
block_enabled: !!(_sqTrack.cachedSettings && _sqTrack.cachedSettings.block_accelerated_checkout),
gate_armed: !!_sqTrack.a
Tanzania (TZSSh)
s/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection.js'
window._RestockRocketConfig.scriptUrlProductBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-product-bis.js'
window._RestockRocketConfig.scriptUrlCollectionBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection-bis.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when present, mirroring the same
// override in assets/js/api.js. cachedSettings is populated acceleratedGateArmed,
gate_active_at_click: !!(document.documentElement &&
document.documentElement.classList.contains('stoq-buy-now-pending')),
},
});
} catch (err) { /* never break checkout */ }
}, true);
}
} catch (e) { /* fail open */ }
function applyTranslations(settings) {
try {
// Skip translation logic entirely if multi-language is not enabled
if (!settings || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translations found, skipping translation');
return settings;
}
const normalizedLocale = window._RestockRocketConfig.normalizedLocale;
const translations = settings.translations;
if (!normalizedLocale) {
// No matching locale has translations; drop payload to save memory
console.debug('STOQ - No matching locale for translations. Available:', Object.keys(translations || {})
bove. Falls
// back to the build-baked host for shops without the use_render_api_host
// toggle (or environments where THEME_EXTENSION_API_HOST is unset), so the
// setting.json + fetchEmbedConfig calls below route to the same host as the
// rest of the extension's API traffic instead of staying on the baked host.
window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://app.restockrocket.io'
// Deployed extension build number, read from the CDN asset host Shopify generates:
// https://cdn.shopify.com/extensions/);
delete settings.translations;
return settings;
}
console.debug(`STOQ - Applying translations for normalized locale: ${normalizedLocale} (original: ${window._RestockRocketConfig.locale})`);
const translatedFields = translations[normalizedLocale];
if (translatedFields && typeof translatedFields === 'object') {
Object.keys(translatedFields).forEach(function(key) {
const value = translatedFields[key];
if (value !== null && value !== undefined && value !== '') {
settings[key] = value;
}
});
} else {
console.debug('STOQ - No translated fields found for locale:', normalizedLocale);
}
delete settings.translations;
return settings;
} catch (e) {
console.debug('STOQ - error applying translations:', e);
return settings;
}
}
// Setup event listener for cart selling plan updates
// This must be called before any scripts are loaded to avoid race conditions
func
{
if (hasUpdates) {
console.debug('STOQ - cart selling plans updated successfully');
} else {
console.debug('STOQ - no cart selling plan updates needed');
}
})
.catch(error => {
console.error('STOQ - error updating cart selling plans:', error);
});
}
});
}
// ---- Live settings via the Storefront API (ad
uuid>/ditive, does not gate init) ----
// The inlined `cachedSettings` comes from the app-embed Liquid render, which
// Shopify edge-caches and can serve stale. Reading the same `settings` metafield
// back over the Storefront API is a POST to /api/G
<<
handle>-version>/graphql.json — never
// CDN-cached — so it returns the live value on every page load. We fetch it
// best-effort and stash it on `window._RestockRocketConfig.storefrontSettings`
// so individual behaviours can migrate onto the fresh value over time. This is
// PURELY ADDITIVE: it does NOT change the resolution flow below, never blocks
// init, and silently no-ops on any failure / missing token.
(function loadStorefrontSettings() {
const cfg = window._RestockRocketConfig;
if (!cfg.storefrontAccessToken || cfg.disableStorefrontApi === true) return;
// Deferred to browser idle so this best-effort read runs strictly AFTER the
// critical init flow and never competes with it for a connection — the call
// is a live, uncached Storefront round-trip and can be slow (multi-second
// TTFB observed). Nothing on the critical path waits for it.
function run() {
const query = 'query StoqSettings($namespace: String!) { shop { metafield(namespace: $namespace, key:
Equatorial Guinea (XAFCFA)
< "settings") { value } } }';
fetch(
`https://${cfg.shop}/api/2025-07/graphql.json`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': cfg.storefrontAccessToken,
},
body: JSON.stringify({ query: query, variables: { namespace: cfg.metafieldNamespace } }),
}
)
.then(function(response) {
if (!response.ok) { throw new Error('Storefront API HTTP ' + response.status); }
return response.json();
})
.then(function(body) {
if (body && body.errors && body.errors.length) {
throw new Error('Storefront API errors: ' + body.errors.map(function(e) { return e && e.message; }).join(', '));
}
const value = body && body.data && body.data.shop && body.data.shop.metafield && body.data.shop.metafield.value;
if (!value) { throw new Error('Storefront API returned no settings metafield value'); }
cfg.sto
version>/assets/...
// Trailing digits (e.g. ".../restockrocket-1-521/assets/" -> "521"). Kept numeric to
// match ParseStoqData, so funnel app_version lines up with the order-attribution
// app_version. Reflects the ACTUAL deployed build. This is the SINGLE source of the
// parsed version — preorder.js getAppVersion() reads it back off config rather than
// re-parsing, so the regex lives in exactly one place.
try {
const _stoqVersionMatch = window._RestockRocketConfig.scriptHost.match(/(\d+)\/?(?:assets\/?)?$/);
window._RestockRocketConfig.appVersion = (_stoqVersionMatch && _stoqVersionMatch[1]) || '';
} catch (e) {
window._RestockRocketConfig.appVersion = '';
}
const SETTINGS_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds
const LIQUID_CACHE_MAX_AGE = 15 * 60; // 15 minutes in seconds
// Calculate Liquid cache freshness once at initialization
const liquidRenderedAt = window._RestockRocketConfig.liquidRenderedAt;
// Validate timestamp and calculate carefrontSettings = JSON.parse(value);
console.debug('STOQ - stored live settings from Storefront API on config.storefrontSettings');
})
.catch(function(e) {
console.debug('STOQ - Storefront settings fetch failed (non-fatal):', e && e.message);
});
}
if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(run, { timeout: 5000 });
} else {
setTimeout(run, 0);
}
})();
// First try to get settings from metafields with expiry check
const cachedSettings = window._RestockRocketConfig.cachedSettings;
const validCachedSettings = cachedSettings ? checkSettingsExpiry(cachedSettings) : null;
if (validCachedSettings) {
console.debug('STOQ - using cached settings');
initializeScripts(validCachedSettings);
} else {
console.debug('STOQ - fetching fresh settings');
const headers = {
'X-Shopify-Shop-Domain': window._RestockRocketConfig.shop || window.Shopify.shop,
'ngrok-skip-browser-warning': 'skiESTIMATED BB HEIGHT
Togo (XOFFr)
che age
if (!liquidRenderedAt || typeof liquidRenderedAt !== 'number' || isNaN(liquidRenderedAt)) {
console.debug('STOQ - Invalid or missing liquidRenderedAt timestamp, assuming fresh');
window._RestockRocketConfig.isLiquidCacheFresh = true;
window._RestockRocketConfig.liquidCacheAge = null;
} else {
const now = Math.floor(Date.now() / 1000); // Current time in seconds
const liquidCacheAge = now - liquidRenderedAt; // Age in seconds
// Surfaced into funnel events: a stale cache means the app rendered with
// outdated inventory/selling-plan data — a real "had the opportunity but
// failed" cause. Negative (client clock ahead) clamps to 0.
window._RestockRocketConfig.liquidCacheAge = Math.max(0, liquidCacheAge);
// Handle client clock ahead of server
if (liquidCacheAge p'
};
if (window.Shopify?.theme?.role === 'main') {
headers['X-Shopify-Theme-Schema-Name'] = window.Shopify.theme.schema_name;
headers['X-Shopify-Theme-Schema-Version'] = window.Shopify.theme.schema_version;
headers['X-Shopify-Theme-Store-Id'] = window.Shopify.theme.theme_store_id;
}
fetch(
`${window._RestockRocketConfig.host}/api/v1/setting.json?translation_locale=${window._RestockRocketConfig.normalizedLocale}`,
{ headers }
)
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(settings) {
initializeScripts(settings);
})
.catch(function(error) {
// If request failed and we have cached settings (even if expired), use them as fallback
if (cachedSettings) {
console.debug('STOQ - using expired cached settings as fallback');
initializeScripts(cachedSettings);
} else {
console.error('S
translation data in metafield
// Metafield hasn't been backfilled yet - force refresh
console.debug('STOQ - multi-language enabled but no translation data in cache, fetching fresh');
return null;
}
// Translations object exists in metafield - cache is valid
// If current locale isn't translated, applyTranslations will gracefully use default locale from base fields
if (window._RestockRocketConfig.normalizedLocale &&
!Object.prototype.hasOwnProperty.call(settings.translations, window._RestockRocketConfig.normalizedLocale)) {
console.debug('STOQ - locale not explicitly translated, will use default language from cache');
}
// Don't return null - continue using cache even for untranslated locales
}
const updatedAt = new Date(settings.updated_at);
if (isNaN(updatedAt.getTime())) {
console.debug('STOQ - Invalid updated_at date format in settings');
return null;
}
const n,
// an enabled offer exists, or a disabled-but-kept plan id remains (cart sweep
// must still strip those). Rationale in the PR.
const hasEnabledOffer = Array.isArray(window._RestockRocketConfig.sellingPlans)
&& window._RestockRocketConfig.sellingPlans.some(function(plan) { return plan && plan.enabled; });
const hasDisabledPlanIds = Array.isArray(window._RestockRocketConfig.disabledSellingPlanIds)
&& window._RestockRocketConfig.disabledSellingPlanIds.length > 0;
const usePreorderBuild = settings.preorder_enabled || hasEnabledOffer || hasDisabledPlanIds;
const collectionScriptUrl = usePreorderBuild
? window._RestockRocketConfig.scriptUrlCollection
: window._RestockRocketConfig.scriptUrlCollectionBis;
const productScriptUrl = usePreorderBuild
? window._RestockRocketConfig.scriptUrlProduct
: window._RestockRocketConfig.scriptUrlProductBis;
const pageType = window._RestockRocketConfig.pageType;
const collecti
Eritrea (GBP£)
age = Date.now() - updatedAt.getTime();
if (age onPageTypes = ['collection', 'index', 'search', 'page'];
if(collectionPageTypes.indexOf(pageType) !== -1 && (settings[`show_button_on_${pageType}`] || settings[`preorder_${pageType}_enabled`])) {
createRestockRocketScript(collectionScriptUrl);
} else if(pageType === 'product') {
createRestockRocketScript(productScriptUrl);
} else if(hijackIntegration) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(usePreorderBuild) {
// cart/article/blog/list-collections: full build so the cart sweep runs.
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else {
console.debug(`STOQ - no scripts enabled for ${pageType}`);
}
// Dispatch custom event when app is loaded
// Cart selling plan updates will be triggered by stoq:inventory-data-loaded event
const appLoadedEvent = new CustomEvent('stoq:loaded', {
detail: {
pageType: window._RestockR
ack.product && _sqTrack.product.id) || '',
channel: channel,
market_id: _sqTrack.marketId || '',
page_type: _sqTrack.pageType || '',
cart_token: _sqTrack.cartToken || '',
page_url: (window.location && window.location.href) || '',
properties: {
// Mirror the bundle's own preorder check (preorder.js checkInventoryProvider-
// WithCachedFallback): the live set config.preorderVariantIds (refreshed after
// page load by loadVariantInventoryData) OR the Liquid-injected
// cachedPreorderVariantIds — always present, so it covers clicks before the
// bundle loads (why this tracker is inline). ORing both (not preferring one)
// matches the bundle and is correct even if the live set is an empty array. Both
// hold integer ids; the click-time id comes off a DOM input (.value → string) or
// selected_variant_id, so coerce with Number for
html.stoq-buy-now-pending .shopify-payment-button{pointer-events:none!important}.stoq-hide-buy-now .shopify-payment-button{display:none!important}.restock-rocket-button,.restock-rocket-button-float{opacity:1!important;border:none!important;cursor:pointer!important;background-image:none!important;box-shadow:none!important;padding:15px 20px;font-size:16px;width:100%;font-family:inherit}@font-face{font-family:OpenSans;font-weight:200;src:url(https://d382hokyqag45a.cloudfront.net/assets/OpenSans-Light.woff)}@font-face{font-family:OpenSans;font-weight:300;src:url(https://d382hokyqag45a.cloudfront.net/assets/OpenSans-Regular.woff)}@font-face{font-family:OpenSans;font-weight:600;src:url(https://d382hokyqag45a.cloudfront.net/assets/OpenSans-SemiBold.woff)}.restock-rocket-button-container{position:relative;z-index:1;width:100%}.restock-rocket-button-container-float-right{position:fixed;z-index:123123;top:calc(50% - 200px);right:0;transform:rotate(270deg);transform-origin:bottom right}.restock-rocket-button-container-float-left{position:fixed;z-index:123123;top:calc(50% - 200px);left:40px;transform:rotate(90deg);transform-origin:top left}.restock-rocket-button-container-float-left:hover,.restock-rocket-button-container-float-right:hover,.restock-rocket-button-container:hover,.restock-rocket-button-float:hover,.restock-rocket-button:hover{opacity:.8}.restock-rocket-button{min-height:50p
Estonia (EUR€)
a like-typed compare.
is_preorder_variant: (function () {
var vid = Number(variantId);
var has = function (a) { return Array.isArray(a) && a.indexOf(vid) !== -1; };
return has(_sqTrack.preorderVariantIds) ||
has(_sqTrack.cachedPreorderVariantIds &&
_sqTrack.cachedPreorderVariantIds.preorder_variant_ids);
})(),
// Narrow, authoritative preorder signal: enrolled in an ENABLED STOQ selling plan
// (is_preorder_variant above is the broad OOS+continue heuristic — non-STOQ too).
in_enabled_plan: !!_sqPlan,
// In-stock preorder signal: enrolled but currently IN STOCK (in the inStockVariantIds
// set, not the OOS preorderVariantIds set). Same live-OR-cached pattern as
// is_preorder_variant. is_preorder_variant OR is_instock_variant = "should sell via
// the plan" regardless of stock, so an in-stock preord
er bypass is detectable too.
is_instock_variant: (function () {
var has = function (a) { return Array.isArray(a) && a.indexOf(_sqVidNum) !== -1; };
return has(_sqTrack.inStockVariantIds) ||
has(_sqTrack.cachedInStockVariantIds &&
_sqTrack.cachedInStockVariantIds.in_stock_variant_ids);
})(),
// The enrolled plan's Shopify selling-plan id + inventory_provider (stoq = STOQ tracks
// the OOS count; shopify = in-stock preorder). Tells order-debug what kind of preorder
// the Buy Now bypassed, without a downstream lookup.
enrolled_plan_id: (_sqPlan && (_sqPlan.shopify_selling_plan_id || _sqPlan.shopify_selling_plan_group_id)) || '',
enrolled_plan_provider: (_sqPlan && _sqPlan.inventory_provider) || '',
block_enabled: !!(_sqTrack.cachedSettings && _sqTrack.cachedSettings.block_accelerated_checkout),
gate_armed: !!_sqTrack.a345
px solid #ebebeb;}.restock-rocket-payment-input-container{flex:1 1 auto;min-width:0}.restock-rocket-preorder-discount-badge{background:#ebebeb;height:25px;line-height:25px;padding:0 15px;border-radius:25px;font-size:0.8rem;flex:0 0 auto}.restock-rocket-payment-input{margin-right:10px;margin-top:-3px;vertical-align:middle;margin-left:0;accent-color:#202223}.restock-rocket-payment-description{margin-top:4px;flex:1 1 100%}.restock-rocket-preorder-badge{font-size:13px;line-height:1;padding:5px 13px 6px;border-radius:40px;height:auto;border:none;width:auto;z-index:2;margin:0;background:0 0}.preorder-badge-collection{position:absolute;top:10px;right:10px}.preorder-badge-product{margin-left:10px}.restock-rocket-price-strike{text-decoration:line-through;color: #666666;}.restock-rocket-discounted-price{margin-left:10px;}.restock-rocket-acknowledgement-checkbox{margin-bottom:12px;display:flex;align-items:flex-start;gap:8px;font-size:14px;line-height: 1.5;}.restock-rocket-acknowledge-checkbox-input{width:18px;height:18pTunisia (GBP£)
cceleratedGateArmed,
gate_active_at_click: !!(document.documentElement &&
document.documentElement.classList.contains('stoq-buy-now-pending')),
},
});
} catch (err) { /* never break checkout */ }
}, true);
}
} catch (e) { /* fail open */ }
function applyTranslations(settings) {
try {
// Skip translation logic entirely if multi-language is not enabled
if (!settings || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translations found, skipping translation');
return settings;
}
const normalizedLocale = window._RestockRocketConfig.normalizedLocale;
const translations = settings.translations;
if (!normalizedLocale) {
// No matching locale has translations; drop payload to save memory
console.debug('STOQ - No matching locale for translations. Available:', Object.keys(translations || {})
);
delete settings.translations;
return settings;
}
console.debug(`STOQ - Applying translations for normalized locale: ${normalizedLocale} (original: ${window._RestockRocketConfig.locale})`);
const translatedFields = translations[normalizedLocale];
if (translatedFields && typeof translatedFields === 'object') {
Object.keys(translatedFields).forEach(function(key) {
const value = translatedFields[key];
if (value !== null && value !== undefined && value !== '') {
settings[key] = value;
}
});
} else {
console.debug('STOQ - No translated fields found for locale:', normalizedLocale);
}
delete settings.translations;
return settings;
} catch (e) {
console.debug('STOQ - error applying translations:', e);
return settings;
}
}
// Setup event listener for cart selling plan updates
// This must be called before any scripts are loaded to avoid race conditions
func
countdown-box{min-width:55px;padding:14px 10px;font-size:26px}.restock-rocket-preorder-countdown-timer .countdown-label{font-size:11px}}@media (max-width:480px){.restock-rocket-preorder-countdown-timer{padding:12px}.restock-rocket-preorder-countdown-timer .countdown-units{width:100%;gap:10px}.restock-rocket-preorder-countdown-timer .countdown-box{width:100%;min-width:50px;padding:12px 8px;font-size:24px}.restock-rocket-preorder-countdown-timer .countdown-label{font-size:10px}}.restock-rocket-toast{position:fixed;cursor:pointer;background:#fff;border:0;min-width:40px;min-height:40px;box-shadow:0 0 15px rgba(0,0,0,.1)!important;z-index:622004;padding:20px 30px;font-family:inherit;font-size:inherit;color:#000;display:flex;justify-content:center;align-items:center}.restock-rocket-toast a{text-decoration:none;font-weight:700;color:#000}.restock-rocket-toast .dismiss{margin-left:15px;z-index:1;font-size:20px;}.restock-rocket-toast-top{top:60px}.restock-rocket-toast-bottom{bottom:75px}.restock-rocket-toast-left,.res
tion setupCartSellingPlanUpdater(settings) {
// Setup listener regardless - updateCartSellingPlans has its own guards
// This ensures cleanup happens even when preorders are disabled globally
// Listen for stoq:inventory-data-loaded event dispatched by api.js
window.addEventListener('stoq:inventory-data-loaded', function(event) {
console.debug('STOQ - Inventory data loaded, updating cart selling plans');
if (window._RestockRocket && window._RestockRocket.updateCartSellingPlans) {
window._RestockRocket.updateCartSellingPlans()
.then(hasUpdates => {
if (hasUpdates) {
console.debug('STOQ - cart selling plans updated successfully');
} else {
console.debug('STOQ - no cart selling plan updates needed');
}
})
.catch(error => {
console.error('STOQ - error updating cart selling plans:', error);
});
}
});
}
// ---- Live settings via the Storefront API (ad
ditive, does not gate init) ----
// The inlined `cachedSettings` comes from the app-embed Liquid render, which
// Shopify edge-caches and can serve stale. Reading the same `settings` metafield
// back over the Storefront API is a POST to /api/
kit-transform:translateX(0)}100%{-webkit-transform:translateX(100%)}}.restock-rocket-preorder-progress-bar{padding:12px 15px;margin-bottom:20px;font-family:inherit;}.restock-rocket-preorder-progress-bar .preorder-progress-text{margin-bottom:8px;}.restock-rocket-preorder-progress-bar .preorder-progress-bar-row{display:flex;align-items:center;gap:10px;}.restock-rocket-preorder-progress-bar .preorder-progress-track{flex:1;height:12px;overflow:hidden;}.restock-rocket-preorder-progress-bar .preorder-progress-fill{display:block;height:100%;min-width:2px;transition:width 0.3s ease;}.restock-rocket-preorder-progress-bar .preorder-progress-percentage{font-weight:500;min-width:35px;text-align:right;}
<
version>/graphql.json — never
// CDN-cached — so it returns the live value on every page load. We fetch it
// best-effort and stash it on `window._RestockRocketConfig.storefrontSettings`
// so individual behaviours can migrate onto the fresh value over time. This is
// PURELY ADDITIVE: it does NOT change the resolution flow below, never blocks
// init, and silently no-ops on any failure / missing token.
(function loadStorefrontSettings() {
const cfg = window._RestockRocketConfig;
if (!cfg.storefrontAccessToken || cfg.disableStorefrontApi === true) return;
// Deferred to browser idle so this best-effort read runs strictly AFTER the
// critical init flow and never competes with it for a connection — the call
// is a live, uncached Storefront round-trip and can be slow (multi-second
// TTFB observed). Nothing on the critical path waits for it.
function run() {
const query = 'query StoqSettings($namespace: String!) { shop { metafield(namespace: $namespace, key:
Eswatini (GBP£)
"settings") { value } } }';
fetch(
`https://${cfg.shop}/api/2025-07/graphql.json`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Shopify-Storefront-Access-Token': cfg.storefrontAccessToken,
},
body: JSON.stringify({ query: query, variables: { namespace: cfg.metafieldNamespace } }),
}
)
.then(function(response) {
if (!response.ok) { throw new Error('Storefront API HTTP ' + response.status); }
return response.json();
})
.then(function(body) {
if (body && body.errors && body.errors.length) {
throw new Error('Storefront API errors: ' + body.errors.map(function(e) { return e && e.message; }).join(', '));
}
const value = body && body.data && body.data.shop && body.data.shop.metafield && body.data.shop.metafield.value;
if (!value) { throw new Error('Storefront API returned no settings metafield value'); }
cfg.sto
H
p'
};
if (window.Shopify?.theme?.role === 'main') {
headers['X-Shopify-Theme-Schema-Name'] = window.Shopify.theme.schema_name;
headers['X-Shopify-Theme-Schema-Version'] = window.Shopify.theme.schema_version;
headers['X-Shopify-Theme-Store-Id'] = window.Shopify.theme.theme_store_id;
}
fetch(
`${window._RestockRocketConfig.host}/api/v1/setting.json?translation_locale=${window._RestockRocketConfig.normalizedLocale}`,
{ headers }
)
.then(function(response) {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(function(settings) {
initializeScripts(settings);
})
.catch(function(error) {
// If request failed and we have cached settings (even if expired), use them as fallback
if (cachedSettings) {
console.debug('STOQ - using expired cached settings as fallback');
initializeScripts(cachedSettings);
} else {
console.error('STürkiye (GBP£)
endpoint + ':', applyError);
throw applyError;
}
})
.catch(function(error) {
console.debug(`STOQ - using cached ${endpoint}:`, error.message);
});
}
function initializeScripts(settings) {
settings = applyTranslations(settings);
window._RestockRocketConfig.settings = settings;
console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`);
// Stale-Liquid resilience (default-on, per-shop opt-out via the
// `disable_refresh_on_stale_liquid` Toggle, surfaced as the negative
// `disable_refresh_on_stale_liquid` flag in settings.json so that
// `undefined` -- in CDN-cached metafield payloads that predate this
// key -- reads as `!undefined === true` and gets default-on behavior
// immediately, no metafield rewrite required).
// When the Liquid CDN cache is older than LIQUID_CACHE_MAX_AGE the in-page
// selling_plans / integrations metafields can be wrong; refresh both from
// the API before launching scr
STANDOVER
}
}),
fetchEmbedConfig('integrations', function(data) {
if (Array.isArray(data)) {
window._RestockRocketConfig.integrations = data;
}
})
]),
new Promise(function(resolve) { setTimeout(resolve, 1000); })
]).then(function() { loadScripts(settings); });
return;
}
loadScripts(settings);
}
function loadScripts(settings) {
// Setup cart selling plan updater BEFORE loading any scripts to avoid race conditions
setupCartSellingPlanUpdater(settings);
if(settings.enable_app) {
const hijackIntegration = window._RestockRocketConfig.integrations.find(function(integration) {
return integration.type === 'hijack' && integration.enabled && integration.page_types.includes(window._RestockRocketConfig.pageType);
})
// STOQ-1520: serve the lean back-in-stock-only build (no preorder/hijack code)
// only to shops with NO preorder plans. Use the full build if preorder is o
Ethiopia (ETBBr)
onPageTypes = ['collection', 'index', 'search', 'page'];
if(collectionPageTypes.indexOf(pageType) !== -1 && (settings[`show_button_on_${pageType}`] || settings[`preorder_${pageType}_enabled`])) {
createRestockRocketScript(collectionScriptUrl);
} else if(pageType === 'product') {
createRestockRocketScript(productScriptUrl);
} else if(hijackIntegration) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(usePreorderBuild) {
// cart/article/blog/list-collections: full build so the cart sweep runs.
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else {
console.debug(`STOQ - no scripts enabled for ${pageType}`);
}
// Dispatch custom event when app is loaded
// Cart selling plan updates will be triggered by stoq:inventory-data-loaded event
const appLoadedEvent = new CustomEvent('stoq:loaded', {
detail: {
pageType: window._RestockR
Uganda (UGXUSh)
Ukraine (UAH₴)
750
Finland (EUR€)
Mayotte (EUR€)
Moldova (MDLL)
You May Also Like
Monaco (EUR€)
Recently viewed
Montenegro (EUR€)
Close
Morocco (MADد.م.)
Mozambique (GBP£)
Namibia (GBP£)
Netherlands (EUR€)
window._RestockRocketConfig = window._RestockRocketConfig || {}
// Stoq is the current name of the app (RestockRocket is the legacy name).
// Expose _Stoq / _StoqConfig as live aliases of the same objects so both names
// work. Done here, before the JS bundles run, and the bundles only ever do
// `window._RestockRocket = window._RestockRocket || {}` (never reassign), so
// every method/config added later is visible on both names.
window._RestockRocket = window._RestockRocket || {}
window._Stoq = window._RestockRocket
window._StoqConfig = window._RestockRocketConfig
// Helper function to normalize locale format from hyphen to underscore (e.g., 'en-US' -> 'en_us')
// This matches the backend's Mobility.normalize_locale behavior
// Returns empty string if locale is empty or invalid (matches original behavior)
function normalizeLocale(locale) {
if (!locale || locale.trim() === '') {
return '';
}
return locale.toString().toLowerCase().replace(/-/g, '_');
}
window._RestockRocketConfig.locale = 'en';
window._RestockRocketConfig.normalizedLocale = normalizeLocale('en');
window._RestockRocketConfig.shop = 'projektride.myshopify.com';
window._RestockRocketConfig.pageType = 'product';
window._RestockRocketConfig.liquidRenderedAt = 1783549812;window._RestockRocketConfig.marketId = 382140642;window._RestockRocketConfig.countryName = 'United Kingdom';
window._RestockRocketConfig.countryIsoCode = 'GB';window._RestockRocketConfig.cartInventoryQuantity = {};// cart.token falls back to the `cart` cookie when the Liquid context didn't carry one
// (some page types render with cart={} until first interaction).
if (!window._RestockRocketConfig.cartToken) {
try {
const m = document.cookie.match(/(?:^|;\s*)cart=([^;]+)/);
if (m && m[1]) window._RestockRocketConfig.cartToken = decodeURIComponent(m[1]);
} catch (e) { /* cookie unavailable */ }
}window._RestockRocketConfig.cachedSettings = {"id":38500,"shop_id":38436,"currency":"GBP","created_at":"2025-07-26T09:13:57.337Z","updated_at":"2025-12-28T14:44:23.508Z","enable_app":true,"enable_signup_widget":false,"storefront_button_text":"Notify me when available","storefront_button_text_color":"#FFFFFF","storefront_button_background_color":"#202223","storefront_form_header":"Notify me","storefront_form_description":"Get a notification as soon as this product is back in stock by signing up below!","storefront_form_button_text":"Notify me when available","storefront_form_button_text_color":"#FFFFFF","storefront_form_button_background_color":"#202223","storefront_form_terms":"Promise we won't spam. You'll only receive notifications for this product.","storefront_form_error":"Please enter a valid email address","storefront_form_success":"Thank you! We will notify you when the product is available.","enable_powered_by":true,"show_button_on_preorder":true,"sms_enabled":false,"email_enabled":true,"storefront_button_disable_tag":"rocket-hide","theme_config":{"disableDebugLoggingForNonPreorderItem":false},"storefront_form_email_placeholder":"Email address","storefront_form_phone_placeholder":"SMS","storefront_form_phone_label":"Phone number","storefront_form_email_label":"Email","storefront_form_phone_error":"Please enter a valid phone number","storefront_form_customer_name_placeholder":"Name","storefront_form_customer_name_error":"Please enter your name","storefront_form_did_you_mean_error":"Did you mean %{suggested_email}? Or use %{current_email}","form_customer_name_enabled":false,"form_customer_name_required":false,"css_config":"","js_config":null,"collect_promotion_consent":false,"storefront_form_promotion_consent_label":"Notify me about other news, sales, discounts & offers too","show_button_on_collection":false,"sms_default_country":"us","sms_allowed_countries":[],"sms_restrict_country":false,"sms_default_channel":true,"optin_required":false,"optin_success_text":"Registration confirmed! You'll receive an alert when the product is restocked.","storefront_button_border_radius":0,"storefront_button_disable_tag_hides_button":true,"storefront_button_disable_tag_enabled":false,"quantity_required":false,"storefront_form_quantity_label":"Quantity","enable_alerts":true,"sms_allowed":false,"email_allowed":true,"collect_promotion_consent_default":true,"insert_button_after_selector":null,"insert_button_after_selector_type":"afterend","storefront_button_position_type":"float-right","storefront_form_duplicate_error":"You've already subscribed for alerts to this product.","storefront_mixed_cart_error":"This item needs to be purchased separately. Please check out or clear your cart before adding this item.","storefront_error_heading":"Error","default_locale":"en","collection_page_button_text_color":"#FFFFFF","collection_page_button_background_color":"#202223","show_button_if_any_out_of_stock":false,"show_button_if_any_variant_out_of_stock_collection":false,"show_button_on_index":false,"insert_button_after_selector_collection":null,"insert_button_after_selector_index":null,"push_enabled":false,"push_allowed":false,"storefront_form_push_label":"Push","storefront_form_push_description":"Click 'Allow' to be notified via push notification","storefront_form_push_error":"Permission rejected! Please review notification settings and try again","storefront_font_family":"OpenSans","insert_button_after_selector_collection_type":"afterend","show_channel_selector":false,"storefront_form_empty_error":"Please fill in one or more of the options above","storefront_form_push_input":"Send notification to your browser","insert_button_after_selector_page":null,"show_button_on_page":false,"insert_button_after_selector_search":null,"show_button_on_search":false,"app_proxy_path_prefix":"/apps/restockrocket-production","collection_link_selector":"","index_link_selector":"","page_link_selector":"","search_link_selector":"","collection_check_link_visibility":true,"collection_buttons_container":null,"index_buttons_container":null,"page_buttons_container":null,"search_buttons_container":null,"extension_enable_url_variant_detection":true,"extension_enable_value_variant_detection":true,"extension_value_variant_selector":"[name='id']","resubscribe_text":"This product is out of stock. Get notified when it's restocked again by entering your details below!","preorder_enabled":true,"preorder_buy_button_selector":null,"preorder_add_to_cart_button_selector":"","preorder_badge_selector":"","preorder_button_out_of_stock_text":"Out of stock","preorder_button_add_to_cart_text":"Add to cart","preorder_form_selector":"form[action*=\"/cart/add\"]","preorder_collection_enabled":false,"preorder_collection_form_selector":"form[action*=\"/cart/add\"]","preorder_collection_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_index_enabled":false,"preorder_index_form_selector":"form[action*=\"/cart/add\"]","preorder_index_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_page_enabled":false,"preorder_page_form_selector":"form[action*=\"/cart/add\"]","preorder_page_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_search_enabled":false,"preorder_search_form_selector":"form[action*=\"/cart/add\"]","preorder_search_add_to_cart_button_selector":"form[action*=\"/cart/add\"] button","preorder_collection_badge_selector":null,"preorder_index_badge_selector":null,"preorder_page_badge_selector":null,"preorder_search_badge_selector":null,"preorder_badge_selector_type":"afterend","preorder_collection_badge_selector_type":"afterend","preorder_button_child_selector":"span","preorder_butto
n_disclaimer_insert_selector":"","preorder_button_disclaimer_insert_selector_type":"afterend","preorder_payment_insert_selector":"","preorder_payment_insert_selector_type":"afterend","preorder_price_container_selector":"","preorder_price_container_selector_insert_type":"afterend","preorder_terms_insert_selector":"","preorder_terms_insert_selector_type":"afterend","preorder_original_price_selector":"","preorder_price_format":"{{amount}} {{currency}}","show_badge_if_any_variant_is_preorder":false,"enable_console_debug":false,"inline_form_enabled":false,"inline_form_selector":null,"inline_form_selector_type":"afterend","storefront_form_prefill_customer":true,"storefront_form_show_image":false,"storefront_form_text_color":"#202223","storefront_form_background_color":"#FFFFFF","storefront_form_border_radius":0,"market_setup_type":"single_market","shopify_app_id":5940125,"preorder_progress_bar_insert_selector":null,"preorder_progress_bar_insert_selector_type":"beforebegin","countdown_timer_insert_selector":null,"co
untdown_timer_insert_selector_type":"afterend","cache":true,"cached_at":"2026-01-08T16:12:13.364Z","multi_language_enabled":false,"translation_locale":"en"};// STOQ shop-metafield namespace. `production` is substituted at build time
// (webpack CopyPlugin), so this is correct for every environment.
window._RestockRocketConfig.metafieldNamespace = 'restockrocket_production';window._RestockRocketConfig.cachedPreorderVariantIds = {"preorder_variant_ids":[42140096102626,42167799447778,43916521013474,43934694998242,43934695031010,43934695620834,43935975440610,43935975473378,43935989399778,43935989432546,43935990284514,43935994118370,43935995625698,43935995855074,43936000835810,43936003195106,43936003227874,43936008012002,43936008044770,43936022757602,43936022790370,43936022823138,43936022855906,43936056115426,43936061030626,43936064930018,43936070631650,43936078037218,43936078069986,43936088195298,43936093470946,43936101138658,43936107266274,43936124076258,43936124109026,43936124141794,43936124174562,439361299