See More
- Tyres Saddles Workshop Prices Tubes Bulgaria (EUR€) BrandsSeat Posts & Clamps
- Cycle to Work TubelessSee More PedalsBurkina Faso (XOFFr) Delivery & Returns Saddles Gears & Drivetrain
- Tent Box Information ComponentsBurundi (BIFFr) Mon - Fri: 08:30 - 17:30Seat Posts & Clamps Sat: 9:00 - 16:00 Sun: Closed E-bike Batteries and chargers
- 0131 374 5324Pedals Cameroon (XAFCFA) Newington Road Wheels EdinburghGears & DrivetrainCockpit EH9 1QN Complete Wheels [email protected]ComponentsSee More Cape Verde (CVE$)
- Tubeless Tools & Maintenance E-bike Batteries and chargers HandlebarsCentral African Republic (XAFCFA) Wheels
- await import("https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.shop-follow-button.en.esm.js"); Complete WheelsStems Chad (XAFCFA) Tubeless Tools & MaintenanceGrips & Bar-Tape
- Clothing and Protection Country Comoros (KMFFr) ProjektRide MerchandiseHeadsets GBP£
- Helmets Congo - Brazzaville (XAFCFA) Åland Islands (EUR€) Gloves BrakesCongo - Kinshasa (CDFFr)
- ClothingSee More Albania (ALLL) Côte d’Ivoire (XOFFr) Socks
- Complete Brakes Algeria (DZDد.ج) Essentials Croatia (EUR€) Cleaners, Degreasers and LubricationBrake Rotors
Cameroon (XAFCFA) Blog
Components Track Service Progress
Cape Verde (CVE$)Comoros (KMFFr)
Ghana (GBP£)Terms of ServiceComplete Wheels
Congo - Brazzaville (XAFCFA)
Refund policy Gibraltar (GBP£)Côte d’Ivoire (XOFFr)
-
Greenland (DKKkr.)
- My Account Tools & Maintenance
- Croatia (EUR€) Guadeloupe (EUR€)
- Open cart
- Cyprus (EUR€) Guernsey (GBP£) Clothing and Protection
- See More
- Czechia (CZKKč) Guinea (GNFFr)
- Open search bar ProjektRide Merchandise
- Denmark (DKKkr.) Guinea-Bissau (XOFFr)
- Helmets
- Djibouti (DJFFdj) Search for products on our site Hungary (HUFFt) Gloves
- Egypt (EGPج.م) Clothing Iceland (ISKkr)
- Socks
- Equatorial Guinea (XAFCFA) Ireland (EUR€)
- Eritrea (GBP£) Isle of Man (GBP£)
- Essentials
Italy (EUR€)
Custom Build Inspiration ons/01a1cf87-0c5a-7dbe-b46c-5802cf5d64ec/restockrocket-1-641/assets/restockrocket-collection-full.js' window._RestockRocketConfig.scriptUrlProductBis = 'https://cdn.shopify.com/extensions/01a1cf87-0c5a-7dbe-b46c-5802cf5d64ec/restockrocket-1-641/assets/restockrocket-product-bis.js' window._RestockRocketConfig.scriptUrlCollectionBis = 'https://cdn.shopify.com/extensions/01a1cf87-0c5a-7dbe-b46c-5802cf5d64ec/restockrocket-1-641/assets/restockrocket-collection-bis.js' window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1) window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://ext.stoqapp.com' try { const _stoqVersionMatch = window._RestockRocketConfig.scriptHost.match(/(\d+)\/?(?:assets\/?)?$/); window._RestockRocketConfig.appVersion = (_stoqVersionMatch && _stoqVersionMatch[1]) || ''; } catch (Blog Maintenance
<São Tomé & Príncipe (STDDb) < Faroe Islands (DKKkr.)
/ 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; } if (settings.multi_language_enabled) { if (!settings.translations) { console.debug('STOQ - multi-language enabled but no translation data in cache, fetching fresh'); return null; } 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'); } } const updatedAt = new Date(settings.updated_at); if (isNaN(updatedAt.getTime()Track Service Progress Kosovo (EUR€)<
.body.appendChild(plainScriptElement); }; restockRocketScriptElement.src = scriptUrl; document.body.appendChild(restockRocketScriptElement); } createRestockRocketContainer() console.debug('STOQ - extension activated') 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; var _stoqPageSeq = 0; try { _stoqPageSeq = (parseInt(window.sessionStorage.getItem('_stoq_pls') || '0', 10) || 0) + 1; window.sessionStorage.setItem('_stoq_pls', String(_stoqPageSeq)); } catch (e) { } Shopify?.analytics?.publish?.('stoq_initialized', { cart_token: _stoqInitConfig.cartToken || '', page_url: window.location.origin + window.location.pathname, page_type: _stoqInitConfig.pageType || '',ColorSenegal (XOFFr) Services.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.closest('form'); var vidEl = form && form.querySelector('[name="id"]'); var variantId = (vidEl && vidEl.value) || _sqTrack.selected_variant_id || ''; var _sqVidNum = Number(variantId); var _sqPlan = null; var _sqPlans = Array.isArray(_sqTrack.sellingPlans) ? _sqTrack.sellingPlans : []; var _sqMktId = Number(_sqTrack.marketId); var _sqOffersOn = !!(_sqTrack.readFlags && _sqTrack.readFlags.enable_storefront_plan_offers === true); var _sqAlloc = _sqOffersOn ? ((_sqTrack.offerAllocations && _sqTrack.offerAllocations[_sqVidNum]) || (_sqTrack.variantSellingPlanIds && _sqTrack.variantSellingPlanIds[_sqVidNum])) : null; var _sqPlanIds = function (pl) Building Your Bike From the BoxFinland (EUR€) Sell Your Bike _sqPlans.forEach(function (pl) { if (!_sqPlan && _sqForVariant(pl) && !pl.markets_enabled) { _sqPlan = pl; } }); } Shopify?.analytics?.publish?.('stoq_accelerated_checkout_clicked', { variant_id: variantId, product_id: (_sqTrack.product && _sqTrack.product.id) || '', channel: channel, market_id: _sqTrack.marketId || '', country_code: _sqTrack.countryIsoCode || '', page_type: _sqTrack.pageType || '', cart_token: _sqTrack.cartToken || '', page_url: (window.location && window.location.origin + window.location.pathname) || '', properties: { 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 && Latvia (EUR€) See More< lassList.contains('stoq-buy-now-pending')), blocked: (function () { try { var rr = window._RestockRocket; return !!(rr && typeof rr.willBlockAcceleratedClick === 'function' && rr.willBlockAcceleratedClick(e)); } catch (err) { return false; } })(), }, }); } catch (err) { } }, true); } } catch (e) { } function applyTranslations(settings) { try { 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) { console.debug('STOQ - No matching locale for translations. Available:', Object.keys(translations || {})); Insure Your Bike Contact Us Serbia (RSDРСД) '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); }); } }); } function storefrontGraphql(query, variables) { const cfg = window._RestockRocketConfig; let token = cfg.storefrontAccessToken || null; if (!token && typeof cfg.sk === 'string' && cfg.sk !== '') { try { token = atob(cfg.sk).split('').reverse().join('') || null; } catch (e) { token = null; } } if (!token || cfg.disableStorefrontApi === true) { return Promise.reject(new Error('Storefro France (EUR€) urn storefrontGraphql(query, { namespace: cfg.metafieldNamespace, key: key }) .then(function(data) { const value = data && data.shop && data.shop.metafield && data.shop.metafield.value; if (!value) { throw new Error('Storefront API returned no ' + key + ' metafield value'); } return JSON.parse(value); }); } function fetchStorefrontSettings() { const query = 'query StoqSettings($namespace: String!) { shop { settings: metafield(namespace: $namespace, key: "settings") { value } translations: metafield(namespace: $namespace, key: "settings_translations") { value } } }'; return storefrontGraphql(query, { namespace: window._RestockRocketConfig.metafieldNamespace }) .then(function(data) { const settings = JSON.parse(data.shop.settings.value); if (!settings.updated_at) { throw new Error('settings metafield is not a settings payload'); } if (settings.single_locale_translations_inline) { settings.translations = data.shop.translations && JSON.parse(data Lesotho (GBP£) Machine Blue const storefrontRead = window._RestockRocketConfig.readFlags?.enable_storefront_settings_read === true ? Promise.race([ fetchStorefrontSettings(), new Promise(function(_, reject) { setTimeout(function() { reject(new Error('timed out')); }, 1500); }) ]).catch(function(error) { console.debug('STOQ - Storefront settings read failed, using setting.json:', error.message); }) : Promise.resolve(); storefrontRead .then(function(settings) { return settings || 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 (cachedSettings) { console.dePrivacy Policy Finance
Workshopr.message); }); } function refreshShopConfig(source) { const cfg = window._RestockRocketConfig; const viaEmbed = function() { return fetchEmbedConfig(source.endpoint, source.apply); }; const flagOn = !!cfg.readFlags && cfg.readFlags[source.flag] === true; if (!flagOn) { return viaEmbed(); } return fetchStorefrontShopMetafield(source.metafieldKey) .then(function(value) { if (!source.isValid(value)) { throw new Error(source.metafieldKey + ' metafield is not a valid ' + source.endpoint + ' payload'); } source.apply(value); console.debug('STOQ - refreshed ' + source.endpoint + ' from the Storefront API'); }) .catch(function(error) { console.debug('STOQ - Storefront ' + source.endpoint + ' read failed, using embed:', error.message); return viaEmbed(); }); } function refreshIntegrations() { const cfg = window._RestockRocketConfig; return refreshShopConfig({ endpoint: 'integrations', metafieldKey: 'in
Seychelles (GBP£)
ngs configured for ${window._RestockRocketConfig.pageType}`);
const staleRefresh = !window._RestockRocketConfig.isLiquidCacheFresh && !settings.disable_refresh_on_stale_liquid;
if (staleRefresh) {
console.debug('STOQ - refreshing selling_plans + integrations (Liquid cache stale)');
Promise.race([
Promise.all([refreshSellingPlans(), refreshIntegrations()]),
new Promise(function(resolve) { setTimeout(resolve, 1000); })
]).then(function() { loadScripts(settings); });
return;
}
loadScripts(settings);
}
function loadScripts(settings) {
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);
})
const hasEnabledOffer = Array.isArray(window._RestockRocketConfig.sellingPlans)
&& w
French Southern Territories (EUR€)
-
St. Helena (SHP£)
Greenland (DKKkr.)
Åland Islands (EUR€)
Malta (EUR€)Mauritius (MUR₨)Svalbard & Jan Mayen (GBP£) Hire Guernsey (GBP£) Algeria (DZDد.ج)
1 Sudan (GBP£) Parts & Components Guadeloupe (EUR€) Albania (ALLL) HomeMauritania (GBP£) See More
1
- 2 Sweden (SEKkr) Guinea (GNFFr) Andorra (EUR€) Tanzania (TZSSh) Hungary (HUFFt) Armenia (AMDդր.)


Tools & Maintenance


Czechia (CZKKč)