Questions about building a custom configuration UI for a Flow Action

:wave: There were major changes between App-Bridge version 3 and 4 so please make sure you’re using the correct version otherwise the code examples won’t work.

We should update the docs, the ... are just there to signify that that’s where your component markup should go (which is custom to your application).

I see some discrepancy in the docs and also some missing information…

Does it work if you put the buttons markup inside the <TitleBar>//buttons here</TitleBar> instead of passing them as a parameter? At least that is what the error message (and some of the possibly outdated docs) suggests.

@Maxime_Leduc thanks - yeah if I could get a more complete version in the docs that would be great. There’s enough magic involved here that a simple working example with a field in it would be super useful.

I did try putting a dummy div in there but it didn’t output onto the canvas.

@curzey I do get the buttons in there when I use this - but again not sure how to get the actual main content area functioning.


Talked this through with Max. Here’s an example of how the code ties together:

import { useAppBridge } from "@shopify/app-bridge-react";
import { useEffect, useState } from "react";
import { Text, Button } from "@shopify/polaris";
//import { useSearchParams } from "@remix-run/react";

const Editor = () => {
  const shopify = useAppBridge();
  const [intent, setIntent] = useState();
  //const params = useSearchParams();
  const shopifyIntents = typeof window !== "undefined" ? shopify.intents : undefined;
  //const stepReference = params[0].get("step_reference");

  useEffect(() => {
    let cleanup;

    if (shopifyIntents) {
      // This code will only run in the browser
      cleanup = shopifyIntents.register((intent) => {
        setIntent(intent);
      });
    }

    return () => cleanup && cleanup();
  }, [shopifyIntents]);

  return (
    <div>
      <ui-title-bar title="Products">
        <button variant="primary" onClick={() => console.log("hey")}>
          Save
        </button>
      </ui-title-bar>

      <Text variant="headingXl" as={"h1"}>
        Data Received by the Editor (key/value)
      </Text>
      {intent?.data?.properties &&
        Object.entries(intent.data.properties).map((field) => (
          <p key={field[0]}>
            <b>{`${field[0]} (${typeof field[1]}):`}</b>{" "}
            {`${field[1] ? field[1] : "N/A"}`}
          </p>
        ))}

      <div>
        <Button
          primary
          onClick={() => {
            intent?.finish();
          }}
        >
          Go back to Flow
        </Button>
      </div>
    </div>
  );
};

export default Editor;
3 Likes

Awesome thanks! I’ve got that loading in here now - the intents are commented out in your snippet - is that intentional? It’s not pulling anything in.

Yeah, just uncomment that.

1 Like