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

嵌入式分析SDK仅适用于专业版企业版计划(包括自托管和Metabase Cloud)。但是,您可以在本地机器上无需许可证即可使用API密钥进行嵌入式身份验证来试用SDK。

关于将嵌入式分析SDK与Next.js结合使用的一些注意事项。SDK经过测试可与Next.js 14配合使用,但可能也适用于其他版本。

带有服务器端渲染(SSR)或React服务器组件的SDK组件

目前,SDK组件仅支持客户端渲染。要将SDK组件与服务器端渲染或React服务器组件结合使用,您可以选择使用兼容层或手动包装组件。

服务器端渲染(SSR)的兼容层(实验性)

为了在Next.js中使用SDK组件,SDK提供了一个实验性兼容层,它使用动态导入包装所有组件并禁用SSR。为了与应用程序路由配合使用,此兼容层使用了use client

要使用兼容层,请将您的导入从@metabase/embedding-sdk-react更改为@metabase/embedding-sdk-react/nextjs

请参阅使用此兼容层的Next.js示例应用程序

手动包装组件

如果您想自定义组件的加载,可以创建自己的包装器。

在您的应用程序中,创建一个名为metabase的目录,并在该目录中添加一个EmbeddingSdkProvider.tsx文件。此文件将包含具有适当配置的提供程序。

"use client";

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

const authConfig = defineMetabaseAuthConfig({
  metabaseInstanceUrl: process.env.NEXT_PUBLIC_METABASE_INSTANCE_URL,
});

export const EmbeddingSdkProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  return (
    <MetabaseProvider authConfig={authConfig}>{children}</MetabaseProvider>
  );
};

接下来,在该metabase目录中添加一个index.tsx文件。该文件将包含use client指令,并将导出一个禁用SSR的延迟加载版本的EmbeddingSdkProvider

"use client";

import dynamic from "next/dynamic";

import type React from "react";

// Lazy load the EmbeddingSdkProvider so and let it render children while it's being loaded
export const EmbeddingSdkProviderLazy = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const EmbeddingSdkProvider = dynamic(
    () =>
      import("./EmbeddingSdkProvider").then(m => {
        return { default: m.EmbeddingSdkProvider };
      }),
    {
      ssr: false,
      loading: () => {
        // render children while loading
        return <div>{children}</div>;
      },
    },
  );

  return <EmbeddingSdkProvider>{children}</EmbeddingSdkProvider>;
};

// Wrap all components that you need like this:

export const StaticQuestion = dynamic(
  () => import("@metabase/embedding-sdk-react").then(m => m.StaticQuestion),
  {
    ssr: false,
    loading: () => {
      return <div>Loading...</div>;
    },
  },
);

export const StaticDashboard = dynamic(
  () => import("@metabase/embedding-sdk-react").then(m => m.StaticDashboard),
  {
    ssr: false,
    loading: () => {
      return <div>Loading...</div>;
    },
  },
);

您现在可以像这样导入组件

import { StaticQuestion } from "@/metabase"; // path to the folder created earlier

export default function Home() {
  return <StaticQuestion questionId={123} />;
}

处理认证

App Router 和 Pages Router 有不同的方式来定义 API 路由。如果您想从服务器使用 JWT 验证用户,可以按照以下说明操作。但如果您想在本地开发时使用 API 密钥进行验证,请参阅使用 API 密钥在本地进行验证

使用 App Router

您可以创建一个路由处理程序,用于将用户登录到 Metabase。

在您的app/*目录中创建一个新的route.ts文件,例如app/sso/metabase/route.ts,它对应于/sso/metabase的端点。此路由处理程序应为经过身份验证的用户生成一个JWT,并以{ jwt: string }的JSON对象形式返回令牌。

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,
  );
  // The user backend should return a JSON object with the JWT.
  return Response.json({ jwt: token });
}

然后,将此authConfig传递给MetabaseProvider

import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs";

const authConfig = defineMetabaseAuthConfig({
  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
});

使用 Pages Router

您可以创建一个 API 路由,用于将用户登录到 Metabase。

在您的pages/api/*目录中创建一个新的metabase.ts文件,例如pages/api/sso/metabase.ts,它对应于/api/sso/metabase的端点。此API路由应为经过身份验证的用户生成一个JWT,并以{ jwt: string }的JSON对象形式返回令牌。

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,
  );
  // The user backend should return a JSON object with the JWT.
  res.status(200).json({ jwt: token });
}

然后,将此authConfig传递给MetabaseProvider

import { defineMetabaseAuthConfig } from "@metabase/embedding-sdk-react/nextjs";

const authConfig = defineMetabaseAuthConfig({
  metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
});

阅读其他版本的 Metabase 的文档。

这有帮助吗?

感谢您的反馈!
想改进这些文档吗?提出更改。
© . This site is unofficial and not affiliated with Metabase, Inc.