"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-kmgndo\" role=\"tabpanel\" aria-labelledby=\"pdl-collapse-head-kmgndo\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"\" data-old-overflow=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"pdl-collapse-item__content\"\u003e\n\u003ctable data-v-05762449=\"\" aria-label=\"Specifications\" class=\"sprocket__table spec\"\u003e\n\u003ctbody data-v-05762449=\"\"\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eCharger\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eBosch standard 4A, 230V, smart system\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eContr
qaid=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"flex items-center flex-grow\"\u003eDrivetrain\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-49tgc9\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24px\" fill=\"currentcolor\" aria-hidden=\"true\" role=\"presentation\" class=\"pdl-collapse-item__icon pdl-icon pdl-icon--size-24 is-active\" qaid=\"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-49tgc9\" role=\"tabpanel\" aria-labelledby=\"pdl-collapse-head-49tgc9\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"
#SiteFooter .footer-block--logo { min-width: calc(160px + calc(var(--gutter) / 2)); }
#SiteFooter .footer-block__logo-image { width: 160px; }r data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eCassette\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eGates CDX, 32T\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003ePedal\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/5254979\"\u003eBontrager City pedals\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" scope=\"row\"\u003eMax. chainring size\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e50T (Gates belt sprocket)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" data-v-05762449=\"\" id=\"pdl-collapse-item-7a5pzs\" name=\"407\" class=\"pdl-collapse-item is-active\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" role=
el\" aria-labelledby=\"pdl-collapse-head-7a5pzs\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"\" data-old-overflow=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"pdl-collapse-item__content\"\u003e\n\u003ctable data-v-05762449=\"\" aria-label=\"Specifications\" class=\"sprocket__table spec\"\u003e\n\u003ctbody data-v-05762449=\"\"\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eSaddle\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eBontrager Boulevard\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eSeatpost\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eAlloy, suspension, 31.6 mm, 300 mm length\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eHandlebar\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\
{"@context":"http:\/\/schema.org\/","@id":"\/products\/trek-fetch-2#product","@type":"ProductGroup","brand":{"@type":"Brand","name":"Trek"},"category":"Electric Bikes","description":"The Fetch+ 2 is a compact electric cargo bike that hauls a lot and is super fun and simple to use. You can easily carry up to 80 kg of cargo, thanks to the powerful boost of the Bosch smart system and best-in-class handling and stability. This bike is designed to grow with your family, and offers multiple configuration options to best suit your needs as they shift and change over time.\n\n*Please note – spec applies to all sizes unless listed separately\n\n\nFrameset\n\n\n\n\n\n\n\nFrame\nHigh-performance hydroformed alloy, low-step, Removable Integrated Battery, internal cable routing, Motor Armour, post-mount disc, 148x12 thru axle\n\n\n\n\n\n\n\n\nWheels\n\n\n\n\n\n\n\nHub front\nFormula DC-71 alloy, sealed bearing, 6-bolt, 15x100 mm thru axle\n\n\nSkewer front\nBontrager Switch thru axle, removable lever\n\n\nHub rear\nFormula EHL-148S, sealed bearing, 6-bolt, Shimano 10 freehub, 148x12 mm thru axle\n\n\nSkewer rear\nBontrager Switch thru-axle, removable lever\n\n\nRim\nAlloy double-walled, 32-hole\n\n\nSpokes\n14 g stainless steel, black\n\n\nTyre\nSchwalbe Pick-Up, Addix E-Compound, ECE-R75 approved, wire bead, 20 x 2.35\"\n\n\n\n\n\n\n\n\nE-system\n\n\n\n\n\n\n\nBattery\nBosch PowerTube 500 Wh, smart system\n\n\nCharger\nBosch standard 4A, 230V, smart system\n\n\nController\nBosch BSP3200 smart phone grip\n\n\nComputer\nBosch LED remote, smart system\n\n\nMotor\nBosch Performance Line Cargo, smart system, magnesium motor body, 85 Nm\n\n\n\n\n\n\n\n\nDrivetrain\n\n\n\n\n\n\n\nShifter\nShimano Deore M4100, 10-speed\n\n\nRear derailleur\nShimano Deore M6000, mid cage, 42T max cog\n\n\nCrank\nProWheel alloy, 165mm length\n\n\nChainring\nProWheel, 46T narrow\/wide, alloy\n\n\nChain\nKMC E10\n\n\nPedal\nBontrager City pedals\n\n\n\n\n\n\n\n\nComponents\n\n\n\n\n\n\n\nSaddle\nBontrager Boulevard\n\n\nSeatpost\nBontrager alloy, telescoping, 34.9 mm\n\n\nHandlebar\nElectra Vale Go\n\n\nGrips\nBontrager Satellite Elite, alloy lock-on\n\n\nStem\nadjustable aluminium, 31.8 mm, 90 mm length,\n\n\nBrake\nHD-T737 4-piston hydraulic disc\n\n\nBrake rotor\nTektro wave, 6-bolt, 180 mm\n\n\n\n\n\n\n\n\nAccessories\n\n\n\n\n\n\n\n*Light\n\nSize: One size fits mostSpanninga Solo\n\n\n\n\nSize: One size fits mostHerrmans H-Black MR8-E, 180 Lumen, 60 Lux, LED, headlight\n\n\n\nKickstand\nFetch custom\n\n\n\n\n\n\n\n\nWeight\n\n\n\n\n\n\n\nWeight\n31 kg\/68.35 lb\n\n\nWeight limit\nThis bike has a maximum total weight limit (combined weight of bicycle, rider, and cargo) of 200 kg (441 lb).\n\n\n\n\n\n\n\n\nWe 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. The prices shown are the manufacturer's suggested retail prices.\n\n\nBike and frame weights are based on pre-production painted frames at time of publication. Weights may vary in final production.\n\n","hasVariant":[{"@id":"\/products\/trek-fetch-2?variant=45824821887202#variant","@type":"Product","image":"https:\/\/projektride.co.uk\/cdn\/shop\/files\/FetchPlus2EU-24-37063-B-Primary.webp?v=1723937960\u0026width=1920","name":"Trek Fetch+ 2 - Red","offers":{"@id":"\/products\/trek-fetch-2?variant=45824821887202#offer","@type":"Offer","availability":"http:\/\/schema.org\/OutOfStock","price":"3562.50","priceCurrency":"GBP","url":"https:\/\/projektride.co.uk\/products\/trek-fetch-2?variant=45824821887202"},"sku":"5279412"},{"@id":"\/products\/trek-fetch-2?variant=45824821919970#variant","@type":"Product","image":"https:\/\/projektride.co.uk\/cdn\/shop\/files\/FetchPlus2EU-24-37063-B-Primary.webp?v=1723937960\u0026width=1920","name":"Trek Fetch+ 2 - Green","offers":{"@id":"\/products\/trek-fetch-2?variant=45824821919970#offer","@type":"Offer","availability":"http:\/\/schema.org\/OutOfStock","price":"3562.50","priceCurrency":"GBP","url":"https:\/\/projektride.co.uk\/products\/trek-fetch-2?variant=45824821919970"},"sku":"5279413"},{"@id":"\/products\/trek-fetch-2?variant=45824821952738#variant","@type":"Product","image":"https:\/\/projektride.co.uk\/cdn\/shop\/files\/FetchPlus2EU-24-37063-B-Primary.webp?v=1723937960\u0026width=1920","name":"Trek Fetch+ 2 - Gray","offers":{"@id":"\/products\/trek-fetch-2?variant=45824821952738#offer","@type":"Offer","availability":"http:\/\/schema.org\/OutOfStock","price":"3562.50","priceCurrency":"GBP","url":"https:\/\/projektride.co.uk\/products\/trek-fetch-2?variant=45824821952738"},"sku":"5279414"}],"name":"Trek Fetch+ 2","productGroupID":"8679050248418","url":"https:\/\/projektride.co.uk\/products\/trek-fetch-2"}
Buy, sell and ride in confidence on ProjektRide’s premium bikesB\/p\/W5284846\"\u003eAlloy rear rack, 25 kg max weight\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"2\" scope=\"row\"\u003e*Mudguard\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\n\u003cspan data-v-05762449=\"\"\u003eSize:\u003c\/span\u003e\u003cspan\u003e \u003c\/span\u003eL, XL, XXL\u003cbr data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/W1043754\"\u003eSKS plastic, rear\u003c\/a\u003e\n\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003ctd data-v-05762449=\"\"\u003e\n\u003cspan data-v-05762449=\"\"\u003eSize:\u003c\/span\u003e\u003cspan\u003e \u003c\/span\u003eL, XL, XXL\u003cbr data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/W1051529\"\u003eSKS plastic, front\u003c\/a\u003e\n\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003c\/div\u003e\n\u003c
8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-dgkjj4\" role=\"tabpanel\" aria-labelledby=\"pdl-collapse-head-dgkjj4\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"\" data-old-overflow=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"pdl-collapse-item__content\"\u003e\n\u003ctable data-v-05762449=\"\" aria-label=\"Specifications\" class=\"sprocket__table spec\"\u003e\n\u003ctbody data-v-05762449=\"\"\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" scope=\"row\"\u003eWeight\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eL - 26.20 kg \/ 57.77 lbs (excluding battery)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" scope=\"row\"\u003eWeight limit\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eThis bike has a maximum total weight limit (combined wei
Quick Links3cdiv\u003e\u003cfooter class=\"yCmsContentSlot footer\"\u003e\n\u003cdiv class=\"grid-container\"\u003e\n\u003cdiv id=\"lightbox-inline-form-641e4d89-c50f-4333-a93a-8155282d70b0\"\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/footer\u003e\u003c\/div\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003c!----\u003e","published_at":"2024-10-10T15:18:35+01:00","created_at":"2024-08-18T00:50:26+01:00","vendor":"Trek","type":"bike","tags":["District"],"price":332500,"price_min":332500,"price_max":384750,"available":true,"price_varies":true,"compare_at_price":350000,"compare_at_price_min":350000,"compare_at_price_max":405000,"compare_at_price_varies":true,"variants":[{"id":45824831389922,"title":"Extra Large \/ 545WH","option1":"Extra Large","option2":"545WH","option3":null,"sku":"5295007","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek District+ 4 - Extra Large \/ 545WH","public_title":"Extra Large \/ 545WH","options":["Extra Large","545WH"],"price":332500,"weight":0,"compa
a Large","800WH"],"price":384750,"weight":0,"compare_at_price":405000,"inventory_management":"shopify","barcode":null,"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":45824831488226,"title":"Extra Extra Large \/ 545WH","option1":"Extra Extra Large","option2":"545WH","option3":null,"sku":"5295010","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Trek District+ 4 - Extra Extra Large \/ 545WH","public_title":"Extra Extra Large \/ 545WH","options":["Extra Extra Large","545WH"],"price":332500,"weight":0,"compare_at_price":350000,"inventory_management":"shopify","barcode":null,"requires_selling_plan":false,"selling_plan_allocations":[],"quantity_rule":{"min":1,"max":null,"increment":1}},{"id":45824831520994,"title":"Extra Extra Large \/ 725WH","option1":"Extra Extra Large","option2":"725WH","option3":null,"sku":"5295011","requires_shipping":true,"taxable":true,"featured_image":null,"available":true,"name":"Tre
ured_image":"\/\/projektride.co.uk\/cdn\/shop\/files\/District_Plus_4_Men_23_36971_A_Primary.webp?v=1723938351","options":["Size","Battery"],"media":[{"alt":null,"id":34472743108834,"position":1,"preview_image":{"aspect_ratio":1.333,"height":1440,"width":1920,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/District_Plus_4_Men_23_36971_A_Primary.webp?v=1723938351"},"aspect_ratio":1.333,"height":1440,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/District_Plus_4_Men_23_36971_A_Primary.webp?v=1723938351","width":1920}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003e\u003cmeta charset=\"utf-8\"\u003e\u003cspan\u003eThe District+ 4 is a sleek and capable city e-bike with rugged durability and top-end comfort. Its frame integrates the batteries inside the downtube and comes with four battery capacity options, ranging from 400 Wh to 800 Wh, so you can choose what's right for your commute. The District+ 4 features a belt drive for low maintenance durability. Bosch
Frequently Asked Questions
pec applies to all sizes unless listed separately\u003c\/p\u003e\n\u003cdiv data-v-5bd42f3c=\"\" data-v-05762449=\"\" id=\"pdl-collapse-item-okyuo9\" name=\"395\" class=\"pdl-collapse-item is-active\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" role=\"tab\" aria-controls=\"pdl-collapse-content-okyuo9\" aria-describedby=\"pdl-collapse-content-okyuo9\" class=\"\" aria-expanded=\"true\" qaid=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"flex items-center flex-grow\"\u003eFrameset\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-okyuo9\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24px\" fill=\"currentcolor\" aria-hidden=\"true\" role=\"presentation\" class=\"pdl-collapse-item__icon pdl-icon pdl-icon--size-24 is-active\" qaid=\"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e
5762449=\"\"\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eHub front\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eAlloy, CenterLock disc, 100 mm thru axle\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eHub rear\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eShimano Nexus C7000, 5-speed\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eRim\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/5252869\"\u003eBontrager Connection, double-wall, 32-hole, 20 mm width, Presta valve\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eSpokes\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e14 g stainle
aid=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"flex items-center flex-grow\"\u003eE-system\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-kmgndo\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24px\" fill=\"currentcolor\" aria-hidden=\"true\" role=\"presentation\" class=\"pdl-collapse-item__icon pdl-icon pdl-icon--size-24 is-active\" qaid=\"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-kmgndo\" role=\"tabpanel\" aria-labelledby=\"pdl-collapse-head-kmgndo\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"\" d
Contact Usrow\"\u003eMotor\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eBosch Performance Line, 250 W, 75 Nm, 20 mph (25 km\/h in Europe)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" data-v-05762449=\"\" id=\"pdl-collapse-item-49tgc9\" name=\"404\" class=\"pdl-collapse-item is-active\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" role=\"tab\" aria-controls=\"pdl-collapse-content-49tgc9\" aria-describedby=\"pdl-collapse-content-49tgc9\" class=\"\" aria-expanded=\"true\" qaid=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"flex items-center flex-grow\"\u003eDrivetrain\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-49tgc9\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24pI'm looking to find out more information about a product, where can I find this?Blogte, alloy lock-on\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eStem\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/5262987\"\u003eBontrager alloy, 31.8 mm clamp, adjustable rise, Blendr-compatible, 105 mm length\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eBrake\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003eTektro HD-M275 hydraulic disc\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"2\" scope=\"row\"\u003e*Brake rotor\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\n\u003cspan data-v-05762449=\"\"\u003eSize:\u003c\/span\u003e\u003cspan\u003e \u003c\/span\u003eL, XL, XXL\u003cbr data-v-05762449=\"\"\u003eShimano EM300, CenterLock, 160 mm\u003c\/tPlease get in touch with a member of the team either by phone (
bd42f3c=\"\" role=\"tab\" aria-controls=\"pdl-collapse-content-orwwl\" aria-describedby=\"pdl-collapse-content-orwwl\" class=\"\" aria-expanded=\"true\" qaid=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"flex items-center flex-grow\"\u003eAccessories\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-orwwl\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24px\" fill=\"currentcolor\" aria-hidden=\"true\" role=\"presentation\" class=\"pdl-collapse-item__icon pdl-icon pdl-icon--size-24 is-active\" qaid=\"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-orwwl\01313745324
\u003c\/span\u003eL, XL, XXL\u003cbr data-v-05762449=\"\"\u003eHerrmans MR4, 120-lumen LED\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eKickstand\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003ePletscher Comp Flex 18\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"1\" scope=\"row\"\u003eCargo rack\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" href=\"https:\/\/www.trekbikes.com\/gb\/en_GB\/p\/W5284846\"\u003eAlloy rear rack, 25 kg max weight\u003c\/a\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-v-05762449=\"\"\u003e\n\u003cth data-v-05762449=\"\" rowspan=\"2\" scope=\"row\"\u003e*Mudguard\u003c\/th\u003e\n\u003ctd data-v-05762449=\"\"\u003e\n\u003cspan data-v-05762449=\"\"\u003eSize:\u003c\/span\u003e\u003cspan\u003e \u003c\/span\u003eL, XL, XXL\u003cbr data-v-05762449=\"\"\u003e\u003ca data-v-05762449=\"\" ) or email (Track Service Progressight\u003c\/div\u003e\n\u003cbutton data-v-5bd42f3c=\"\" id=\"pdl-collapse-head-dgkjj4\" type=\"button\" class=\"pdl-collapse-item__header is-active flex-row-reverse items-center\" tabindex=\"0\"\u003e\u003csvg data-v-1e7396ba=\"\" data-v-5bd42f3c=\"\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 24 24\" width=\"24px\" height=\"24px\" fill=\"currentcolor\" aria-hidden=\"true\" role=\"presentation\" class=\"pdl-collapse-item__icon pdl-icon pdl-icon--size-24 is-active\" qaid=\"\"\u003e\u003cpath d=\"M0 0h24v24H0z\" fill=\"none\"\u003e\u003c\/path\u003e\u003cpath d=\"M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\u003e\u003c\/path\u003e\u003c\/svg\u003e\u003c\/button\u003e\n\u003c\/div\u003e\n\u003cdiv data-v-5bd42f3c=\"\" id=\"pdl-collapse-content-dgkjj4\" role=\"tabpanel\" aria-labelledby=\"pdl-collapse-head-dgkjj4\" class=\"pdl-collapse-item__wrap\" data-old-padding-top=\"\" data-old-padding-bottom=\"\" data-old-overflow=\"\"\u003e\n\u003cdiv data-v-5bd42f3c=\"\" class=\"pdl-collapse-item__content[email protected]
rials and pricing. Due to supply chain issues, compatible parts may be substituted at any time without notice. The prices shown are the manufacturer's suggested retail prices.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"mb-1\"\u003e\n\u003cp\u003eBike and frame weights are based on pre-production painted frames at time of publication. Weights may vary in final production.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/section\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/section\u003e\n\u003c\/main\u003e\n\u003cdiv\u003e\u003cfooter class=\"yCmsContentSlot footer\"\u003e\n\u003cdiv class=\"grid-container\"\u003e\n\u003cdiv id=\"lightbox-inline-form-641e4d89-c50f-4333-a93a-8155282d70b0\"\u003e\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c\/footer\u003e\u003c\/div\u003e\n\u003cp\u003e \u003c\/p\u003e\n\u003c!----\u003e"};
window._RestockRocketConfig.variantsInventoryPolicy = {45824831389922 : "deny",45824831422690 : "deny",45824831455458 : ) where on of the team will be more than happy to help.
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {45824831389922 : null,45824831422690 : null,45824831455458 : null,45824831488226 : null,45824831520994 : null,45824831553762 : null,};
window._RestockRocketConfig.variantsShippingText = {45824831389922 : "",45824831422690 : "",45824831455458 : "",45824831488226 : "",45824831520994 : "",45824831553762 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {45824831389922 : null,45824831422690 : null,45824831455458 : null,45824831488226 : null,45824831520994 : null,45824831553762 : null,};
window._RestockRocketConfig.selected_variant_id = 45824831389922;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;// STOQ-1595/1612 shared signal, derived once here so both the accelerated-checkout block
// gate (STOQ-1612) and the click tracker (STOQ-1595) read one clearProjektRide Bike Shop Edinburgh
Building Your Bike From the Boxaccelerated_checkout` toggle (default OFF) for gradual rollout.
// Armed ONLY when we're sure preorder is in play — product page: THIS product has a
// preorder variant (never block a plain product's Shop Pay); featured: integration
// enabled for this page type. Rationale: PR #2784.
try {
var _sqc = window._RestockRocketConfig;
var _sqOn = !!(_sqc.cachedSettings && _sqc.cachedSettings.block_accelerated_checkout);
var _sqPre = (_sqc.cachedPreorderVariantIds &&
_sqc.cachedPreorderVariantIds.preorder_variant_ids) || [];
var _sqArm = false;
if (_sqOn && _sqc.preordersConfigured) {
if (_sqc.pageType === 'product' && _sqc.product && _sqc.product.variants) {
_sqArm = _sqc.product.variants.some(function (v) { return _sqPre.indexOf(Number(v.id)) !== -1; });
} else {
_sqArm = (_sqc.integrations || []).some(function (i) {
return i && i.type === 'featured_product' && i.enabled &&
Array.isArray(i.page_types) && i.page_types.indexOf(_sqc
7522a/restockrocket-1-539/assets/restockrocket-collection-bis.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when present, mirroring the same
// override in assets/js/api.js. cachedSettings is populated above. Falls
// back to the build-baked host for shops without the use_render_api_host
// toggle (or environments where THEME_EXTENSION_API_HOST is unset), so the
// setting.json + fetchEmbedConfig calls below route to the same host as the
// rest of the extension's API traffic instead of staying on the baked host.
window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://app.restockrocket.io'
// Deployed extension build number, read from the CDN asset host Shopify genera
t":800,"width":1200,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/L-FC67_media-TEAL-9.jpg?v=1736263149"},"aspect_ratio":1.5,"height":800,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/L-FC67_media-TEAL-9.jpg?v=1736263149","width":1200},{"alt":null,"id":63810039775615,"position":11,"preview_image":{"aspect_ratio":1.5,"height":800,"width":1200,"src":"\/\/projektride.co.uk\/cdn\/shop\/files\/L-FC67_media-TEAL-1.jpg?v=1736263149"},"aspect_ratio":1.5,"height":800,"media_type":"image","src":"\/\/projektride.co.uk\/cdn\/shop\/files\/L-FC67_media-TEAL-1.jpg?v=1736263149","width":1200}],"requires_selling_plan":false,"selling_plan_groups":[],"content":"\u003cp\u003e \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eWhy buy a Frog City 67? \u003c\/strong\u003e\u003c\/p\u003e\n\u003cul data-mce-fragment=\"1\"\u003e\n\u003cli data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eLightweight 26-inch geared urban bike with step-through frBook a Service
tand included\u003c\/span\u003e\u003c\/li\u003e\n\u003cli data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eSuitable for 10 to 12 years with a recommended inside leg of 63cm-81cm\u003c\/span\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003e \u003c\/span\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eThe 26-inch Frog City 67 kids’ bike is the ultimate urban geared bike, suitable for 10 to 12-year-olds. This premium children’s city bike is designed for everyday use allowing kids to commute to school or explore the city in comfort and style. It has a lightweight, aluminium step-through frame, weighing just 9.61kg making the bike easy to mount and dismount and handle around town. \u003c\/span\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eWith this versatile city
cling success\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eThe Frog City 67 urban bike is suitable for 10 to 12 years with a recommended inside leg measurement of 63cm-81cm.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003eOne of the biggest temptations is to buy a child's bike that they will grow into. However, this will likely have the opposite effect and put your child off bikes and cycling altogether! Another common mistake is to purchase a budget kids' bike but these models are often as heavy as a child which can lead to frustration at not being able to cycle. That’s why Frog bikes are lightweight and designed to specifically accommodate the anatomy of children.\u003c\/span\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\
3e \u003c\/span\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003cstrong data-mce-fragment=\"1\"\u003eAvailable colours*\u003c\/strong\u003e: Teal, Pink, Black \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e\u003csmall data-mce-fragment=\"1\"\u003e\u003cspan data-mce-fragment=\"1\"\u003e*Actual colours may vary. This is due to the fact that every computer monitor has a different capability to display colours and that everyone sees these colours differently. Our photos show the samples as life-like as possible, but please understand the actual colour may vary slightly as paint batches also have variances. We cannot guarantee that the colour you see accurately portrays the true colour of the product.\u003c\/span\u003e\u003c\/small\u003e\u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e \u003c\/p\u003e\n\u003cp data-mce-fragment=\"1\"\u003e \u003cbr data-mce-fragment=\"1\"\u003e\u003c\/p\u003e\n\u003cdiv id=\"product-details-information-tab-content-container-1\" class=\"product-deWorkshop PricesRecently viewed003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003e9.61kg (with pedals) \/ 11.01kg (with pedals \u0026amp; accessories)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eFrame\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003e6061 T6 heat treated Aluminum alloy, seat tube 16\" (406mm)\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eFork\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003e6061 T6 heat treated Aluminum alloy\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eFront Hub\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eQuando, Aluminum, sealed hub, QR, 28 hole\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eRear Hub\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eQuando, Aluminum, sealed hub, QR, 28 hole, Shimano type 8\/9s
d\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eNeco, 1\"1\/8 semi-integrated threadless, Frog Bikes top cap\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eStem\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eAluminum, 1\"1\/8, 60mm, 4 bolt clamp\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eGear Shifter\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eFrogFitTechnology®, youth-specific 8-speed with short lever travel and ultra-slick gear cable\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eBrakes (F\u0026amp;R)\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eTektro 836AL, Aluminum, linear pull\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eTyres\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eKenda K154, 26\"x1.5\", Cit
03e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003ePedals\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eFrog Bikes, eco-friendly rice husk \u0026amp; plastic composite, with reflectors, 9\/16\"\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eChain\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eKMC, 8-speed\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eHandlebar\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eAlloy, 620mm width, 60mm rise, 25º sweep\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eBrake Levers\u003c\/td\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eTektro JL510, Aluminum, easy reach\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr data-mce-fragment=\"1\"\u003e\n\u003ctd data-mce-fragment=\"1\"\u003eSaddle\u003c\/td\u003e\n\u003ctd Cycle to Work
window._RestockRocketConfig.variantsPreorderCountForMarket = {54939170537855 : null,54939170570623 : null,54939170603391 : null,};
window._RestockRocketConfig.variantsPreorderMaxCount = {54939170537855 : parseInt(""),54939170570623 : parseInt(""),54939170603391 : parseInt(""),};
window._RestockRocketConfig.variantsPreorderMaxCountForMarket = {54939170537855 : null,54939170570623 : null,54939170603391 : null,};
window._RestockRocketConfig.variantsShippingText = {54939170537855 : "",54939170570623 : "",54939170603391 : "",};
window._RestockRocketConfig.variantsShippingTextForMarket = {54939170537855 : null,54939170570623 : null,54939170603391 : null,};
window._RestockRocketConfig.selected_variant_id = 54939170537855;
window._RestockRocketConfig.selected_variant_available = window._RestockRocketConfig.product.variants.find(function(variant) { return variant.id == window._RestockRocketConfig.selected_variant_id }).available;// STOQ-1595/1612 shared signal, derived once here so both the ac
timeout releases; renderPreorderButton / featured_product.js lift it.
// Gated by the `block_accelerated_checkout` toggle (default OFF) for gradual rollout.
// Armed ONLY when we're sure preorder is in play — product page: THIS product has a
// preorder variant (never block a plain product's Shop Pay); featured: integration
// enabled for this page type. Rationale: PR #2784.
try {
var _sqc = window._RestockRocketConfig;
var _sqOn = !!(_sqc.cachedSettings && _sqc.cachedSettings.block_accelerated_checkout);
var _sqPre = (_sqc.cachedPreorderVariantIds &&
_sqc.cachedPreorderVariantIds.preorder_variant_ids) || [];
var _sqArm = false;
if (_sqOn && _sqc.preordersConfigured) {
if (_sqc.pageType === 'product' && _sqc.product && _sqc.product.variants) {
_sqArm = _sqc.product.variants.some(function (v) { return _sqPre.indexOf(Number(v.id)) !== -1; });
} else {
_sqArm = (_sqc.integrations || []).some(function (i) {
return i && i.type === 'feature
ig.scriptUrlCollectionBis = 'https://cdn.shopify.com/extensions/019f37a7-f058-7bcb-a02d-3fb0b8a7522a/restockrocket-1-539/assets/restockrocket-collection-bis.js'
window._RestockRocketConfig.scriptHost = window._RestockRocketConfig.scriptUrlProduct.substring(0, window._RestockRocketConfig.scriptUrlProduct.lastIndexOf('/') + 1)
// Canary override (STOQ-1287): prefer the Render host emitted into the
// metafield-cached settings (api_host) when present, mirroring the same
// override in assets/js/api.js. cachedSettings is populated above. Falls
// back to the build-baked host for shops without the use_render_api_host
// toggle (or environments where THEME_EXTENSION_API_HOST is unset), so the
// setting.json + fetchEmbedConfig calls below route to the same host as the
// rest of the extension's API traffic instead of staying on the baked host.
window._RestockRocketConfig.host = (window._RestockRocketConfig.cachedSettings && window._RestockRocketConfig.cachedSettings.api_host) || 'https://app.restoDelivery & Returns
<
<
che age
if (!liquidRenderedAt || typeof liquidRenderedAt !== 'number' || isNaN(liquidRenderedAt)) {
console.debug('STOQ - Invalid or missing liquidRenderedAt timestamp, assuming fresh');
window._RestockRocketConfig.isLiquidCacheFresh = true;
window._RestockRocketConfig.liquidCacheAge = null;
} else {
const now = Math.floor(Date.now() / 1000); // Current time in seconds
const liquidCacheAge = now - liquidRenderedAt; // Age in seconds
// Surfaced into funnel events: a stale cache means the app rendered with
// outdated inventory/selling-plan data — a real "had the opportunity but
// failed" cause. Negative (client clock ahead) clamps to 0.
window._RestockRocketConfig.liquidCacheAge = Math.max(0, liquidCacheAge);
// Handle client clock ahead of server
if (liquidCacheAge Mon - Fri: 09:00 - 18:30
0) {
console.debug(`STOQ - Client clock appears ahead of server by ${Math.abs(Math.round(liquidCacheAge / 60))} minutes, assuming cache fresh`);
window._RestockRocketConfig.isLiquidCacheFresh = true;
} else if (liquidCacheAge Sat: 9:00 - 16:00
ProjektRide Bike Shop Edinburghtranslation 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
82 Newington Road, EH91QN, Edinburgh.<Sale
tomer interaction.
// Detected variants: the variants present in this page's Liquid context (product page has them;
// collection/index/etc. don't expose variants from Liquid). Used to disambiguate "embed didn't
// load" vs "embed loaded but the variant wasn't a preorder/BIS candidate" in order debug.
try {
const _stoqInitConfig = window._RestockRocketConfig;
const _stoqDetectedVariantIds = (_stoqInitConfig.product && Array.isArray(_stoqInitConfig.product.variants))
? _stoqInitConfig.product.variants.map(function(v) { return v.id })
: [];
const _stoqSelectedVariantId = _stoqInitConfig.selected_variant_id;
Shopify?.analytics?.publish?.('stoq_initialized', {
cart_token: _stoqInitConfig.cartToken || '',
page_url: window.location.href,
page_type: _stoqInitConfig.pageType || '',
shop_domain: _stoqInitConfig.shop || '',
market_id: _stoqInitConfig.marketId || '',
detected_variant_ids: _stoqDetectedVariantIds,
selected_variant_id: _stoqSele
on block above) — nothing to bypass otherwise. variant_id is read per-clicked-button
// from its form so it's correct on collection/index/search too. block_accelerated_checkout
// context (STOQ-1612) rides in `properties` (forwarded verbatim by the pixel, no schema
// change): a buy_now click on a preorder variant while the gate was armed is a visible
// bypass signal for order debug. Also sends page_url (top-level, like the pixel's native
// events) and two preorder signals in properties (see below).
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.close
ack.product && _sqTrack.product.id) || '',
channel: channel,
market_id: _sqTrack.marketId || '',
page_type: _sqTrack.pageType || '',
cart_token: _sqTrack.cartToken || '',
page_url: (window.location && window.location.href) || '',
properties: {
// Mirror the bundle's own preorder check (preorder.js checkInventoryProvider-
// WithCachedFallback): the live set config.preorderVariantIds (refreshed after
// page load by loadVariantInventoryData) OR the Liquid-injected
// cachedPreorderVariantIds — always present, so it covers clicks before the
// bundle loads (why this tracker is inline). ORing both (not preferring one)
// matches the bundle and is correct even if the live set is an empty array. Both
// hold integer ids; the click-time id comes off a DOM input (.value → string) or
// selected_variant_id, so coerce with Number for
er bypass is detectable too.
is_instock_variant: (function () {
var has = function (a) { return Array.isArray(a) && a.indexOf(_sqVidNum) !== -1; };
return has(_sqTrack.inStockVariantIds) ||
has(_sqTrack.cachedInStockVariantIds &&
_sqTrack.cachedInStockVariantIds.in_stock_variant_ids);
})(),
// The enrolled plan's Shopify selling-plan id + inventory_provider (stoq = STOQ tracks
// the OOS count; shopify = in-stock preorder). Tells order-debug what kind of preorder
// the Buy Now bypassed, without a downstream lookup.
enrolled_plan_id: (_sqPlan && (_sqPlan.shopify_selling_plan_id || _sqPlan.shopify_selling_plan_group_id)) || '',
enrolled_plan_provider: (_sqPlan && _sqPlan.inventory_provider) || '',
block_enabled: !!(_sqTrack.cachedSettings && _sqTrack.cachedSettings.block_accelerated_checkout),
gate_armed: !!_sqTrack.a
);
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 set
TOQ - no cart selling plan updates needed');
}
})
.catch(error => {
console.error('STOQ - error updating cart selling plans:', error);
});
}
});
}
// ---- Live settings via the Storefront API (additive, does not gate init) ----
// The inlined `cachedSettings` comes from the app-embed Liquid render, which
// Shopify edge-caches and can serve stale. Reading the same `settings` metafield
// back over the Storefront API is a POST to /api/
Quick Buy#relatedProducts--template--26482384994687__related {
--PT: 60px;
--PB: 60px;
}
#relatedProducts--template--26482384994687__related .tabs__nav { --text-size: calc(var(--adjust-heading) * 1.35); }
@media screen and (max-width: 767px) {
#relatedProducts--template--26482384994687__related .grid--mobile,
#relatedProducts--template--26482384994687__related .carousel--mobile {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
}
version>/graphql.json — never
// CDN-cached — so it returns the live value on every page load. We fetch it
// best-effort and stash it on `window._RestockRocketConfig.storefrontSettings`
// so individual behaviours can migrate onto the fresh value over time. This is
// PURELY ADDITIVE: it does NOT change the resolution flow below, never blocks
// init, and silently no-ops on any failure / missing token.
(function loadStorefrontSettings() {
const cfg = window._RestockRocketConfig;
if (!cfg.storefrontAccessToken || cfg.disableStorefrontApi === true) return;
// Deferred to browser idle so this best-effort read runs strictly AFTER the
// critical init flow and never competes with it for a connection — the call
// is a live, uncached Storefront round-trip and can be slow (multi-second
// TTFB observed). Nothing on the critical path waits for it.
function run() {
const query = 'query StoqSettings($namespace: String!) { shop { metafield(namespace: $namespace, key:
refrontSettings = JSON.parse(value);
console.debug('STOQ - stored live settings from Storefront API on config.storefrontSettings');
})
.catch(function(e) {
console.debug('STOQ - Storefront settings fetch failed (non-fatal):', e && e.message);
});
}
if (typeof window.requestIdleCallback === 'function') {
window.requestIdleCallback(run, { timeout: 5000 });
} else {
setTimeout(run, 0);
}
})();
// 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': 'ski
TOQ - 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._RestockRocketConfig.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) {
// Apply failures are programming bugs (e.g. response shape changed
// server-side and the assignment threw). Surface them as console.error
// so they're visible in browser logs, then re-throw to fall through
// to the same Liquid-cached fallback as a fetch failure.
console.error('STOQ - apply failed for ' +
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 || [];
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