Integration Guide: Receiving Messages from the Quiz Iframe
When you embed the GOFA Quiz experience as an <iframe>, you can listen for important events and results using the window.postMessage API.
1. Embed the Iframe
<iframe
id="quizIframe"
src="https://your-gofa-app-url/fall-risk/[fallRiskResultId]/quiz?noAutoNav=true"
width="100%"
height="600"
frameborder="0"
></iframe>
2. Listen for Messages
Add a message event listener in your parent page's JavaScript:
window.addEventListener("message", function (event) {
// Optionally, check event.origin for security
// if (event.origin !== 'https://your-gofa-app-url') return;
const { source, type, payload } = event.data || {};
// Only handle messages from the GOFA quiz iframe
if (source !== "gofa-quiz") return;
switch (type) {
case "STATE_TRANSITION":
// payload: { state, ... }
console.log("Quiz state changed:", payload.state, payload);
break;
case "QUIZ_STARTED":
// payload: { step, state }
console.log("Quiz started:", payload);
break;
case "QUIZ_ENDED":
// payload: { step, state }
console.log("Quiz ended:", payload);
// Quiz is finished!
// You can show a summary, trigger analytics, or navigate as needed
// If you used ?noAutoNav=true, you must handle navigation yourself
break;
case "RESULTS_SET":
// payload: { ...quizResults }
console.log("Quiz results:", payload);
break;
default:
// Handle other message types if needed
break;
}
});
3. Message Types
STATE_TRANSITION: Sent on every quiz step change. Payload includes current step and state.QUIZ_STARTED: Sent when the quiz starts (step 0).QUIZ_ENDED: Sent when the quiz is completed (step 3).RESULTS_SET: Sent when results are shown (step 3, payload is the quiz result state).
4. About noAutoNav
- If you open the quiz with
?noAutoNav=truein the URL, the quiz page will NOT auto-navigate to the result page after completion. - This lets the parent site fully control what happens next after receiving the
QUIZ_ENDEDmessage. - Without
noAutoNav, the quiz will automatically redirect to the results page after 1.2 seconds.
5. Example Implementation
// Track quiz progress
let quizActive = false;
window.addEventListener("message", function (event) {
const { source, type, payload } = event.data || {};
if (source !== "gofa-quiz") return;
switch (type) {
case "STATE_TRANSITION":
console.log("Quiz step changed to:", payload.step);
updateQuizProgress(payload.step);
break;
case "QUIZ_STARTED":
quizActive = true;
updateUI("Quiz started");
break;
case "QUIZ_ENDED":
quizActive = false;
updateUI("Quiz completed");
// Handle what happens after quiz completion
// Since we used ?noAutoNav=true, we control navigation
setTimeout(() => {
showNextSteps();
}, 2000);
break;
case "RESULTS_SET":
displayQuizResults(payload);
break;
}
});
function updateUI(message) {
document.getElementById("status").textContent = message;
}
function updateQuizProgress(step) {
const progressBar = document.getElementById("progress");
if (progressBar) {
progressBar.style.width = `${(step / 3) * 100}%`;
}
}
function displayQuizResults(results) {
document.getElementById("results").innerHTML = `
<h3>Quiz Results</h3>
<pre>${JSON.stringify(results, null, 2)}</pre>
`;
}
function showNextSteps() {
document.getElementById("next-steps").style.display = "block";
}
6. Security Considerations
Always validate event.origin to ensure messages are from your trusted GOFA app domain:
window.addEventListener("message", function (event) {
// Replace with your actual GOFA app domain
if (event.origin !== "https://your-gofa-app-url") {
return;
}
// Process the message...
});