嵌入式分析 SDK - 将 SDK 与 Next.js 结合使用
嵌入式分析 SDK 仅适用于 Pro 和 Enterprise 计划(包括自托管和 Metabase 云版)。但是,您可以通过使用 API 密钥进行嵌入式身份验证,在本地机器上无需许可证即可试用 SDK。
关于将嵌入式分析 SDK 与 Next.js 结合使用的一些注意事项。SDK 已经过测试,可与 Next.js 14 配合使用,尽管它可能也适用于其他版本。
带服务器端渲染 (SSR) 或 React 服务器组件的 SDK 组件
目前,SDK 组件仅支持客户端渲染。要在服务器端渲染或 React 服务器组件中使用 SDK 组件,您可以使用兼容层或手动封装组件。
服务器端渲染 (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
指令,并将导出 EmbeddingSdkProvider
的延迟加载版本,并禁用 SSR。
"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 版本的文档。