#FeaturedImage--template--15326745395426__1645734801adfd4c07 { --overlay-opacity: 0.2; }
Contact UsEssentials
Cart
FAQ_media--featured"
href="/collections/new-collection/products/kryptolok-standard-u-lock-with-4-foot-kryptoflex-cable-hire"
title="Hire Kryptolok Standard U-Lock & 4 foot Kryptoflex cable"
aria-label="Hire Kryptolok Standard U-Lock & 4 foot Kryptoflex cable"
style="background-image: url(//projektride.co.uk/cdn/shop/files/Screenshot2022-03-09at20.04.46_560e2033-8232-4bd3-a423-3ce8c9f11849_600x.png?v=1691610428)">
CloseBottles and CagesFrog 44 Congratulations! Your order qualifies for free shipping
£0.00£390.00Please get in touch with a member of the team either by phone (
Bike Packing
between the pedals increasing efficiency and comfort for children. price":2495,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":42205177217250,"title":"700c \/ 32mm","option1":"700c \/ 32mm","option2":null,"option3":null,"sku":"","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"700c Continental Ultra Sport Tyre in Black (Folding) - 700c \/ 32mm","public_title":"700c \/ 32mm","options":["700c \/ 32mm"],"price":2495,"weight":0,"compare_at_price":2495,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]}],"images":["\/\/projektride.co.uk\/cdn\/shop\/products\/p558c08154bf760.87457661.jpg?v=1640544817","\/\/projektride.co.uk\/cdn\/shop\/products\/p558c08823c9181.11837059.jpg?v=1640544816"],"featured_image":"\/\/projektride.co.uk\/cdn\/shop\/products\/p558c08154bf760.87457661.jpg?v=1640544817","options":["Size"],"media":[{"alt":null,"id":28913871552738,"position":1,"preview_image":{"aspect_ratio":1.5,"height":600,"width":900,"s
e tread stripe run suits Fi:zik and jazzes up every bicycle. This tyre scores with a lot of grip, the silica-based tread compound and very high mileage.\u003c\/p\u003e\n\u003cul data-mce-fragment=\"1\"\u003e\n\u003cli data-mce-fragment=\"1\"\u003eFolding version\u003c\/li\u003e\n\u003cli data-mce-fragment=\"1\"\u003ePerformance technology\u003c\/li\u003e\n\u003cli data-mce-fragment=\"1\"\u003eTPI: 3\/180\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eIf any more information is needed, please don't hesitate to get in touch with one of the team:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eProjektRide Bike shop Edinburgh.\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eedinburgh@projektride.co.uk\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eT Track Your ServiceShop by Brand- 01313745324\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp\u003e \u003c\/p\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {42205177118946 : "deny",42205177151714 : "deny",42205177184482 : "deny",42205177217250 : "deny",};
window._RestockRocketConfig.variantsInventoryQuantity = {42205177118946 : parseInt("5"),42205177151714 : parseInt("4"),42205177184482 : parseInt("5"),42205177217250 : parseInt("4"),};
window._RestockRocketConfig.variantsPreorderCount = {42205177118946 : parseInt(""),42205177151714 : parseInt(""),42205177184482 : parseInt(""),42205177217250 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderCountForMarket = {42205177118946 : null,42205177151714 : null,42205177184482 : null,42205177217250 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {42205177118946 : parseInt(""),42205177151714 : parseInt(""),42205177184482 : parseInt(""),42205177217250 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {42205
177118946 : null,42205177151714 : null,42205177184482 : null,42205177217250 : null,};
window._RestockRocketConfig.variantsShippingText = {42205177118946 : "",42205177151714 : "",42205177184482 : "",42205177217250 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {42205177118946 : null,42205177151714 : null,42205177184482 : null,42205177217250 : null,};
window._RestockRocketConfig.selected_variant_id = 42205177118946;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;window._RestockRocketConfig.scriptUrlProduct = 'https://cdn.shopify.com/extensions/019b1405-52e0-7e89-a6c1-1ac7fea6dd8f/restock-rocket-shopify-410/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019b1405-52e0-7e89-a6c1-1ac7fea6dd8f/restock-rocket-shopify-410/assets/restockrocket-collect
ion.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
window._RestockRocketConfig.host = 'https://app.restockrocket.io'
const SETTINGS_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds
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 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 age = Date.now() - updatedAt.getTime();
if (age
Gloria<
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')
function applyTranslations(settings) {
try {
// Skip translation logic entirely if multi-language is not enabled
if (!settings || Not ready for pedals yet?
!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 !== undef
ined && 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;
}
}
// 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': 'skip'
};
if (window.Shopify?.theme?.role === 'main') {
headers['X-Shopify-The
me-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('STOQ - failed to load settings:', error);
}
})
.catch(function(e) {
coOur lightweight first pedal bikes are a great confidence booster and can also be used as a balance bike for a taller child by simply removing the pedals.TrekOthernsole.error(e)
})
}
function initializeScripts(settings) {
settings = applyTranslations(settings);
window._RestockRocketConfig.settings = settings;
console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`);
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);
})
if(window._RestockRocketConfig.pageType === 'collection' && (settings.show_button_on_collection || settings.preorder_collection_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._RestockRocketConfig.pageType === 'index' && (settings.show_button_on_index || settings.preorder_index_enabled)) {
createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection);
} else if(window._Resto
Hope
Available colours*: Frog Electric Blue, Green, Orange, Pink, Red and SpottyEnve
- Tubes


<
Life Systems Pocket First Aid Kit - HIRE
