From 08ef2b5d95fea628756bfb15f012a027940a2620 Mon Sep 17 00:00:00 2001 From: Vahid Ahmadi Date: Tue, 26 May 2026 11:58:45 +0200 Subject: [PATCH 1/2] Proxy /uk/data.json so student-loan-visualisation figures render MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The source HTML at student-loan-visualisation.vercel.app does fetch('./data.json'). Under the multizone rewrite at /uk/student-loan-visualisation (no trailing slash), the relative URL resolves to /uk/data.json, which 404s — so the D3 figures and the decile table never get data. Adding the trailing slash isn't viable because Next.js's default trailingSlash:false auto-strips it. This adds an afterFiles rewrite proxying /uk/data.json to the source. A more durable fix is to give the source repo an absolute path or a basePath, at which point this hot-patch can be removed. Co-Authored-By: Claude Opus 4.7 (1M context) --- website/next.config.ts | 111 ++++++++++++++++++++++++++++++++++------- 1 file changed, 93 insertions(+), 18 deletions(-) diff --git a/website/next.config.ts b/website/next.config.ts index 642a57196..116cddf5d 100644 --- a/website/next.config.ts +++ b/website/next.config.ts @@ -88,37 +88,112 @@ const nextConfig: NextConfig = { beforeFiles: [ ...appZoneRewrites, // Household API docs (Vercel) — beforeFiles so it intercepts before Next.js trailing slash redirect - { source: "/us/api", destination: "https://household-api-docs-policy-engine.vercel.app/us/api/" }, - { source: "/us/api/:path*", destination: "https://household-api-docs-policy-engine.vercel.app/us/api/:path*" }, + { + source: "/us/api", + destination: + "https://household-api-docs-policy-engine.vercel.app/us/api/", + }, + { + source: "/us/api/:path*", + destination: + "https://household-api-docs-policy-engine.vercel.app/us/api/:path*", + }, // Python client docs — same household-api-docs deployment, served at top-level /us/python - { source: "/us/python", destination: "https://household-api-docs-policy-engine.vercel.app/us/python" }, - { source: "/us/python/:path*", destination: "https://household-api-docs-policy-engine.vercel.app/us/python/:path*" }, + { + source: "/us/python", + destination: + "https://household-api-docs-policy-engine.vercel.app/us/python", + }, + { + source: "/us/python/:path*", + destination: + "https://household-api-docs-policy-engine.vercel.app/us/python/:path*", + }, // Zone asset proxy — API docs uses assetPrefix: '/_zones/household-api-docs' - { source: "/_zones/household-api-docs/:path*", destination: "https://household-api-docs-policy-engine.vercel.app/_zones/household-api-docs/:path*" }, + { + source: "/_zones/household-api-docs/:path*", + destination: + "https://household-api-docs-policy-engine.vercel.app/_zones/household-api-docs/:path*", + }, ], // afterFiles: checked after pages/public files but before dynamic routes. afterFiles: [ + // Student loan visualisation: the source HTML at student-loan-visualisation.vercel.app + // does `fetch('./data.json')`. Under the multizone rewrite at /uk/student-loan-visualisation + // (no trailing slash), the relative URL resolves to /uk/data.json. Proxy it so the + // figures and table render. Remove once the source repo uses an absolute path or basePath. + { + source: "/uk/data.json", + destination: + "https://student-loan-visualisation.vercel.app/data.json", + }, // PostHog analytics proxy — first-party path bypasses ad blockers that // filter *.i.posthog.com. Static rule must come first. - { source: "/ingest/static/:path*", destination: "https://us-assets.i.posthog.com/static/:path*" }, - { source: "/ingest/:path*", destination: "https://us.i.posthog.com/:path*" }, + { + source: "/ingest/static/:path*", + destination: "https://us-assets.i.posthog.com/static/:path*", + }, + { + source: "/ingest/:path*", + destination: "https://us.i.posthog.com/:path*", + }, // State legislative tracker (Modal) - { source: "/_tracker/:path*", destination: "https://policyengine--state-legislative-tracker.modal.run/_tracker/:path*" }, + { + source: "/_tracker/:path*", + destination: + "https://policyengine--state-legislative-tracker.modal.run/_tracker/:path*", + }, // Tracker assets at root paths — temporary until tracker repo updates to use absolute URLs - { source: "/policyengine-favicon.svg", destination: "https://policyengine--state-legislative-tracker.modal.run/policyengine-favicon.svg" }, - { source: "/policyengine-logo.svg", destination: "https://policyengine--state-legislative-tracker.modal.run/policyengine-logo.svg" }, + { + source: "/policyengine-favicon.svg", + destination: + "https://policyengine--state-legislative-tracker.modal.run/policyengine-favicon.svg", + }, + { + source: "/policyengine-logo.svg", + destination: + "https://policyengine--state-legislative-tracker.modal.run/policyengine-logo.svg", + }, // Slides (Vercel) - { source: "/slides", destination: "https://policyengine-slides.vercel.app/slides" }, - { source: "/slides/:path*", destination: "https://policyengine-slides.vercel.app/slides/:path*" }, + { + source: "/slides", + destination: "https://policyengine-slides.vercel.app/slides", + }, + { + source: "/slides/:path*", + destination: "https://policyengine-slides.vercel.app/slides/:path*", + }, // Plugin blog (GitHub Pages) - { source: "/plugin-blog", destination: "https://policyengine.github.io/plugin-blog/" }, - { source: "/plugin-blog/:path*", destination: "https://policyengine.github.io/plugin-blog/:path*" }, + { + source: "/plugin-blog", + destination: "https://policyengine.github.io/plugin-blog/", + }, + { + source: "/plugin-blog/:path*", + destination: "https://policyengine.github.io/plugin-blog/:path*", + }, // TAXSIM (Vercel) - { source: "/us/taxsim", destination: "https://policyengine-taxsim-policy-engine.vercel.app/us/taxsim" }, - { source: "/us/taxsim/:path*", destination: "https://policyengine-taxsim-policy-engine.vercel.app/us/taxsim/:path*" }, + { + source: "/us/taxsim", + destination: + "https://policyengine-taxsim-policy-engine.vercel.app/us/taxsim", + }, + { + source: "/us/taxsim/:path*", + destination: + "https://policyengine-taxsim-policy-engine.vercel.app/us/taxsim/:path*", + }, // Model documentation (Vercel) - { source: "/:countryId/model", destination: "https://policyengine-model-phi.vercel.app/?country=:countryId" }, - { source: "/:countryId/model/:path*", destination: "https://policyengine-model-phi.vercel.app/:path*?country=:countryId" }, + { + source: "/:countryId/model", + destination: + "https://policyengine-model-phi.vercel.app/?country=:countryId", + }, + { + source: "/:countryId/model/:path*", + destination: + "https://policyengine-model-phi.vercel.app/:path*?country=:countryId", + }, ], }; }, From 9a358a37f8b6e4ec7875198c785ffc2ba631d2cb Mon Sep 17 00:00:00 2001 From: Vahid Ahmadi Date: Tue, 26 May 2026 12:06:13 +0200 Subject: [PATCH 2/2] Skip .json destinations in multizone-tracking audit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JSON data proxies (like /uk/data.json → student-loan-visualisation/data.json) have no HTML layout to install gtag into, so the audit's gtag check doesn't apply. Same rationale as the existing .svg/.css/.js skip list. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/scripts/audit-multizone-tracking.mjs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/audit-multizone-tracking.mjs b/.github/scripts/audit-multizone-tracking.mjs index 439fff687..00d0e7c0a 100644 --- a/.github/scripts/audit-multizone-tracking.mjs +++ b/.github/scripts/audit-multizone-tracking.mjs @@ -39,10 +39,10 @@ const SKIP_IF_CONTAINS = [ "policyengine-slides.vercel.app", // Internal slides, not in ads ]; -// File extensions that indicate a static-asset proxy rather than a -// page. Static SVGs / images / fonts don't have a root layout to -// install gtag into. -const STATIC_ASSET_EXTS = [".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico", ".woff", ".woff2", ".ttf", ".css", ".js"]; +// File extensions that indicate a static-asset / data proxy rather +// than a page. Static SVGs / images / fonts / data files don't have a +// root layout to install gtag into. +const STATIC_ASSET_EXTS = [".svg", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".ico", ".woff", ".woff2", ".ttf", ".css", ".js", ".json"]; // Pages that serve reference / documentation content where firing // tool_engaged would inflate conversion counts. Allowed to have gtag