1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127324898,"position":7,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-red-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-red-1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127357666,"position":8,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-tan-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-tan-1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127390434,"position":9,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-yellow-black-1.jpg?v=1,"position":12,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-blue-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-blue-1.jpg?v=1720098274","width":1999}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cdiv class=\"woocommerce-tabs wc-tabs-wrapper\"\u003e\n\u003cdiv aria-labelledby=\"tab-title-description\" role=\"tabpanel\" id=\"tab-description\" class=\"woocommerce-Tabs-panel woocommerce-Tabs-panel--description panel entry-content wc-tab\"\u003e\n\u003cp\u003e\u003cspan\u003eThese Voile Straps® are made of tough stretch polyurethane, with a UV-resistant additive to increase their lifespan.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cspan\u003eTheir Super-Tough® nylon buckle is non-marring, non-conductive, and non-reflective.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u00
{
"@context": "http://schema.org/",
"@type": "Product",
"name": "Voile 15″ Nylon Buckle Strap",
"url": "https:\/\/projektride.co.uk\/products\/voile-15-nylon-buckle-strap","image": [
"https:\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-cyan-white-1_1999x.jpg?v=1720098273"
],"description": "\n\nThese Voile Straps® are made of tough stretch polyurethane, with a UV-resistant additive to increase their lifespan.\nTheir Super-Tough® nylon buckle is non-marring, non-conductive, and non-reflective.\nFew things in life are as reliable as the original Voile Strap®. Over the last 30 years they have become the ultimate alternative to duct tape, nylon straps, and bungee cords.\nOn the job, in the outdoors, and everywhere in between: they are the definitive way to secure, bundle, and repair almost anything on the go.\nLoad Circumference Min — Max: 5.5in — 12.5in \/ 14cm — 31.7cmMaterial: UV-Resistant PolyurethaneBuckle: Super-Tough® Nylon\n\n\n\n\n","brand": {
"@type": "Thing",
"name": "Voile"
},"gtin8": "","offers": [{
"@type" : "Offer","availability" : "http://schema.org/InStock",
"price" : 15.0,
"priceCurrency" : "GBP",
"url" : "https:\/\/projektride.co.uk\/products\/voile-15-nylon-buckle-strap?variant=45662746804450"
},
{
"@type" : "Offer","availability" : "http://schema.org/InStock",
"price" : 15.0,
"priceCurrency" : "GBP",
"url" : "https:\/\/projektride.co.uk\/products\/voile-15-nylon-buckle-strap?variant=45662746837218"
},
{
"@type" : "Offer","availability" : "http://schema.org/InStock",
"price" : 15.0,
"priceCurrency" : "GBP",
"url" : "https:\/\/projektride.co.uk\/products\/voile-15-nylo
Cookie PolicyView allimg src="//projektride.co.uk/cdn/shop/files/voile-straps-25-inch-nylon-buckle-olive-1_98x.jpg?v=1720100212" alt="" class="product-single__thumbnail-img">
Terms of Service
ignup_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":{},"storefront_form_email_placeholder":"Email address","storefront_form_phone_placeholder":"SMS","storefront_form_phone_label":"Phone number","storefr
img src="//projektride.co.uk/cdn/shop/files/voile-straps-20-inch-nylon-buckle-magenta-white-1_98x.jpg?v=1720099174" alt="" class="product-single__thumbnail-img">
Helmets
Add to cart
Notify me when this product is available:Add to cart
ce Min — Max:\u003c\/b\u003e 5.1in — 22.4in \/ 13cm — 57cm\u003cbr\u003e\u003cb\u003eMaterial:\u003c\/b\u003e UV-Resistant Polyurethane\u003cbr\u003e\u003cb\u003eBuckle:\u003c\/b\u003e Super-Tough® Nylon\u003c\/span\u003e\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003csection class=\"related products\"\u003e\u003c\/section\u003e\n\u003csection class=\"related products\"\u003e\u003c\/section\u003e\n\u003c!----\u003e"}-nylon-buckle-orange-1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127324898,"position":7,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-red-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-red-1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127357666,"position":8,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-tan-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-tan-1.jpg?v=1720098274","width":1999},{"alt":null,"id":34187127390434,"position":9,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-y
l,"id":34187127488738,"position":12,"preview_image":{"aspect_ratio":1.0,"height":1999,"width":1999,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-blue-1.jpg?v=1720098274"},"aspect_ratio":1.0,"height":1999,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/voile-straps-15-inch-nylon-buckle-blue-1.jpg?v=1720098274","width":1999}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cdiv class=\"woocommerce-tabs wc-tabs-wrapper\"\u003e\n\u003cdiv aria-labelledby=\"tab-title-description\" role=\"tabpanel\" id=\"tab-description\" class=\"woocommerce-Tabs-panel woocommerce-Tabs-panel--description panel entry-content wc-tab\"\u003e\n\u003cp\u003e\u003cspan\u003eThese Voile Straps® are made of tough stretch polyurethane, with a UV-resistant additive to increase their lifespan.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cspan\u003eTheir Super-Tough® nylon buckle is non-marring, non-conductive, and non-reflective.\u003c\/span\u003e\u003c\
span class="visually-hidden">Life Systems Pocket First Aid Kit - HIRE
<
a class="product__media product__media--featured"
href="/products/life-systems-pocket-first-aid-kit-hire"
title="Life Systems Pocket First Aid Kit - HIRE"
aria-label="Life Systems Pocket First Aid Kit - HIRE"
style="background-image: url(//projektride.co.uk/cdn/shop/files/Screenshot2022-02-24at21.18.22_5c0e6e2d-1913-4fd1-a90d-b486895960b6_600x.png?v=1691610357)">
>
<span class="visually-hidden">Life Systems Pocket First Aid Kit - HIRE
>
>
<
div class="product__media-hover-img product__media" style="background-image: url(//projektride.co.uk/cdn/shop/files/Screenshot2022-02-24at21.18.32_9d81277b-124e-4fdc-8a0f-fbfb40a9343d_600x.png?v=1691610357)">
: "",45662747197666 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {45662746804450 : null,45662746837218 : null,45662746869986 : null,45662746902754 : null,45662746935522 : null,45662746968290 : null,45662747001058 : null,45662747033826 : null,45662747066594 : null,45662747099362 : null,45662747132130 : null,45662747164898 : null,45662747197666 : null,};
window._RestockRocketConfig.selected_variant_id = 45662747197666;
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/019b08ef-eea8-746d-807f-b70c50171bc3/restock-rocket-shopify-404/assets/restockrocket-product.js'
window._RestockRocketConfig.scriptUrlCollection = 'https://cdn.shopify.com/extensions/019b08ef-eea8-746d-807f-b70c50171bc3/restock-rocket-shopify-404/assets/restockrocket-collec<
sole.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 || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translations found, skipping translation');
tion.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
span class="visually-hidden">Life Systems Pocket First Aid Kit - HIRE
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 transl 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
n;
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) {
console.error(e)
})
}
function initializeScripts(settings) {
settings = applyTranslations(settings);
window._RestockRocket 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 ||
Product Detailsled: settings.enable_app,
settings: settings
}
});
console.debug('STOQ - dispatching app loaded event');
window.dispatchEvent(appLoadedEvent);
}
}
function updateCartSellingPlans() {
// Wait for the API to be available with retries
const maxRetries = 10;
const retryDelay = 500;
function attemptCartCheck(attempt = 1) {
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);
});
} else if (attempt fined && 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-Th
The all-new NANO Series, Voiles smallest straps yet! 1/2″ thick, this micro version of our time tested tiedown offers the same versatility in an even smaller package. maxRetries) {
console.debug(`STOQ - API not ready, retry ${attempt}/${maxRetries}`);
setTimeout(() => attemptCartCheck(attempt + 1), retryDelay);
} else {
console.debug('STOQ - API not loaded after max retries, skipping cart selling plan check');
}
}
attemptCartCheck();
}
onsole.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._Rest
pLoadedEvent = new CustomEvent('stoq:loaded', {
detail: {
pageType: window._RestockRocketConfig.pageType,
enabled: settings.enable_app,
settings: settings
}
});
console.debug('STOQ - dispatching app loaded event');
window.dispatchEvent(appLoadedEvent);
}
}
function updateCartSellingPlans() {
// Wait for the API to be available with retries
const maxRetries = 10;
const retryDelay = 500;
function attemptCartCheck(attempt = 1) {
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:', err
<
div class="product__media-hover-img product__media" style="background-image: url(//projektride.co.uk/cdn/shop/files/Screenshot2022-02-24at21.18.32_9d81277b-124e-4fdc-8a0f-fbfb40a9343d_600x.png?v=1691610357)">