© 2025,
kend'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.marketId = 382140642;window._RestockRocketConfig.countryName = 'United Kingdom';
window._RestockRocketConfig.countryIsoCode = 'GB';window._RestockRocketConfig.cartInventoryQuantity = {};window._RestockRocketConfig.cachedSettings = {"id":38500,"shop_id":38436,"currency":"GBP","created_at":"2025-07-26T09:13:57.337Z","updated_at":"2025-11-11T14:27:02.312Z","enable_app":true,"enable_signup_widget":false,"storefront_button_text":"Notify me when available","storeL
lid 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_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_b
,"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_selecto
"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,"market_setup_type":"single_market","shopify_app_id":5940125,"cache":true,"cached_at":"2025-11-11T14:27:02.333Z","multi_language_enabled
06786,43936331661538,43936332349666,43936333103330,43936351224034,43936353714402,43936362889442,43936362922210,43936388153570,43936389333218,43936395526370,43936398508258,43936401522914,43936408568034,43936414400738,43936700727522,43936706101474,43936706134242,43936706167010,43936706199778,43936706232546,43936706265314,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,43981392904418,43981695844578,43981695877346,43981695910114,43981695942882,43981986070754,43981987905762,43981987938530,44052906967266,44052907327714,44052907360482,44052907393250,44052907426018,44052907458786,44052907491554,44052909097186,44052909129954,44140302827746,44140302893282,4414031701629XL
Product Details._RestockRocketConfig.cachedInStockVariantIds = { in_stock_variant_ids: [] };window._RestockRocketConfig.cachedOutOfStockVariantIds = { out_of_stock_variant_ids: [] };window._RestockRocketConfig.cachedVariantPreorderLimits = {"variant_preorder_limits":{},"updated_at":"2025-12-13T21:38:57Z","shopify_market_id":382140642,"market_locations_enabled":false};
window._RestockRocketConfig.cachedVariantPreorderLimitsMarketKey = "variant_preorder_limits_for_market_382140642";window._RestockRocketConfig.cachedVariantShippingTexts = {"variant_shipping_texts":{},"updated_at":"2025-12-13T21:38:57Z","shopify_market_id":382140642,"market_locations_enabled":false};
window._RestockRocketConfig.cachedVariantShippingTextsMarketKey = "variant_shipping_texts_for_market_382140642";window._RestockRocketConfig.sellingPlans = [{"shopify_selling_plan_group_id":98590196095,"shopify_selling_plan_id":713071886719,"enabled":true,"variant_ids":[55569933140351,55569712382335,55569712415103,55569712480639,55569933173119,55570017616255
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","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_o
: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,"updated_at":"2025-08-19T10:05:43.042Z","allow_mixed_cart":true}];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,"created_at":"2025-07-26T09:16:04.076Z","updated_at":"2025-07-26T09:16:04.076Z"}];window._RestockRocketConfig.obfuscateInventoryQuantity = false;window._RestockRocketConfig.product = {"id":14965979775359,"title":"Hire Ortlieb 40L Pannier Bags","handle":"hire-ortlieb-40l-pannier-bags","description":"\u003cdiSelect variant dropdown
The FX Sport AL Equipped is a capable and confident hybrid bike that's fun to ride from roads to rail trails and beyond. It has a light frame, a sturdy drivetrain and loads of ride-ready accessories like a rear rack and lights. Wide wheels and lofty tyres soak up bumps and rough terrain for a comfortable, confident ride on the road, light gravel trails, bike paths and more. quickly mounted and taken off the bike rack. A shoulder strap provides carrying comfort when taken off the rack.\u003c\/div\u003e\n\u003cdiv class=\"text-lighter-text\"\u003e\u003cstrong\u003e\u003c\/strong\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-lighter-text\"\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cbutton class=\"heading-button flex min-h-[52px] w-full py-2.5 items-center\" type=\"button\"\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv\u003e\u003cbutton class=\"heading-button flex min-h-[52px] w-full py-2.5 items-center\" type=\"button\"\u003e\u003cspan class=\"ml-auto inline-block h-6 transition duration-300 rotate-180\"\u003e\u003csvg viewbox=\"0 0 32 32\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-full w-4 rotate-90 text-[#D31716]\"\u003e\u003cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M19.775 16 4.555 7.629l2.89-5.258L24.26 11.62c3.454 1.9 3.454 6.863 0 8.762L7.447 29.63l-2.893-5.26L19.774 16Z\" fill=\"currentColor\"\u003e\u003c\/path\u003e\u003c
ride.co.uk\/cdn\/shop\/files\/resize_width_1000.jpg?v=1741085512","options":["Title"],"media":[{"alt":null,"id":64543150244223,"position":1,"preview_image":{"aspect_ratio":1.215,"height":745,"width":905,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/resize_width_1000.jpg?v=1741085512"},"aspect_ratio":1.215,"height":745,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/resize_width_1000.jpg?v=1741085512","width":905}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cdiv\u003e\n\u003cdiv class=\"flex h-full flex-col justify-center gap-3\"\u003e\n\u003cdiv class=\"text-lighter-text\"\u003e\u003cspan class=\"text-xl font-semibold text-default-text\"\u003eOrtlieb Back-Roller 40L Pannier Bags - ProjektRide Bike Hire Edinburgh.\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-lighter-text\"\u003e\u003cspan\u003e\u003c\/span\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-lighter-text\"\u003e\u003cspan\u003eSupplied as a pair, these rear pannier bags have hermeticalXS - Sold Out
flex min-h-[52px] w-full py-2.5 items-center\" type=\"button\"\u003e\u003cspan class=\"ml-auto inline-block h-6 transition duration-300 rotate-180\"\u003e\u003csvg viewbox=\"0 0 32 32\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"h-full w-4 rotate-90 text-[#D31716]\"\u003e\u003cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M19.775 16 4.555 7.629l2.89-5.258L24.26 11.62c3.454 1.9 3.454 6.863 0 8.762L7.447 29.63l-2.893-5.26L19.774 16Z\" fill=\"currentColor\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/span\u003e\u003c\/button\u003e\u003c\/div\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {55162210320767 : "deny",};
window._RestockRocketConfig.variantsInventoryQuantity = {55162210320767 : parseInt("-15"),};
window._RestockRocketConfig.variantsPreorderCount = {55162210320767 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderCountForMarket = {55162210320767 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {55162210320767 S - £2,700.00 GBP
tring(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');
<
ings;
} 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 || !settings.multi_language_enabled) {
return settings;
}
if (!settings.translations) {
console.debug('STOQ - No translation
XL - Sold Outs 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;
}
}
// 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-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('STOQ - failed to load settings:', error);
}
})
.catch(function(e) {
console.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._RestockRocketConfig.pageType === 'search' && (settings.show_button_on_search || settings.preorder_search_
-
2- Fork
-
FX alloy, flat-mount disc, rack mounts, 410mm axle-to-crown, ThruSkew 5mm QR3
4
5+
- Hub front
Decrease quantity-
Formula DC-20, alloy, 6-bolt, 100x5 mm
Increase quantity
- Skewer front
<
label for="quantity--template--15326745395426__main">Quantity-
<
input type="number" name="quantity" id="quantity--template--15326745395426__main" value="1" min="1">
139x5 mm bolt-on
Add to cart- Hub rearNotify me when this product is available:
-
Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5 mm
- Skewer rearSubmit
-
window.appBlockPlacements ||= [];
if (window.klarnaAppBlocksManager) {
window.klarnaAppBlocksManager.push({
productVariants: [{"id":56386096628095,"title":"XS","option1":"XS","option2":null,"option3":null,"sku":"5323995","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Sport SL 6 - XS","public_title":"XS","options":["XS"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096660863,"title":"S","option1":"S","option2":null,"option3":null,"sku":"5323996","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek FX Sport SL 6 - S","public_title":"S","options":["S"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096693631,"title":"M","option1":"M","option2":null,"option3":null,"sku":"5323997","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek FX Sport SL 6 - M","public_title":"M","options":["M"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096726399,"title":"L","option1":"L","option2":null,"option3":null,"sku":"5323998","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Sport SL 6 - L","public_title":"L","options":["L"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096759167,"title":"XL","option1":"XL","option2":null,"option3":null,"sku":"5323999","requires_shipping":
true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Sport SL 6 - XL","public_title":"XL","options":["XL"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]}],
templateName: 'product',
dataKey: 'top-strip-promotion-badge',
storefrontCurrency: 'GBP',
storefrontCountry: 'GB',
storefrontLanguage: 'en',
shopLocale: 'en',
shopDomain: 'projektride.co.uk',
variantPrice: '270000',
cartPrice: '0',
selector: 'shopify-osm-ASUorQUNvQS9uckFQO__klarna_on_site_messaging_app_block_8gNReH',
topPadding: '0',
bottomPadding: '0',
});
} else {
window.appBlockPlacements.push({
productVariants: [{"id":56386096628095,"title":"XS","option1":"XS","option2":null,"option3":null,"sku":"5323995","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Spor
t SL 6 - XS","public_title":"XS","options":["XS"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096660863,"title":"S","option1":"S","option2":null,"option3":null,"sku":"5323996","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek FX Sport SL 6 - S","public_title":"S","options":["S"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096693631,"title":"M","option1":"M","option2":null,"option3":null,"sku":"5323997","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek FX Sport SL 6 - M","public_title":"M","options":["M"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096726399,"tit- le":"L","option1":"L","option2":null,"option3":null,"sku":"5323998","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Sport SL 6 - L","public_title":"L","options":["L"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]},{"id":56386096759167,"title":"XL","option1":"XL","option2":null,"option3":null,"sku":"5323999","requires_shipping":true,"taxable":true,"featured_image":null,"available":false,"name":"Trek FX Sport SL 6 - XL","public_title":"XL","options":["XL"],"price":270000,"weight":0,"compare_at_price":null,"inventory_management":"shopify","barcode":"","requires_selling_plan":false,"selling_plan_allocations":[]}],
templateName: 'product',
shopLocale: 'en',
dataKey: 'top-strip-promotion-badge',
storefrontCurrency: 'GBP',
storefrontCountry: 'GB',
storefrontLanguage: 'en',
shopDomain: 'projektride.co.uk',
Rim variantPrice: '270000',
cartPrice: '0',
selector: 'shopify-osm-ASUorQUNvQS9uckFQO__klarna_on_site_messaging_app_block_8gNReH',
topPadding: '0',
bottomPadding: '0',
});
}
-
- TyreProduct Details
-
FX Sport SL 6 is an ultra-light and fast fitness bike. It has every performance feature of a high-end road bike, with the added benefit of flat handlebars for additional comfort and control. A lightweight 400 Series OCLV Carbon frame, wireless electronic SRAM shifting and Bontrager carbon wheels make it the best choice for serious fitness riders with serious goals.
Bontrager H2 Comp, wire bead, 30 tpi, 700x35 mm
*Please note – spec applies to all sizes unless listed separately
Frameset
Frame
- Shifter
-
400 series OCLV Carbon, internal routing, 3s chain keeper, DuoTrap S compatible, mudguard mounts, flat mount disc, 135x5 mm ThruSkew
Fork
- Rear derailleur
-
*Crank
Size:
SRAM Apex 1, 40T, DUB Wide, 170 mm length
Tektro wave, 6-bolt, 160 mm
Skewer rear