Header Image
Visa

Close
Quantity
window._RestockRocketConfig = window._RestockRocketConfig || {} // Stoq is the current name of the app (RestockRocket is the legacy name). // Expose _Stoq / _StoqConfig as live aliases of the same objects so both names // work. Done here, before the JS bundles run, and the bundles only ever do // `window._RestockRocket = window._RestockRocket || {}` (never reassign), so // every method/config added later is visible on both names. window._RestockRocket = window._RestockRocket || {} window._Stoq = window._RestockRocket window._StoqConfig = window._RestockRocketConfig // Helper function to normalize locale format from hyphen to underscore (e.g., 'en-US' -> 'en_us') // This matches the backend'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.liquidRenderedAt = 1782564979;window._RestockRocketConfig.marketId = 382140642;window._RestockRocketConfig.countryName = 'United Kingdom'; window._RestockRocketConfig.countryIsoCode = 'GB';window._RestockRocketConfig.cartInventoryQuantity = {};// cart.token falls back to the `cart` cookie when the Liquid context didn't carry one // (some page types render with cart={} until first interaction). if (!window._RestockRocketConfig.cartToken) { try { const m = document.cookie.match(/(?:^|;\s*)cart=([^;]+)/); if (m && m[1]) window._RestockRocketConfig.cartToken = decodeURIComponent(m[1]); } catch (e) { /* cookie unavailable */ } }window._RestockRocketConfig.cachedSettings = {"id":38500,"shop_id":38436,"currency":"GBP","created_at":"2025-07-26T09:13:57.337Z","updated_at":"2025-12-28T14:44:23.508Z","enable_app":true,"enable_signup_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":{"disableDebugLoggingForNonPreorderItem":false},"storefront_form_email_placeholder":"Email address","storefront_form_phone_placeholder":"SMS","storefront_form_phone_label":"Phone number","storefront_form_email_label":"Email","storefront_form_phone_error":"Please enter a valid phone number","storefront_form_customer_name_placeholder":"Name","storefront_form_customer_name_error":"Pl endpoint + ':', applyError); throw applyError; } }) .catch(function(error) { console.debug(`STOQ - using cached ${endpoint}:`, error.message); }); } function initializeScripts(settings) { settings = applyTranslations(settings); window._RestockRocketConfig.settings = settings; console.debug(`STOQ - settings configured for ${window._RestockRocketConfig.pageType}`); // Stale-Liquid resilience (default-on, per-shop opt-out via the // `disable_refresh_on_stale_liquid` Toggle, surfaced as the negative // `disable_refresh_on_stale_liquid` flag in settings.json so that // `undefined` -- in CDN-cached metafield payloads that predate this // key -- reads as `!undefined === true` and gets default-on behavior // immediately, no metafield rewrite required). // When the Liquid CDN cache is older than LIQUID_CACHE_MAX_AGE the in-page // selling_plans / integrations metafields can be wrong; refresh both from // the API before launching scr ipts. Race against a 1000ms timeout so a slow // API can't block init indefinitely. If the timeout wins, the in-flight // fetches still complete and update window._RestockRocketConfig — the // bundle re-reads sellingPlans/integrations on every interaction, so the // late-arriving values benefit subsequent renders even though the first // paint may use the Liquid-cached values. On any failure the existing // Liquid-loaded values stay in place via fetchEmbedConfig's catch. if (!window._RestockRocketConfig.isLiquidCacheFresh && !settings.disable_refresh_on_stale_liquid) { console.debug('STOQ - Liquid cache stale, refreshing selling_plans + integrations'); Promise.race([ Promise.all([ fetchEmbedConfig('selling_plans', function(data) { if (data && Array.isArray(data.plans)) { window._RestockRocketConfig.sellingPlans = data.plans; window._RestockRocketConfig.disabledSellingPlanIds = data.disabled_plan_ids || [];
} }), fetchEmbedConfig('integrations', function(data) { if (Array.isArray(data)) { window._RestockRocketConfig.integrations = data; } }) ]), new Promise(function(resolve) { setTimeout(resolve, 1000); }) ]).then(function() { loadScripts(settings); }); return; } loadScripts(settings); } function loadScripts(settings) { // Setup cart selling plan updater BEFORE loading any scripts to avoid race conditions 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); }) // STOQ-1520: serve the lean back-in-stock-only build (no preorder/hijack code) // only to shops with NO preorder plans. Use the full build if preorder is o n, // an enabled offer exists, or a disabled-but-kept plan id remains (cart sweep // must still strip those). Rationale in the PR. const hasEnabledOffer = Array.isArray(window._RestockRocketConfig.sellingPlans) && window._RestockRocketConfig.sellingPlans.some(function(plan) { return plan && plan.enabled; }); const hasDisabledPlanIds = Array.isArray(window._RestockRocketConfig.disabledSellingPlanIds) && window._RestockRocketConfig.disabledSellingPlanIds.length > 0; const usePreorderBuild = settings.preorder_enabled || hasEnabledOffer || hasDisabledPlanIds; const collectionScriptUrl = usePreorderBuild ? window._RestockRocketConfig.scriptUrlCollection : window._RestockRocketConfig.scriptUrlCollectionBis; const productScriptUrl = usePreorderBuild ? window._RestockRocketConfig.scriptUrlProduct : window._RestockRocketConfig.scriptUrlProductBis; const pageType = window._RestockRocketConfig.pageType; const collecti
onPageTypes = ['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) { // cart/article/blog/list-collections: full build so the cart sweep runs. createRestockRocketScript(window._RestockRocketConfig.scriptUrlCollection); } else { console.debug(`STOQ - no scripts enabled for ${pageType}`); } // Dispatch custom event when app is loaded // Cart selling plan updates will be triggered by stoq:inventory-data-loaded event const appLoadedEvent = new CustomEvent('stoq:loaded', { detail: { pageType: window._RestockR ocketConfig.pageType, enabled: settings.enable_app, settings: settings, preorderEnabled: settings.preorder_enabled } }); console.debug('STOQ - dispatching app loaded event'); window.dispatchEvent(appLoadedEvent); } }

Marlin 5 is a trail-worthy daily rider that's perfectly suited for everyday adventures, on and off the trail. It features a trail-savvy frame with a suspension fork, 9-speed Shimano CUES shifting and mounts for a rack and kickstand that make it an ideal choice for trail riders or anyone looking for a comfortable, stable commuter with the ruggedness of a real mountain bike.

*Please note – spec applies to all sizes unless listed separately

*Frame
Size: XS
Alpha Silver Aluminium, curved top tube, internal derailleur and dropper post routing, rack and kickstand mount, 135x5 mm ThruSkew
Size: S , M , ML , L , XL , XXL
Alpha Silver Aluminium, internal derailleur and dropper post routing, rack and kickstand mount, 135x5 mm ThruSkew
*Fork
Size: XS
SR Suntour XCT 30, coil spring, preload, hydraulic lockout, 42 mm offset for 27.5" wheel, 100 mm QR, 80 mm travel
Size: S
SR Suntour XCT 30, coil spring, preload, hydraulic lockout, 42 mm offset for 27.5" wheel, 100 mm QR, 100 mm travel
Size: M , ML , L , XL , XXL
SR Suntour XCT 30, coil spring, preload, hydraulic lockout, 42 mm offset for 29" wheel, 100 mm QR, 100 mm travel

Hub front
Formula DC-20, alloy, 6-bolt, 100x5 mm
Skewer front
Trek Thru-Skew
Hub rear
Formula DC-22, alloy, 6-bolt, Shimano 8/9/10 freehub, 135x5 mm
Skewer rear
Rim
Bontrager Connection, double-wall, 32-hole, 20 mm width, Schrader valve
Spokes
14 g stainless steel, black
*Tyre
Size: XS , S
Bontrager Montrose Comp, wire bead, 30 tpi, 27.5x2.40"
Size: M , ML , L , XL , XXL
Bontrager Montrose Comp, wire bead, 30 tpi, 29x2.40"

Shifter
Shimano U4000, 9-speed
Rear derailleur
Shimano CUES U4000
*Crank
Size: XS , S , M , ML
Shimano CUES U4001, 32T, 52mm chain line, 170 mm length
Size: L , XL , XXL
Shimano CUES U4001, 32T, 52mm chain line, 175mm length
Bottom bracket
Shimano, 73 mm, threaded cartridge, 122.5 mm spindle
Cassette
Shimano LINKGLIDE LG300, 11-46, 9-speed
Chain
Shimano LG500
Pedal

Saddle
*Seatpost
Size: XS , S , M
Bontrager alloy, 31.6 mm, 12 mm offset, 330 mm length
Size: ML , L , XL , XXL
Bontrager alloy, 31.6 mm, 12 mm offset, 400 mm length
*Handlebar
Size: XS
Bontrager alloy, 31.8 mm, 5 mm rise, 690 mm width
Size: S
Bontrager alloy, 31.8 mm, 15 mm rise, 720 mm width
Size: M , ML , L , XL , XXL
Bontrager alloy, 31.8 mm, 15 mm rise, 750 mm width
Grips
*Stem
Size: XS , S
Bontrager Comp, 31.8 mm, 7-degree, 35 mm length
Size: M , ML , L
Bontrager Comp, 31.8 mm, Blendr compatible, 7-degree, 50 mm length
Head set
Semi-integrated, 1-1/8"
Brake
Shimano MT200 hydraulic disc
*Brake rotor
Size: XS , S , M , ML , L , XL , XXL
Shimano RT26, 6-bolt, 160 mm
Size: M , ML , L , XL , XXL
Shimano RT26, 6-bolt, 180 mm
Brake Set
Shimano MT200 hydraulic disc

Weight
M - 15.10 kg / 33.29 lbs
Weight limit
This bike has a maximum total weight limit (combined weight of bicycle, rider and cargo) of 136 kg (300 lb).

We reserve the right to make changes to the product information contained on this site at any time without notice, including with respect to equipment, specifications, models, colours, materials and pricing. Due to supply chain issues, compatible parts may be substituted at any time without notice.

Bike and frame weights are based on pre-production painted frames at time of publication. Weights may vary in final production.

Frequently Asked Questions

  • Please get in touch with a member of the team either by phone (01313745324) or email ([email protected]) where on of the team will be more than happy to help.

    ProjektRide Bike Shop Edinburgh

  • 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.

    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.