News
Together. We Go.
Footwear For The Island Lifestyle
We just launched three new commercials celebrating the inspiration behind OluKai footwear and the adventurous spirit of life in Hawai‘i. Our team followed a big wave surfer, a renowned spearfish diver, a traditional tattoo artist, and a brave lifeguard to give you a glimpse into life in the Islands. Keep an eye out for these spots on your devices and for larger character features in the future. This is footwear for the island lifestyle.
Shop The Story
{"id":6696749367431,
"handle":"ulele-mens-beach-sandals-slate-blue-charcoal",
"title":"Ulele - Slate Blue \/ Charcoal",
"available":true,
"tags":["01","arch:high","beach sandals","Beach\/Boat","best:beach_boat","best:everday_wear","best:travel","blue-depth","cat:sandals","collection:chief-home-officer","collection:tide-tracker","collection:wfh","color:blue","color:Slate Blue \/ Charcoal","Division-01","enhanced traction footbed","enhanced traction outsole","Everyday Wear","EXP_REC_MEN","fit:wide","gender:men","labor day","Ltd.","M","material:synthetic","men s flipslops","Mens sansandals","October Trading Co.","RGroup_10435","Sand","sandals","size:true","split_color","style:10435","synthetic","Travel","uelele","ulee flip","Ulele-","uleue","ulule","vegan","water-friendly","wide width","widewidh","YGroup_10435"],
"type":"Men’s Water-Ready Beach Sandals",
"options_with_values": [{"name":"Color","position":1,"values":["Slate Blue \/ Charcoal"]},{"name":"Size","position":2,"values":["7","8","9","10","11","12","13","14","15"]}],
"price":11000,
"price_min":11000,
"price_max":11000,
"compare_at_price":null,"featured_image": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_001_M_Ulele_SltbChr.png?v=1762445187",
"featured_image_aspect_ratio": 1.0,
"featured_image_width": 2000,
"featured_image_height": 2000,
"featured_image_id": 34414949761159,
"featured_image_alt": "Slate Blue \/ Charcoal",
"hover_image": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_101_554d31ff-0c73-4b9b-b935-f944ab9a8475.jpg?v=1744996241",
"hover_image_alt": "Slate Blue \/ Charcoal",
"images": [{
"id": 34414949761159,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_001_M_Ulele_SltbChr.png?v=1762445187",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
},{
"id": 34414949793927,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_101_554d31ff-0c73-4b9b-b935-f944ab9a8475.jpg?v=1744996241",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
},{
"id": 34414949826695,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_102_M_Ulele_SltbChar_Web_Opt_1024x1024_f1946ce0-afb1-467b-a579-26983500873b.jpg?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 1024,
"height": 1024
},{
"id": 34414949859463,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_004_M_Ulele_SltbChr.png?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
},{
"id": 34414949892231,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_104_27e591d9-44c7-4b81-ba58-4a2882b2efc9.jpg?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2001
},{
"id": 34414949924999,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_105_1724a753-f48c-4bd4-9f59-0333f977ad61.jpg?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
},{
"id": 34414949957767,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_104_c9cc79e1-98d0-4368-904a-4436e87bf914.jpg?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
},{
"id": 34414949990535,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_101_1024x1024_c319504f-69f6-4836-baef-b1e63f4d184f.jpg?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 1024,
"height": 1024
},{
"id": 34414950023303,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10435_7S26_005_M_Ulele_SltbChr.png?v=1744996242",
"alt": "Slate Blue \/ Charcoal",
"width": 2000,
"height": 2000
}],
"plp_image_order_positions": "",
"sku": "10435-7S26-7"
}
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>
{"id":5156404789383,
"handle":"ohana-womens-beach-sandals-black",
"title":"‘Ohana - Black",
"available":true,
"tags":["'ohanna","2024-gift-guide","arch:high","beach sandals","Beach\/Boat","beachbum","best sellers","best selling","best:beach_boat","best:everday_wear","black fliflps","cat:sandals","collection:chief-home-officer","collection:HGG-Slider-W","collection:tide-tracker","color:Black","enhanced traction outsole","Everyday Wear","EXP_REC_WOMEN","extra-colors","fit:wide","flip flops","gender:women","labor day","likes:beach","material:synthetic","mothers-day","nature-inspired","o hana","o hanas","obama","oha","Ohana","ohana w","ohanaflip flops","ohanaohana women","ohsna","omaha","prime","RGroup_20110","size:true","SP-19-COLOR","SP19-Style","split_color","style:20110","synthetic","vacation:tropical","vegan","vegan friendly","water-friendly","wide sizes","wide width","widewidh","women","womens","womensflip flop","women’s","YGroup_20110","‘ohani"],
"type":"Women’s Water-Friendly Sandals",
"options_with_values": [{"name":"Color","position":1,"values":["Black"]},{"name":"Size","position":2,"values":["5","6","7","8","9","10","11","12"]}],
"price":10000,
"price_min":10000,
"price_max":10000,
"compare_at_price":null,"featured_image": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_001_W_Ohana_BlkBlk_41e6f1b8-ca5c-4d05-94b5-8f99b86192d1.png?v=1762441470",
"featured_image_aspect_ratio": 1.0,
"featured_image_width": 2000,
"featured_image_height": 2000,
"featured_image_id": 34400636043399,
"featured_image_alt": "Black",
"hover_image": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_102_W_OHANA_BlackBlack_29477e0f-6d55-47ce-a8a2-5d3cc7b3e441.jpg?v=1746734998",
"hover_image_alt": "Black",
"images": [{
"id": 34400636043399,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_001_W_Ohana_BlkBlk_41e6f1b8-ca5c-4d05-94b5-8f99b86192d1.png?v=1762441470",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636076167,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_102_W_OHANA_BlackBlack_29477e0f-6d55-47ce-a8a2-5d3cc7b3e441.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636108935,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_201_3d4a23f2-2dc2-4377-b783-2facd28f27cc.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636141703,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_105_W_OHANA_BlackBlack_9583fbfc-e266-4f84-8cb7-6bea1e1d83ea.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636174471,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_103_W_OHANA_BlackBlack_544bdd54-9555-4ff7-8502-0d553b48c511.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636207239,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_202_c9aea4c7-0925-4de5-8e8c-6ddc4cb76f70.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636240007,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_004_W_Ohana_BlkBlk.png?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636272775,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_203_3b915de6-8cff-43d6-b402-12306bad97cf.jpg?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
},{
"id": 34400636305543,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20110_4040_005_W_Ohana_BlkBlk.png?v=1746734998",
"alt": "Black",
"width": 2000,
"height": 2000
}],
"plp_image_order_positions": "",
"sku": "20110-4040-5"
}
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>
{"id":5156381229191,
"handle":"laeahi-mens-sneakers-pavement",
"title":"Lae‘ahi - Pavement",
"available":true,
"tags":["2024-gift-guide","arch:standard","Beach\/Boat","best selling","best:beach_boat","best:everday_wear","best:travel","blue-depth","bundle|4|4|0|2","cat:shoes","collection:chief-home-officer","collection:tide-tracker","collection:wfh","color:grey","color:Pavement","drop-in heel®","enhance gip","enhanced traction outsole","Everyday Wear","EXP_REC_MEN","Father’s Day Gifts","fit:standard","foldable heal","gender:men","gifts","kahu","laahi","laceless","lae ahi pavement","Lae'ahi","Lae'ahii","laeaahi","laeahi slip on","laeahu","laeai","laehi","Lae‘","Lae‘ahi","lae‘ahi collection","lahi","lai ahi","land","le ahi","Lea","Leahahi","leahhi","lehai","material:textile","mens","mesh","RGroup_10443","shoes","size:large","size:true","slioons","slip on shoes","Slip os","slipons","split_color","style:10443","textile","Travel","vegan","YGroup_10443"],
"type":"Men’s Breathable Slip-On Shoes",
"options_with_values": [{"name":"Color","position":1,"values":["Pavement"]},{"name":"Size","position":2,"values":["7","8","8.5","9","9.5","10","10.5","11","11.5","12","13","14","15"]}],
"price":13000,
"price_min":13000,
"price_max":13000,
"compare_at_price":null,"featured_image": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_001_M_Laeahi_PvmtPvmt_9678f637-af2c-427a-8984-381df4226f46.png?v=1762441178",
"featured_image_aspect_ratio": 1.0,
"featured_image_width": 2000,
"featured_image_height": 2000,
"featured_image_id": 34414952284295,
"featured_image_alt": "Pavement",
"hover_image": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_101_c297f4d7-3556-43ab-92d4-5335a2b4afa3.jpg?v=1746706343",
"hover_image_alt": "Pavement",
"images": [{
"id": 34414952284295,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_001_M_Laeahi_PvmtPvmt_9678f637-af2c-427a-8984-381df4226f46.png?v=1762441178",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952317063,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_101_c297f4d7-3556-43ab-92d4-5335a2b4afa3.jpg?v=1746706343",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952382599,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_201_49112430-12cc-4067-83d2-40327fb9c3c4.jpg?v=1746706343",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952448135,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_102_f40fb600-dfc6-42d3-8a12-af5a1c8d8611.jpg?v=1746706343",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952546439,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_004_M_Laeahi_PvmtPvmt.png?v=1746706343",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952644743,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_106_M_Lae_ahi_PavementPavement_09319ae5-a018-482e-8fd2-2428da88824e.jpg?v=1746706343",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952743047,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_103_M_Lae_ahi_PavementPavement_15b261e6-5dcb-4229-908b-193ef90479d9.jpg?v=1746706344",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952841351,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_103_9ac35622-4f5a-4239-810c-e195edec5d9d.jpg?v=1746706344",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414952939655,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_203_84ac8e05-df9d-4abb-9fbf-3d2ed9f41521.jpg?v=1746706344",
"alt": "Pavement",
"width": 2000,
"height": 2000
},{
"id": 34414953037959,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/10443_PVPV_005_M_Laeahi_PvmtPvmt.png?v=1746706344",
"alt": "Pavement",
"width": 2000,
"height": 2000
}],
"plp_image_order_positions": "",
"sku": "10443-PVPV-7"
}
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>
{"id":5156396204167,
"handle":"pehuea-li-womens-sneakers-tapa",
"title":"Pehuea Lī - Tapa",
"available":true,
"tags":["arch:standard","Beach\/Boat","best sellers","best selling","best:beach_boat","best:everday_wear","best:travel","breathable","cat:shoes","collection:back-to-school","collection:HGG-Slider-W","collection:tide-tracker","color:tan","color:Tapa","drop-in heel®","Everyday Wear","EXP_REC_WOMEN","fit:narrow","fit:standard","gender:women","homebody","interest:driving","labor day","landtextile","likes:friends","likes:relaxing","likes:urban-exploring","material:textile","mesh","mothers-day","peheaua","pehuea","pehuea collection","pehuea li","pehuea lii","prahulra li","removable footbed","RGroup_20379","size:true","sneakers","SP19-Style","split_color","style:20379","tempstandard","textile","Travel","trendsetter","vacation:city-downtown","vacation:road-trip","women","womens","women’s","YGroup_20379"],
"type":"Women’s Lightweight Sneakers",
"options_with_values": [{"name":"Color","position":1,"values":["Tapa"]},{"name":"Size","position":2,"values":["5","6","6.5","7","7.5","8","8.5","9","9.5","10","11","12"]}],
"price":14000,
"price_min":14000,
"price_max":14000,
"compare_at_price":null,"featured_image": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_001_W_PehueaLi_TapTap_374da846-7db5-4dfb-8a0f-e2406d519368.png?v=1762441369",
"featured_image_aspect_ratio": 1.0,
"featured_image_width": 2000,
"featured_image_height": 2000,
"featured_image_id": 34256067133575,
"featured_image_alt": "Tapa",
"hover_image": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_101_d6e285d6-ec79-49e3-af24-268ffe81855e.jpg?v=1743725043",
"hover_image_alt": "Tapa",
"images": [{
"id": 34256067133575,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_001_W_PehueaLi_TapTap_374da846-7db5-4dfb-8a0f-e2406d519368.png?v=1762441369",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067166343,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_101_d6e285d6-ec79-49e3-af24-268ffe81855e.jpg?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2001
},{
"id": 34256067199111,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_201_45b9670d-5e96-4d40-8791-1af49aacc60f.jpg?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067231879,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_002_W_PehueaLi_TapTap.png?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067264647,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_102_41bd2033-217a-4a50-8976-6b5e3279fb4a.jpg?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067297415,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/Pehuea_Li-Tapa-galleryimage-04_b0074138-acae-480c-919d-ffb86b522e97.jpg?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067330183,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/pehuea-li--tapa_b8319fbb-5ad3-4d9a-b25b-eb88829838e1.jpg?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067362951,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_004_W_PehueaLi_TapTap.png?v=1743725043",
"alt": "Tapa",
"width": 2000,
"height": 2000
},{
"id": 34256067395719,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20379_2020_005_W_PehueaLi_TapTap.png?v=1743725044",
"alt": "Tapa",
"width": 2000,
"height": 2000
}],
"plp_image_order_positions": "",
"sku": "20379-2020-5"
}
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>
Explore Similar Stories
{ $dispatch('product-item:images-changed', { product: product, source: 'swatch-container' }) })"
@pointercancel="intendedSwatchIndex = null; intendedSwatchEl = null"
x-data="{
wrapper: $el,
selectedSibling:product.siblings[0],
intendedSwatchIndex: null,
intendedSwatchEl: null,
swatchGap: 8,
scrollable: product.siblings.filter(s => !!s.available).length > 9.5,
canPrev: false,
canNext: true,
_edgeReady: false,
imageLimit: 0,
limitImages(nextProduct) {
const images = Array.isArray(nextProduct && nextProduct.images) ? nextProduct.images : [];
const limitedImages = this.imageLimit > 0 ? images.slice(0, this.imageLimit) : images;
const hoverImage = limitedImages[1] || null;
return Object.assign({}, nextProduct, {
images: limitedImages,
hover_image: hoverImage ? hoverImage.src : null,
hover_image_alt: hoverImage ? hoverImage.alt : null
});
},
selectProduct(nextProduct) {
const productRoot = $el.closest('.product-item');
const productData = productRoot && productRoot._x_dataStack && productRoot._x_dataStack[0];
if (productData && typeof productData.setProduct === 'function') {
productData.setProduct(nextProduct);
} else {
$data.product = this.limitImages(nextProduct);
}
},
getSwatchImageSrc(sibling) {
return sibling.images[0].src;
},
buildSwatchSrcset(src) {
if (!src) return '';
const widths = ['48', '96', '192'];
const separator = src.includes('?') ? '&' : '?';
return widths.map(w => `${src}${separator}width=${w} ${w}w`).join(', ');
},
isSwatchPriority(index) {
return window.innerWidth >= 1024 ? index < 3 : index < 2;
},
swatchBg(sibling) {
// swatch_bg precomputed at hydration. Nullish (not ||): null = no colors set
// (fall back to theme default), empty string = invalid combo, no fallback.
return sibling.swatch_bg ?? '#000000';
},
centerSwatch(el) {
if ($data.wrapper.scrollWidth <= $data.wrapper.clientWidth) return false
const wrapperRect = $data.wrapper.getBoundingClientRect()
const elRect = el.getBoundingClientRect()
const centerPoint = wrapperRect.x + (wrapperRect.width / 2)
const behavior = window.innerWidth < 1024 ? 'auto' : 'smooth'
$data.wrapper.scrollTo({
left: $data.wrapper.scrollLeft + (elRect.x - centerPoint + (elRect.width / 2)),
behavior
})
},
selectSwatchFromTap(siblingIndex, el) {
const idx = (this.intendedSwatchIndex !== null && this.intendedSwatchIndex !== undefined)
? this.intendedSwatchIndex
: siblingIndex
const targetEl = this.intendedSwatchEl || el
this.intendedSwatchIndex = null
this.intendedSwatchEl = null
const next = product.siblings[idx]
if (next) product = next
this.centerSwatch(targetEl)
},
scroll(direction = 'forward') {
const swatch = $data.wrapper.querySelector('.product-item__swatch')
const unit = swatch ? swatch.offsetWidth + $data.swatchGap : $data.wrapper.clientWidth * 0.3
let amount = 2 * unit
$data.wrapper.scrollTo({
left: direction == 'forward' ? $data.wrapper.scrollLeft + amount : $data.wrapper.scrollLeft - amount,
behavior:'smooth'
})
},
// Lazily wire the prev/next edge detection on first desktop hover/focus —
// the arrows are a desktop affordance, so no observer is built at load and
// none is ever built on mobile. canPrev/canNext default to the at-start state.
initSwatchEdges() {
if (this._edgeReady || window.innerWidth <= 1023) return
this._edgeReady = true
const root = this.wrapper
const swatches = root.querySelectorAll('.product-item__swatch')
if (swatches.length < 2) return
const first = swatches[0], last = swatches[swatches.length - 1]
const io = new IntersectionObserver((entries) => {
const d = window.Alpine && window.Alpine.$data ? window.Alpine.$data(root) : null
if (!d) return
entries.forEach((e) => {
if (e.target === first) d.canPrev = !e.isIntersecting
if (e.target === last) d.canNext = !e.isIntersecting
})
}, { root, threshold: 0.99 })
io.observe(first)
io.observe(last)
root._swatchEdgeIO = io
}
}"
@pointerenter="initSwatchEdges()"
@focusin="initSwatchEdges()"
>