Skip to content
Snippets Groups Projects
Unverified Commit a03ea880 authored by Mahatthana (Kelvin) Nomsawadi's avatar Mahatthana (Kelvin) Nomsawadi Committed by GitHub
Browse files

docs(sdk): Add a guide on how to use the SDK with Next.js (#48569)

* Add Next.js to SDK readme

* Fix typo
parent 74a14bba
No related branches found
No related tags found
No related merge requests found
......@@ -1189,6 +1189,169 @@ async function fetchRequestToken(url) {
const config = {fetchRequestToken};
```
### Using with Next.js
#### Using App Router
Create a component that imports the `MetabaseProvider` and mark it a React Client component with "use client";
```typescript jsx
"use client";
import { MetabaseProvider, StaticQuestion } from "@metabase/embedding-sdk-react";
const config = {...}; // Your Metabase SDK configuration
export default function MetabaseComponents() {
return (
<MetabaseProvider config={config}>
<StaticQuestion questionId={QUESTION_ID} />
</MetabaseProvider>
);
```
Make sure to use default export, as named export is not supported with this setup.
Then, import this component in your page:
```typescript jsx
// page.tsx
const MetabaseComponentsNoSsr = dynamic(() => import("@/components/MetabaseComponents"), {
ssr: false
});
export default function HomePage() {
return (
<>
<MetabaseComponentsNoSsr />
</>
);
}
```
> [!CAUTION]
> If you export the component as a named export, it will not work with Next.js. You must use a default export.
This won't work:
```typescript jsx
const DynamicAnalytics = dynamic(
() => import("@/components/MetabaseComponents").then((module) => module.MetabaseComponents),
{
ssr: false,
}
);
```
If you authenticate with Metabase using JWT, you can create a Route handler that signs a user into Metabase.
Create a new `route.ts` file in your `app/*` directory, for example `app/sso/metabase/route.ts` that corresponds to an endpoint at /sso/metabase.
```typescript
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,
}
);
}
}
}
```
And pass this `config` to `MetabaseProvider`
```ts
const config = {
metabaseInstanceUrl: "https://metabase.example.com", // Required: Your Metabase instance URL
jwtProviderUri: "/sso/metabase", // Required: An endpoint in your app that returns signs the user in and delivers a token
};
```
#### Using Pages Router
This works almost the same as the App Router, but you don't need to mark your component that imports Metabase SDK components as a React Client component (with "use client").
If you authenticate with Metabase using JWT, you can create an API route that signs a user into Metabase.
Create a new `metabase.ts` file in your `pages/api/*` directory, for example `pages/api/sso/metabase.ts` that corresponds to an endpoint at /api/sso/metabase.
```typescript
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,
});
}
}
}
```
And pass this `config` to `MetabaseProvider`
```ts
const config = {
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
};
```
# Development
## Storybook
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment