嵌入式分析SDK - 使用SDK与Next.js结合
⚠️此功能处于测试阶段。您可以自由尝试,但请注意,可能会有变化(并且可能无法按预期工作)。
有关使用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 版本 的文档。