Vacation rentals in Southwest Florida

Handpicked villas, direct booking, and local hosts who know every hidden gem—tell us your wish list and we’ll match the perfect stay.

(function () { var settings = window.FFCVLinkRewrite || {}; var apiUrl = settings.apiUrl || ''; if (!apiUrl) return; var mapCache = null; var fetchPromise = null; var scheduled = false; function normalize(val) { return String(val || '').toLowerCase().replace(/[^a-z0-9]/g, ''); } function extractId(href) { if (!href) return ''; try { var url = new URL(href, window.location.origin); var queryId = url.searchParams.get('propertyId') || url.searchParams.get('PropertyID'); if (queryId) return queryId; var unitId = url.searchParams.get('unitId'); if (unitId) return unitId; } catch (e) { // Relative/invalid URL, fall back to regex } var match = href.match(/(orp[0-9a-z]+)/i); if (match && match[1]) return match[1]; var orpCode = href.match(/(ORP[0-9]+)/i); if (orpCode && orpCode[1]) return orpCode[1]; return ''; } function buildMap(data) { var map = Object.create(null); if (!data || !Array.isArray(data.items)) return map; data.items.forEach(function (item) { var url = typeof item.url === 'string' ? item.url.trim() : ''; if (!url) return; var codes = []; if (Array.isArray(item.codes)) codes = item.codes.slice(); if (item.id !== undefined && item.id !== null) codes.push(item.id); if (typeof item.slug === 'string') codes.push(item.slug); codes.forEach(function (code) { var norm = normalize(code); if (norm && !map[norm]) { map[norm] = url; } }); }); return map; } function fetchMap() { if (mapCache) return Promise.resolve(mapCache); if (fetchPromise) return fetchPromise; fetchPromise = fetch(apiUrl, { credentials: 'same-origin', cache: 'no-store' }) .then(function (resp) { if (!resp.ok) throw new Error('HTTP ' + resp.status); return resp.json(); }) .then(function (json) { mapCache = buildMap(json); return mapCache; }) .catch(function () { mapCache = {}; return mapCache; }) .finally(function () { fetchPromise = null; }); return fetchPromise; } function rewriteLinks() { fetchMap().then(function (map) { var anchors = document.querySelectorAll( '.ownerrez-widget a[href], a[href*="rentals."][href], a[href*="ownerrez."][href]' ); anchors.forEach(function (anchor) { if (anchor.dataset.ffcvLinkRewritten === '1') return; var id = extractId(anchor.href); var norm = normalize(id); if (norm && map[norm]) { anchor.href = map[norm]; anchor.dataset.ffcvLinkRewritten = '1'; } }); }); } function scheduleRewrite() { if (scheduled) return; scheduled = true; window.setTimeout(function () { scheduled = false; rewriteLinks(); }, 120); } document.addEventListener('DOMContentLoaded', scheduleRewrite); window.addEventListener('load', scheduleRewrite); if ('MutationObserver' in window) { var observer = new MutationObserver(scheduleRewrite); observer.observe(document.documentElement, { childList: true, subtree: true }); // Keep watching longer so pagination/filters also get rewritten. window.setTimeout(function () { observer.disconnect(); }, 60000); } // Initial pass in case the widget has already rendered. scheduleRewrite(); })();