feat: render WRNexus bot widget globally via shared layout
Deploy to Production / Build & Verify (push) Failing after 16m44s
E2E Test Suite / Security Header Tests (push) Failing after 10m27s
E2E Test Suite / Mobile Device Tests (push) Failing after 10m28s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 11m21s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 12m13s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 13m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 13m58s
E2E Test Suite / Form Interaction Tests (push) Failing after 14m51s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 21m43s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Pre-Deploy Tests (push) Failing after 14m59s
E2E Test Suite / Test Report Summary (push) Failing after 14m58s
Deploy to Production / Deploy to Fly.io (push) Failing after 13m21s
Deploy to Production / Deploy to VPS (PM2) (push) Failing after 13m48s
Deploy to Production / Deploy to Render (push) Failing after 14m14s
Deploy to Production / Deploy to Railway (push) Failing after 14m40s
Deploy to Production / Post-Deploy Verification (push) Failing after 14m10s
Deploy to Production / Notify on Failure (push) Successful in 1s
Deploy to Production / Build & Verify (push) Failing after 16m44s
E2E Test Suite / Security Header Tests (push) Failing after 10m27s
E2E Test Suite / Mobile Device Tests (push) Failing after 10m28s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 11m21s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 12m13s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 13m6s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 13m58s
E2E Test Suite / Form Interaction Tests (push) Failing after 14m51s
E2E Test Suite / Smoke Tests (P0) (push) Failing after 21m43s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
Deploy to Production / Pre-Deploy Tests (push) Failing after 14m59s
E2E Test Suite / Test Report Summary (push) Failing after 14m58s
Deploy to Production / Deploy to Fly.io (push) Failing after 13m21s
Deploy to Production / Deploy to VPS (PM2) (push) Failing after 13m48s
Deploy to Production / Deploy to Render (push) Failing after 14m14s
Deploy to Production / Deploy to Railway (push) Failing after 14m40s
Deploy to Production / Post-Deploy Verification (push) Failing after 14m10s
Deploy to Production / Notify on Failure (push) Successful in 1s
Inject the WRNexus bot widget loader (bots/widget.js) once into BaseLayout.astro's <head> so the chat widget appears on every route (pages + blog posts) without per-page duplication. Uses is:inline so Astro does not bundle/transform the external script, preserving the data-bot-id and async attributes. Update CSP in middleware.ts to permit the widget: script-src and connect-src already allowed https://api.wrnexus.com (web-push SDK); added it to frame-src for the widget's iframe. No other directives weakened. Verified: build is clean, widget tag served on /, /about, /contact, and a blog post; widget.js loads 200; zero console CSP violations. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
189260bbb3
commit
fccc0115c4
@@ -186,6 +186,12 @@ const fullTitle = title === 'Home' ? homeTitle : `${title} | ${brand}`;
|
|||||||
from rewriting the external src and preserves data-site-id / defer. -->
|
from rewriting the external src and preserves data-site-id / defer. -->
|
||||||
<script is:inline src="https://api.wrnexus.com/push/sdk.js" data-site-id="pk_rP51XN8tZnud5HdX9UqidjHk" defer></script>
|
<script is:inline src="https://api.wrnexus.com/push/sdk.js" data-site-id="pk_rP51XN8tZnud5HdX9UqidjHk" defer></script>
|
||||||
|
|
||||||
|
<!-- WRNexus Bot Widget — loaded once globally here so the chat widget
|
||||||
|
renders on every route (pages + blog posts) via this shared layout.
|
||||||
|
is:inline keeps Astro's bundler from rewriting the external src and
|
||||||
|
preserves data-bot-id / async. -->
|
||||||
|
<script is:inline src="https://api.wrnexus.com/bots/widget.js" data-bot-id="d3998f1b-51d7-4f7c-a57e-3fa1af4394a0" async></script>
|
||||||
|
|
||||||
<!-- Additional head content slot -->
|
<!-- Additional head content slot -->
|
||||||
<slot name="head" />
|
<slot name="head" />
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
+3
-2
@@ -155,7 +155,8 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|||||||
// - inline scripts/styles: Required for Astro framework
|
// - inline scripts/styles: Required for Astro framework
|
||||||
// - https://www.googletagmanager.com & https://www.google-analytics.com: GA4
|
// - https://www.googletagmanager.com & https://www.google-analytics.com: GA4
|
||||||
// - https://plausible.io: Plausible Analytics
|
// - https://plausible.io: Plausible Analytics
|
||||||
// - https://api.wrnexus.com: WRNexus web-push SDK (sdk.js) + runtime config
|
// - https://api.wrnexus.com: WRNexus web-push SDK (sdk.js), bot widget
|
||||||
|
// (bots/widget.js) + runtime config/iframe served from the same origin
|
||||||
// Note: unsafe-eval is removed in production (only needed during Astro HMR dev mode)
|
// Note: unsafe-eval is removed in production (only needed during Astro HMR dev mode)
|
||||||
const isProduction = import.meta.env.PROD;
|
const isProduction = import.meta.env.PROD;
|
||||||
const scriptSrc = isProduction
|
const scriptSrc = isProduction
|
||||||
@@ -172,7 +173,7 @@ export const onRequest = defineMiddleware(async (context, next) => {
|
|||||||
"worker-src 'self'",
|
"worker-src 'self'",
|
||||||
"manifest-src 'self'",
|
"manifest-src 'self'",
|
||||||
"object-src 'none'", // Block Flash/plugins (defense-in-depth)
|
"object-src 'none'", // Block Flash/plugins (defense-in-depth)
|
||||||
"frame-src https://www.google.com", // Allow Google Maps iframe embed
|
"frame-src https://www.google.com https://api.wrnexus.com", // Google Maps iframe + WRNexus bot widget iframe
|
||||||
"frame-ancestors 'none'",
|
"frame-ancestors 'none'",
|
||||||
"base-uri 'self'",
|
"base-uri 'self'",
|
||||||
"form-action 'self'",
|
"form-action 'self'",
|
||||||
|
|||||||
Reference in New Issue
Block a user