/** * Loads "davo-bot 2000" (the floating launcher) on davidwindham.com. * * Unlike the daw (WordPress) and daw_til (Docusaurus) consumers — which live on * davidawindham.com and load the widget SAME-ORIGIN through that site's Apache * /ask proxy — this single-page portfolio is on a DIFFERENT origin * (davidwindham.com). So it loads the bundle and calls the API CROSS-ORIGIN * against the absolute davidawindham.com/ask/ URLs. The widget bundle has open * CORS, so the button always loads; for it to *answer*, the ralph server's * ALLOWED_ORIGINS must include https://davidwindham.com (see ralph README). * Local dev (browserSync/localhost) points at the ralph dev server on :3001. * * We probe the widget URL first and only inject it when the response is really * JavaScript: when ralph is down, davidawindham.com falls through to WordPress * and returns HTML, and injecting that would throw "Unexpected token '<'". The * content-type probe makes this a silent no-op until the backend is actually * serving the widget. The widget sets window.__dawaskLoaded to guard against a * double instance. */ ( function () { if ( typeof document === 'undefined' || typeof fetch === 'undefined' ) { return; } var local = /^(localhost|127\.0\.0\.1|0\.0\.0\.0)$/.test( window.location.hostname ); var ORIGIN = local ? 'http://localhost:3001' : 'https://davidawindham.com'; var WIDGET_URL = ORIGIN + '/ask/widget.js'; var API_URL = local ? ORIGIN + '/api/ask' : ORIGIN + '/ask/api/ask'; function inject() { if ( document.getElementById( 'dawask-script' ) ) { return; // already injected } var s = document.createElement( 'script' ); s.id = 'dawask-script'; s.src = WIDGET_URL; s.setAttribute( 'data-api-url', API_URL ); s.setAttribute( 'data-mode', 'launcher' ); document.body.appendChild( s ); } fetch( WIDGET_URL, { method: 'GET', cache: 'no-store' } ) .then( function ( r ) { var ct = ( r.headers.get( 'content-type' ) || '' ).toLowerCase(); if ( r.ok && ct.indexOf( 'javascript' ) !== -1 ) { inject(); } } ) .catch( function () {} ); // backend unreachable → no widget, no error } )();