DEV Community

Cover image for Embedding Metabase using GraphQL
Sibelius Seraphini for Woovi

Posted on

Embedding Metabase using GraphQL

Metabase is a powerful tool to create data visualizations.

It also enables us to embed these visualizations in other websites.

This article will explain how we use GraphQL to make this embed easier to consume in our back office.

GraphQL resolver for Metabase embed

export const metabaseEmbedResolver = {
  metabaseEmbedUrl: {
    type: GraphQLString,
    args: {
      question: {
        type: GraphQLString,
      },
      dashboard: {
        type: GraphQLString,
      },
      params: {
        type: GraphQLString,
      },
    },
    resolve: (obj, args, context) => {
      if (!isLoggedIn(context)) {
        return NullConnection;
      }

      if (!args.question && !args.dashboard) {
        return null;
      }

      const payload = {
        resource: {
          question: parseInt(args.question, 10),
          dashboard: parseInt(args.dashboard, 10),
        },
        params: args.params ? JSON.parse(args.params) : {},
        exp: Math.round(Date.now() / 1000) + 10 * 60, // 10 minute expiration
      };

      const token = jwt.sign(payload, METABASE_SECRET_KEY);

      const getIframeUrl = (): string | null => {
        if (args.question) {
          return `${METABASE_SITE_URL}/embed/question/${token}#bordered=true&titled=true`;
        }

        if (args.dashboard) {
          return `${METABASE_SITE_URL}/embed/dashboard/${token}#bordered=true&titled=true`;
        }

        return null;
      };

      return getIframeUrl();
    },
  },
};
Enter fullscreen mode Exit fullscreen mode

The code above generates this GraphQL Schema:

metabaseEmbedUrl(question: String, dashboard: String, params: String): String
Enter fullscreen mode Exit fullscreen mode

It accepts a question or a dashboard number, params as a string, and returns an iFrame URL

This code must be in the backend because the iFrame URL contains the payload signed by a secret, so users can't modify the question/dashboard or params.

This is useful to create a visualization for your users using a tenantId as a parameter.

Embed using React and Relay

const MetabaseEmbed = (props): ReactNode => {
  const response = useLazyLoadQuery<MetabaseDailyTransactionPerClusterQuery>(
    graphql`
      query MetabaseEmbedQuery {
        ...MetabaseEmbed_query
      }
    `,
    {},
    {
      fetchPolicy: 'store-or-network',
    },
  );

  const query = useFragment<MetabaseEmbed_query$key>(
    graphql`
      fragment MetabaseEmbed_query on Query {
        metabaseEmbedUrl(question: "179")
      }
    `,
    response,
  );

  return <iframe src={query.metabaseEmbedUrl} height={'500px'} />;
};
Enter fullscreen mode Exit fullscreen mode

The MetabaseEmbedQuery query will return the Metabase embed URL from the backend, we can reuse this component everywhere we want to embed a Metabase question or dashboard.

In Conclusion

Using Metabase embed is an easy task when working with GraphQL and Relay.
This can be used in your back office or for your users.
Instead of rebuilding the visualization in your product, you can create a few visualizations on Metabase for the MVP and then refine and need it.


Woovi is an innovative startup revolutionizing the payment landscape. With Woovi, shoppers can enjoy the freedom to pay however they prefer. Our cutting-edge platform provides instant payment solutions, empowering merchants to accept orders and enhance their customer experience seamlessly.

If you're interested in joining our team, we're hiring! Check out our job openings at Woovi Careers.

Top comments (0)