嵌入式分析SDK - 使用SDK与Next.js结合

⚠️此功能处于测试阶段。您可以自由尝试,但请注意,可能会有变化(并且可能无法按预期工作)。

嵌入式分析SDK仅在Pro企业计划中可用(包括自托管和Metabase云服务)。然而,您可以通过使用API密钥进行身份验证来在本地机器上尝试SDK,而无需许可证。

有关使用Next.js与嵌入式分析SDK的一些说明。

使用App Router

创建一个组件,导入 MetabaseProvider 并将其标记为“使用客户端”的 React 客户端组件。

"use client";

import { MetabaseProvider, StaticQuestion, defineEmbeddingSdkConfig } from "@metabase/embedding-sdk-react";

const config = defineEmbeddingSdkConfig({
//...
}); // Your Metabase SDK configuration

export default function MetabaseComponents() {
  return (
    <MetabaseProvider config={config}>
      <StaticQuestion questionId={QUESTION_ID} />
    </MetabaseProvider>
  );

您必须使用默认导出。在此配置中不支持命名导出,并且它将不起作用。

然后,在您的页面上导入此组件

// page.tsx

const MetabaseComponentsNoSsr = dynamic(
  () => import("@/components/MetabaseComponents"),
  {
    ssr: false,
  },
);

export default function HomePage() {
  return (
    <>
      <MetabaseComponentsNoSsr />
    </>
  );
}

重复:如果您将组件作为命名导出,它将不会与 Next.js 一起工作。您必须使用默认导出。例如,下面的代码将不起作用:

const DynamicAnalytics = dynamic(
  () =>
    import("@/components/MetabaseComponents").then(
      module => module.MetabaseComponents,
    ),
  {
    ssr: false,
  },
);

处理身份验证

如果您使用 JWT 通过 Metabase 进行身份验证,您可以创建一个路由处理程序,将人们登录到 Metabase。

在您的 app/* 目录中创建一个新的 route.ts 文件,例如 app/sso/metabase/route.ts,对应于 /sso/metabase 的端点。

import jwt from "jsonwebtoken";

const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || "";
const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || "";

export async function GET() {
  const token = jwt.sign(
    {
      email: user.email,
      first_name: user.firstName,
      last_name: user.lastName,
      groups: [user.group],
      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
    },
    // This is the JWT signing secret in your Metabase JWT authentication setting
    METABASE_JWT_SHARED_SECRET,
  );
  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;

  try {
    const ssoResponse = await fetch(ssoUrl, { method: "GET" });
    const ssoResponseBody = await ssoResponse.json();

    return Response.json(ssoResponseBody);
  } catch (error) {
    if (error instanceof Error) {
      return Response.json(
        {
          status: "error",
          message: "authentication failed",
          error: error.message,
        },
        {
          status: 401,
        },
      );
    }
  }
}

将此 config 传递给 MetabaseProvider

import { defineEmbeddingSdkConfig } from "@metabase/embedding-sdk-react";
const config = defineEmbeddingSdkConfig({
  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
  jwtProviderUri: "/sso/metabase", // Required: An endpoint in your app that signs people in and returns a token.
});

使用页面路由器

这与 App Router 几乎相同,但您不需要将导入 Metabase SDK 组件的组件标记为 React 客户端组件。

如果您使用 JWT 通过 Metabase 进行身份验证,您可以创建一个 API 路由,将人们登录到 Metabase。

在您的 pages/api/* 目录中创建一个新的 metabase.ts 文件,例如 pages/api/sso/metabase.ts,对应于 /api/sso/metabase 的端点。

import type { NextApiRequest, NextApiResponse } from "next";
import jwt from "jsonwebtoken";

const METABASE_JWT_SHARED_SECRET = process.env.METABASE_JWT_SHARED_SECRET || "";
const METABASE_INSTANCE_URL = process.env.METABASE_INSTANCE_URL || "";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  const token = jwt.sign(
    {
      email: user.email,
      first_name: user.firstName,
      last_name: user.lastName,
      groups: [user.group],
      exp: Math.round(Date.now() / 1000) + 60 * 10, // 10 minutes expiration
    },
    // This is the JWT signing secret in your Metabase JWT authentication setting
    METABASE_JWT_SHARED_SECRET,
  );
  const ssoUrl = `${METABASE_INSTANCE_URL}/auth/sso?token=true&jwt=${token}`;

  try {
    const ssoResponse = await fetch(ssoUrl, { method: "GET" });
    const ssoResponseBody = await ssoResponse.json();

    res.status(200).json(ssoResponseBody);
  } catch (error) {
    if (error instanceof Error) {
      res.status(401).json({
        status: "error",
        message: "authentication failed",
        error: error.message,
      });
    }
  }
}

并将此 config 传递给 MetabaseProvider

import { defineEmbeddingSdkConfig } from "@metabase/embedding-sdk-react";
const config = defineEmbeddingSdkConfig({
  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
  jwtProviderUri: "/api/sso/metabase", // Required: An endpoint in your app that returns signs the user in and delivers a token
});

阅读其他 Metabase 版本 的文档。

想改进这些文档吗? 提出更改。