Skip to content

Commit 2030b9f

Browse files
authored
Merge pull request #2702 from PolicyEngine/MaxGhenis/issue2701
Fix deep linking for OBBBA household-by-household iframe
2 parents ee5648a + 568fe65 commit 2030b9f

1 file changed

Lines changed: 67 additions & 11 deletions

File tree

src/pages/AppPage.jsx

Lines changed: 67 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,67 @@
1-
import { useParams } from "react-router-dom";
1+
import { useParams, useLocation, useNavigate } from "react-router-dom";
22
import Header from "../layout/Header";
33
import Footer from "../layout/Footer";
44
import { apps } from "../apps/appTransformers";
55
import { Helmet } from "react-helmet";
6+
import { useEffect, useRef, useState } from "react";
67

78
export default function AppPage() {
89
const { appName } = useParams();
10+
const location = useLocation();
11+
const navigate = useNavigate();
12+
const iframeRef = useRef(null);
913

1014
const app = apps.find((app) => app.slug === appName);
1115

16+
// Check if this is an OBBBA app that needs special handling
17+
const isOBBBAApp = app?.slug === "obbba-household-by-household";
18+
const [initialUrl, setInitialUrl] = useState(null);
19+
20+
// Construct iframe URL with parameters (for OBBBA app only on initial load)
21+
useEffect(() => {
22+
if (!app) return;
23+
24+
if (isOBBBAApp && !initialUrl) {
25+
const baseUrl = app.url;
26+
const separator = baseUrl.includes("?") ? "&" : "?";
27+
const urlParams = new URLSearchParams(location.search);
28+
29+
const url = urlParams.toString()
30+
? `${baseUrl}${separator}${urlParams.toString()}`
31+
: baseUrl;
32+
33+
setInitialUrl(url);
34+
} else if (!isOBBBAApp) {
35+
// For non-OBBBA apps, just use the app URL
36+
setInitialUrl(app.url);
37+
}
38+
}, [app, location.search, initialUrl, isOBBBAApp]);
39+
40+
// Listen for messages from OBBBA iframe
41+
useEffect(() => {
42+
if (!isOBBBAApp || !app) return;
43+
44+
const handleMessage = (event) => {
45+
try {
46+
const iframeOrigin = new URL(app.url).origin;
47+
if (event.origin !== iframeOrigin) return;
48+
49+
// Handle URL update messages from the iframe
50+
if (event.data?.type === "urlUpdate" && event.data?.params) {
51+
const newParams = new URLSearchParams(event.data.params);
52+
navigate(`${location.pathname}?${newParams.toString()}`, {
53+
replace: true,
54+
});
55+
}
56+
} catch (e) {
57+
console.error("Error handling iframe message:", e);
58+
}
59+
};
60+
61+
window.addEventListener("message", handleMessage);
62+
return () => window.removeEventListener("message", handleMessage);
63+
}, [isOBBBAApp, app, navigate, location.pathname]);
64+
1265
if (!app) {
1366
return (
1467
<>
@@ -30,16 +83,19 @@ export default function AppPage() {
3083
</Helmet>
3184
<Header />
3285
<div style={{ height: "var(--app-content-height)" }}>
33-
<iframe
34-
src={app.url}
35-
style={{
36-
width: "100%",
37-
height: "100%",
38-
border: "none",
39-
}}
40-
title={app.title}
41-
aria-label={app.description}
42-
/>
86+
{initialUrl && (
87+
<iframe
88+
ref={iframeRef}
89+
src={initialUrl}
90+
style={{
91+
width: "100%",
92+
height: "100%",
93+
border: "none",
94+
}}
95+
title={app.title}
96+
aria-label={app.description}
97+
/>
98+
)}
4399
</div>
44100
<Footer />
45101
</>

0 commit comments

Comments
 (0)