ask-widget.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /**
  2. * Loads "davo-bot 2000" (the floating launcher) on davidwindham.com.
  3. *
  4. * Unlike the daw (WordPress) and daw_til (Docusaurus) consumers — which live on
  5. * davidawindham.com and load the widget SAME-ORIGIN through that site's Apache
  6. * /ask proxy — this single-page portfolio is on a DIFFERENT origin
  7. * (davidwindham.com). So it loads the bundle and calls the API CROSS-ORIGIN
  8. * against the absolute davidawindham.com/ask/ URLs. The widget bundle has open
  9. * CORS, so the button always loads; for it to *answer*, the ralph server's
  10. * ALLOWED_ORIGINS must include https://davidwindham.com (see ralph README).
  11. * Local dev (browserSync/localhost) points at the ralph dev server on :3001.
  12. *
  13. * We probe the widget URL first and only inject it when the response is really
  14. * JavaScript: when ralph is down, davidawindham.com falls through to WordPress
  15. * and returns HTML, and injecting that would throw "Unexpected token '<'". The
  16. * content-type probe makes this a silent no-op until the backend is actually
  17. * serving the widget. The widget sets window.__dawaskLoaded to guard against a
  18. * double instance.
  19. */
  20. ( function () {
  21. if ( typeof document === 'undefined' || typeof fetch === 'undefined' ) {
  22. return;
  23. }
  24. var local = /^(localhost|127\.0\.0\.1|0\.0\.0\.0)$/.test( window.location.hostname );
  25. var ORIGIN = local ? 'http://localhost:3001' : 'https://davidawindham.com';
  26. var WIDGET_URL = ORIGIN + '/ask/widget.js';
  27. var API_URL = local ? ORIGIN + '/api/ask' : ORIGIN + '/ask/api/ask';
  28. function inject() {
  29. if ( document.getElementById( 'dawask-script' ) ) {
  30. return; // already injected
  31. }
  32. var s = document.createElement( 'script' );
  33. s.id = 'dawask-script';
  34. s.src = WIDGET_URL;
  35. s.setAttribute( 'data-api-url', API_URL );
  36. s.setAttribute( 'data-mode', 'launcher' );
  37. document.body.appendChild( s );
  38. }
  39. fetch( WIDGET_URL, { method: 'GET', cache: 'no-store' } )
  40. .then( function ( r ) {
  41. var ct = ( r.headers.get( 'content-type' ) || '' ).toLowerCase();
  42. if ( r.ok && ct.indexOf( 'javascript' ) !== -1 ) {
  43. inject();
  44. }
  45. } )
  46. .catch( function () {} ); // backend unreachable → no widget, no error
  47. } )();