<
& !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())) { console.debug('STOQ - Invalid updated_at date format in settings'); return null; } const age = Date.now() - updatedAt.getTime(); if (ages); } 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(', ')); } return body && body.data; }); } function fetchStorefrontShopMetafield(key) { const cfg = window._RestockRocketConfig; const query = 'query StoqShopMetafield($namespace: String!, $key: String!) { shop { metafield(namespace: $namespace, key: $key) { value } } }'; return 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: $nam
dSettings); } else { console.debug('STOQ - fetching fresh settings'); const headers = { 'X-Shopify-Shop-Domain': window._RestockRocketConfig.shop || window.Shopify.shop, 'ngrok-skip-browser-warning': 'skip' }; 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; } 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 .tBlogonfig.shop || window.Shopify.shop, 'ngrok-skip-browser-warning': 'skip' } } ) .then(function(response) { if (!response.ok) throw new Error(`Failed to fetch ${endpoint}`); return response.json(); }) .then(function(data) { try { apply(data); } catch (applyError) { console.error('STOQ - apply failed for ' + endpoint + ':', applyError); throw applyError; } }) .catch(function(error) { console.debug(`STOQ - using cached ${endpoint}:`, error.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 || source.embedOnly === true) { return viaEmbed(); } return fetchStorefrontShopMetafield(source.metafieldKey) .then(function(value) { if (!source.isValid(value)) { thro
| Privacy Policy | |
| Terms of Service | |
| Service | |
| Servicing | Book a Service |
| Workshop Prices | Cycle to Work |
| Delivery & Returns | Information |
| Sun: Closed | 0131 374 5324Newington Road | Edinburgh
| CHAIN await import("https://cdn.shopify.com/shopifycloud/shop-js/modules/v2/loader.shop-follow-button.en.esm.js"); Libya (GBP£) | KMC X10 |
| CASSETTE | Shimano Deore 11-46t 10spdGBP£Lithuania (EUR€) |
| CHAINGUIDEÅland Islands (EUR€) Luxembourg (EUR€) | n/a |
| F/D | n/aAlgeria (DZDد.ج) Malawi (MWKMK) |
| R/DAndorra (EUR€) Mali (XOFFr) | Shimano Deore |
| SHIFTERS | Shimano DeoreArmenia (AMDդր.) Mauritania (GBP£) |
| BRAKE CALIPERSAscension Island (SHP£) Mauritius (MUR₨) | Shimano MT410 Hydrualic |
| FRONT BRAKE ROTOR | Shimano RT30 203mmBelarus (GBP£) Moldova (MDLL) |
| REAR BRAKE ROTORBelgium (EUR€) Monaco (EUR€) | Shimano RT30 180mm |
| BRAKE LEVERS | Shimano M4100 HydrualicBosnia & Herzegovina (BAMКМ) Morocco (MADد.م.) |
| HEADSETBotswana (BWPP) Mozambique (GBP£) | FSA No.57B |
| HANDLEBAR | Kona XC/BC 35Bulgaria (EUR€) Netherlands (EUR€) |
| STEMBurkina Faso (XOFFr) Niger (XOFFr) | Kona XC/BC 35 |
| SEATPOST | TranzX Dropper Internal 31.6mmCameroon (XAFCFA) North Macedonia (MKDден) |
| SEAT CLAMPCape Verde (CVE$) Norway (GBP£) | Kona Clamp |
| GRIPS | Kona Key GripChad (XAFCFA) Portugal (EUR€) |
| SADDLEComoros (KMFFr) Réunion (EUR€) | WTB Volt |
| FRONT HUB | Shimano 110x15mmCongo - Kinshasa (CDFFr) Rwanda (RWFFRw) |
| REAR HUBCôte d’Ivoire (XOFFr) San Marino (EUR€) | Shimano 148x12mm |
| SPOKES | Stainless Black 14gCyprus (EUR€) Senegal (XOFFr) |
| RIMSCzechia (CZKKč) Serbia (RSDРСД) | WTB ST i35 TCS 2.0 |
| FRONT TIRE | Maxxis Minion DHF EXO TR DUAL 29x2.6"Djibouti (DJFFdj) Sierra Leone (SLLLe) |
| REAR TIREEgypt (EGPج.م) Slovakia (EUR€) | Maxxis Minion DHR II EXO TR DUAL 29x2.4" WT |
| DRIVEUNIT | Shimano E7000 20MPHSomalia (GBP£) Eritrea (GBP£) |
| BATTERYSouth Africa (GBP£) Estonia (EUR€) | Shimano 504Wh |
| DISPLAY | Shimano SC-E7000 DisplaySpain (EUR€) Ethiopia (ETBBr) |
| CHARGERSt. Helena (SHP£) Faroe Islands (DKKkr.) | Shimano STEPS 2A |
| BATTERYLOCK | n/aSvalbard & Jan Mayen (GBP£) France (EUR€) |
| PAINT COLOURSweden (SEKkr) French Southern Territories (EUR€) | Matte Midnight w/ Blue-Grey Decals |
| EXTRAS | n/aTanzania (TZSSh) Gambia (GMDD) |
GEOMETRY
| SIZE | Ukraine (UAH₴) Greenland (DKKkr.)S | M | United Kingdom (GBP£) Guadeloupe (EUR€)L | XL | United States (GBP£) Guernsey (GBP£)|||||||||||||||||||
| 1 | Vatican City (EUR€) Guinea (GNFFr)ST LENGTH | 385 | Guinea-Bissau (XOFFr) Western Sahara (MADد.م.)410 | 450 | Hungary (HUFFt) Zambia (GBP£)485 | ||||||||||||||||||
| 2 | TT LENGTH | Ireland (EUR€)586 | 612 | Isle of Man (GBP£)639 | © 2026,677 ProjektRide | Italy (EUR€) .||||||||||||||||||
| 3 Shopify | Jersey (GBP£) .REACH | 425 | Kenya (KESKSh) American Express450 | 475 Apple Pay | Kosovo (EUR€)510 | Diners Club||||||||||||||||||
| Lesotho (GBP£) | Liberia (GBP£) | Libya (GBP£) | |||||||||||||||||||||
| Liechtenstein (CHFCHF) | Lithuania (EUR€) | Luxembourg (EUR€) | |||||||||||||||||||||
| Malawi (MWKMK) | Mali (XOFFr) | Malta (EUR€) | |||||||||||||||||||||
| Mauritania (GBP£) | Mauritius (MUR₨) | Mayotte (EUR€) | |||||||||||||||||||||
| Monaco (EUR€) | Montenegro (EUR€) | Morocco (MADد.م.) | |||||||||||||||||||||
| Mozambique (GBP£) | Namibia (GBP£) | Netherlands (EUR€) | |||||||||||||||||||||
| Nigeria (NGN₦) | North Macedonia (MKDден) | Norway (GBP£) | |||||||||||||||||||||
| Poland (PLNzł) | Portugal (EUR€) | Réunion (EUR€) | |||||||||||||||||||||
| Rwanda (RWFFRw) | San Marino (EUR€) | 1270< | |||||||||||||||||||||
| 13 liquid_cache_age: _stoqInitConfig.liquidCacheAge, inventory_policy: (_stoqInitConfig.variantsInventoryPolicy || {})[_stoqSelectedVariantId] || '', inventory_quantity: (_stoqInitConfig.variantsInventoryQuantity || {})[_stoqSelectedVariantId], }); } catch (e) { console.debug('STOQ - stoq_initialized publish failed:', e); } 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.closest('form'); var vidEl = form && form.querySelector('[name="id"]'); var variantId = (vidEl && vidEl.value) || _sqTrack.selected_variant_id || ''; | ck.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.href) || '', 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 && _sqTrack.cachedPreorderVariantIds.preorder_variant_ids); })(), in_enabled_plan: !!_sqPlan, is_instock_variant: (function () { var has = function (a) { return Array.isArray(a) && a.indexOf(_sqVidNum) !== -1; }; return has(_sqTrack.inStockVariantIds) || hSenegal (XOFFr)FRONT CENTER; } 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 || {})); delete settings.translations; return settings; } console.debug(`STOQ - Applying translations for normalized locale: ${normalizedLocale} (original: ${window._RestockRocketConfig.locale})`); const translatedFields = translations[normalizedLocale]; if (tra | Q - 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; if (!cfg.storefrontAccessToken || cfg.disableStorefrontApi === true) { return Promise.reject(new Error('Storefront API unavailable')); } return fetch( `https://${cfg.shop}/api/${cfg.storefrontApiVersion}/graphql.json`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Shopify-Storefront-Access-Token': cfg.storefrontAccessToken, }, body: JSON.stringify({ query: query, variables: variables }), } ) .then(function(response) { if (!response.ok) { throw new Error('Storefront API HTTP ' + response.sta746amespace, 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.shop.translations.value); } if (settings.multi_language_enabled && !settings.translations) { throw new Error('settings metafield carries no translations'); } return settings; }); } const cachedSettings = window._RestockRocketConfig.cachedSettings; const validCachedSettings = cachedSettings ? checkSettingsExpiry(cachedSettings) : null; if (validCachedSettings) { console.debug('STOQ - using cached settings'); initializeScripts(validCac | .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.debug('STOQ - using expired cached settings as fallback'); initializeScripts(cachedSettings); } else { console.error('STOQ - failed to load settings:', error); } }) .catch(function(e) { console.error(e) }) } function fetchEmbedConfig(endpoint, apply) { return fetch( `${window._RestockRocketConfig.host}/api/v1/embed/${endpoint}.json`, { headers: { 'X-Shopify-Shop-Domain': window._RestockRockeSerbia (RSDРСД)773 - using cached ${endpoint}:`, error.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 || source.embedOnly === true) { 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 refreshShop | lyTranslations(settings); window._RestockRocketConfig.settings = settings; console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`); const forceEmbedSellingPlans = settings.force_embed_selling_plans === true; const staleRefresh = !window._RestockRocketConfig.isLiquidCacheFresh && !settings.disable_refresh_on_stale_liquid; if (forceEmbedSellingPlans || staleRefresh) { console.debug('STOQ - refreshing selling_plans' + (staleRefresh ? ' + integrations (Liquid cache stale)' : ' (force_embed_selling_plans)')); const refreshes = [refreshSellingPlans(forceEmbedSellingPlans)]; if (staleRefresh) { refreshes.push(refreshIntegrations()); } Promise.race([ Promise.all(refreshes), new Promise(function(resolve) { setTimeout(resolve, 1000); }) ]).then(function() { loadScripts(settings); }); return; } loadScripts(settings); } function loadScripts(settings) { setupCartSellingPlanUpdater(settings); if(se802window._RestockRocketConfig.scriptUrlProductBis; const pageType = window._RestockRocketConfig.pageType; const collectionPageTypes = ['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) { createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection); } else { console.debug(`STOQ - no scripts enabled for ${pageType}`); } const appLoadedEvent = new CustomEvent('stoq:loaded', { detail: { pageType: window._RestockRocketConfig.pageType, enabled: settings.enable_app, settings: settings, | Seychelles (GBP£)|||||||||||||||||||
| 14 | FORK LENGTH | Slovakia (EUR€)551 | 551 | Slovenia (EUR€)551 | 551 | Somalia (GBP£)||||||||||||||||||
| 15 | South Africa (GBP£)FORK OFFSET | 51 | South Sudan (GBP£)51 | 51 | Spain (EUR€)51 |

Frequently Asked Questions Türkiye (GBP£)
-
Uganda (UGXUSh)
Please get in touch with a member of the team either by phone (Ukraine (UAH₴) 01313745324 ) or email ( [email protected] ) where on of the team will be more than happy to help.United Kingdom (GBP£)
ProjektRide Bike Shop Edinburgh
-
United States (GBP£)
If the item is showing in stock, we aim to post the product within 24 hours. Please allow 5 working days to receive the item. Vatican City (EUR€)
Postage is free on orders over £50. Orders under £50, our postage charge is £3.99.
We also have a physical store, if you are local please pop in -
ProjektRide Bike Shop Edinburgh
82 Newington Road, EH91QN, Edinburgh.Western Sahara (MADد.م.)
Poland (PLNzł)



















