Skip to main content

Embed a metapage in your React app

Live example

This live example shows how to embed a metapage in a React app.

First imports:

import { MetapageGridLayoutFromDefinition } from "@metapages/metapage-grid-react";

You can copy the metapage JSON (blue button) and paste in https://app.metapages.org/ to see the live app.

Result
Loading...
Live Editor
function ExampleEmbedMetapage() {
  const [definition, setDefinition] = useState();

  useEffect(() => {
		(async () => {
				var resp = await fetch("https://app.metapage.io/dion/example-hello-world-b4dc42b55df94364a1ebac10e8e91f32/metapage.json");
				var metapageJson = await resp.json();
				setDefinition(metapageJson);
		})();
	}, []);

  const onOutputs = (outputs) => {
    // This is where the metapage state changes, via metaframes setting
    // outputs and passing them to downstream metaframes.
    // You can intercept the data state changes for your own purposes
    // console.log(`Got outputs!! outputs=${JSON.stringify(outputs)}`);
  };

  // hack to copy metapage JSON to clipboard
  const copyToClipboard = useCallback(() => {
    var textarea = document.createElement("textarea");
    textarea.value = JSON.stringify(definition);
    document.body.appendChild(textarea);
    textarea.select();
    document.execCommand("copy");
    document.body.removeChild(textarea);
  }, [definition]);

  const CustomGridItemComponentLabel = useMemo(() => {
    return React.forwardRef((props, ref) => {
      return (
        <div
          style={{
            overflow: "hidden",
            padding: "10px",
            backgroundColor: "white",
            border: "1px solid lightgrey",
						width: "100%",
						height: "100%",
            ...props.style,
          }}
          className={props.className}
          ref={ref}
        >
          <h4 style={{ textAlign: "right" }}>
            <span style={{ padding: "2px", color: "lightgrey" }}>
              {props.children[0].key}
            </span>
          </h4>
          {props.children}
        </div>
      );
    });
  }, []);

  const onDefinition = useCallback(
    (def) => {
      setDefinition(def);
    },
    [setDefinition]
  );

  return (
    <>
      <button
        onClick={copyToClipboard}
        style={{
          backgroundColor: "#32AEE4",
          borderWidth: "0px",
          color: "#ffffff",
          fontWeight: 800,
          position: "relative",
          outline: "none",
          borderRadius: "6px",
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          cursor: "pointer",
          height: "30px",
          width: "120px",
        }}
      >
        Copy metapage
      </button>
      <MetapageGridLayoutFromDefinition
        definition={definition}
        onOutputs={onOutputs}
        onDefinition={onDefinition}
        Wrapper={CustomGridItemComponentLabel}
      />
    </>
  );
}