Your
Opinion.is

Embed survey to your own site

High level process

  1. Enable embedding is channel settings
  2. Create an iframe on your page and load the channel url
  3. Wait for a Post Message with survey load status and decide if you want to show the iframe or not
  4. When user has completed the form you will get another Post Message so you can hide the iframe

Information you can include in the URL (optional)

Below settings can be added to the channel url as search parameters

ParameterValuesDescription
languageen, et, de, frIf not provided will default to internaltional english
themelight, darkIf not provided we will respect users browser preference
transparenttrue, falseIf true will turn page background transparent
payloadstringSee safe links documentation for more info

Messages we are ready to receive

{
    "message": "theme-change",
    "theme": "light" // "light", "dark"
}

Messages we are sending

{
    "message": "survey-ready"
}

{
    "message": "survey-completed"
}

Simplified example for React

import { cn } from "@workspace/ui/lib/utils";
import { useCallback, useEffect, useRef, useState } from "react";
import * as v from "valibot";

const PostMessages = v.variant("message", [
    v.object({
        message: v.literal("survey-ready"),
    }),
    v.object({
        message: v.literal("survey-completed"),
    }),
]);

export function EmbeddedWidget() {
    const [visible, setVisible] = useState(false);
    const surveyRef = useRef<HTMLIFrameElement>(null);
    const theme = useTheme();

    // Handle messages from the iframe
    const handlePostMessage = useCallback((event: MessageEvent) => {
        if (event.origin !== "https://youropinion.is") {
            return null;
        }

        const message = v.parse(PostMessages, event.data);

        if (message.message === "survey-ready") {
            setVisible(true);
        } else if (message.message === "survey-completed") {
            setVisible(false);
        }
    }, []);

    // Listen for messages from iframe
    useEffect(() => {
        window.addEventListener("message", handlePostMessage);

        return () => {
            window.removeEventListener("message", handlePostMessage);
        };
    }, []);

    // Example of how to send a message to iframe
    useEffect(() => {
        if (surveyRef.current) {
            surveyRef.current.contentWindow?.postMessage({ message: "change-theme", theme }, "*");
        }
    }, [theme]);

    return (
        <div
            className={cn(
                "h-[400px] w-[400px] fixed right-24 bottom-24 opacity-0 transition-opacity duration-1000",
                {
                    "opacity-100": visible,
                }
            )}
        >
            <iframe
                src={`https://youropinion.is/snap/xxx/c/yyy?theme=${theme}&transparent=true`}
                className="w-full h-full"
                ref={surveyRef}
            />
        </div>
    );
}