News
We Go Season 2 Episode 2: The Path to The Eddie
Shop The Story
{"id":8014847639687,
"handle":"southshore-womens-waterproof-leather-sandals-toasted-coconut",
"title":"Southshore - Toasted Coconut",
"available":true,
"tags":["arch:standard","beach sandals","Beach\/Boat","best:beach_boat","best:everday_wear","cat:sandals","color:Tan","Everyday Wear","fit:standard","flip flops","gender:women","landleather","leather","leather:material","material:leather","olukai beach sandals","RGroup_20532","sandals","size:true","south shore","Southshore","split_color","style:20532","water poof","water-friendly","waterproof","waterproof leather","women","womens","Womenssandals","womenβs"],
"type":"Womenβs Waterproof Leather Sandals",
"options_with_values": [{"name":"Color","position":1,"values":["Toasted Coconut"]},{"name":"Size","position":2,"values":["5","6","7","8","9","10","11"]}],
"price":13000,
"price_min":13000,
"price_max":13000,
"compare_at_price":null,"featured_image": "\/\/olukai.ca\/cdn\/shop\/files\/20532_TCTC_001_W_SOUTHSHORE_ToastdCoconutTostdCoconut.png?v=1736189137",
"featured_image_aspect_ratio": 1.0,
"featured_image_width": 2000,
"featured_image_height": 2000,
"featured_image_id": 33354939695239,
"featured_image_alt": "Toasted Coconut",
"hover_image": "\/\/olukai.ca\/cdn\/shop\/files\/Southshore_Toffee_1.png?v=1742497961",
"hover_image_alt": "Toasted Coconut",
"images": [{
"id": 33354939695239,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20532_TCTC_001_W_SOUTHSHORE_ToastdCoconutTostdCoconut.png?v=1736189137",
"alt": "Toasted Coconut",
"width": 2000,
"height": 2000
},{
"id": 34004211368071,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/Southshore_Toffee_1.png?v=1742497961",
"alt": "Toasted Coconut",
"width": 1000,
"height": 1000
},{
"id": 33354939760775,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20532_TCTC_AMZ_W_SOUTHSHORE_ToastdCoconutTostdCoconut.png?v=1742497961",
"alt": "Toasted Coconut",
"width": 2000,
"height": 2000
},{
"id": 33354939793543,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20532_TCTC_004_W_SOUTHSHORE_ToastdCoconutTostdCoconut.png?v=1742497961",
"alt": "Toasted Coconut",
"width": 2000,
"height": 2000
},{
"id": 33354939826311,
"src": "\/\/olukai.ca\/cdn\/shop\/files\/20532_TCTC_005_W_SOUTHSHORE_ToastdCoconutTostdCoconut.png?v=1742497961",
"alt": "Toasted Coconut",
"width": 2000,
"height": 2000
}],
"plp_image_order_positions": "",
"sku": "20532-TCTC-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":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()"
>
{ $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()"
>