Skip to content

Commit b96c464

Browse files
github-automation-metabaseMetabase Docs bot
andauthored
[auto] adding content to release-x.57.x->release-x.57.x (#794)
Co-authored-by: Metabase Docs bot <[email protected]>
1 parent 41385b0 commit b96c464

File tree

8 files changed

+203
-66
lines changed

8 files changed

+203
-66
lines changed

_docs/v0.57/embedding/sdk/introduction.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ The SDK doesn't support:
135135
- Official collections
136136
- Subscriptions
137137
- Alerts
138+
- Click behavior with custom destinations to other items in the same Metabase (like to other questions or dashboards)
138139
- Server-side rendering (SSR)
139140

140141
Other limitations:

_docs/v0.57/embedding/sdk/plugins.md

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,59 +15,57 @@ layout: new-docs
1515

1616
The Metabase Embedded analytics SDK supports plugins to customize the behavior of components. These plugins can be used in a global context or on a per-component basis.
1717

18-
## Global plugins
18+
## Plugin scope
19+
20+
### Global plugins
1921

2022
To use a plugin globally, add the plugin to the `MetabaseProvider`'s `pluginsConfig` prop:
2123

2224
```typescript
2325
{% include_file "{{ dirname }}/snippets/plugins/global-plugins.tsx" snippet="example" %}
2426
```
2527

26-
## Component plugins
28+
### Component plugins
2729

2830
To use a plugin on a per-component basis, pass the plugin as a prop to the component:
2931

3032
```typescript
3133
{% include_file "{{ dirname }}/snippets/plugins/component-plugins.tsx" snippet="example" %}
3234
```
3335

34-
## `handleLink`
36+
See docs for specific components:
37+
38+
- [Interactive question plugins](./questions#interactive-question-plugins)
39+
- [Dashboard plugins](./dashboards#dashboard-plugins)
40+
41+
## Global plugins
42+
43+
### `mapQuestionClickActions`
44+
45+
The plugin `mapQuestionClickActions` lets you to customize what happens when people click on a data point on a dashboard or chart. `mapQuestionClickActions` can be used globally, or on component level.
46+
47+
See [`mapQuestionClickActions` plugin](./questions#mapquestionclickactions) for more information and examples.
48+
49+
### `handleLink`
3550

3651
To customize what happens when people click a link in your embedded questions and dashboards, use the global plugin `handleLink`:
3752

3853
```typescript
39-
export default function App() {
40-
const navigate = useNavigate(); // coming from whatever routing lib you're using
41-
42-
const plugins = {
43-
handleLink: (urlString: string) => {
44-
const url = new URL(urlString, window.location.origin);
45-
const isInternal = url.origin === window.location.origin;
46-
if (isInternal) {
47-
// client side navigation
48-
navigate(url.pathname + url.search + url.hash);
49-
50-
return { handled: true }; // prevent default navigation
51-
}
52-
return { handled: false }; // let the sdk do the default behavior
53-
},
54-
};
55-
56-
return (
57-
<MetabaseProvider authConfig={authConfig} pluginsConfig={plugins}>
58-
<nav style={{ display: "flex", gap: 12, padding: 12 }}>
59-
<Link to="/">Home</Link>
60-
<Link to="/question">Question</Link>
61-
<Link to="/about">About</Link>
62-
</nav>
63-
<div style={{ padding: 12 }}>
64-
<Outlet />
65-
</div>
66-
</MetabaseProvider>
67-
);
68-
}
54+
{% include_file "{{ dirname }}/snippets/plugins/handlelink.tsx" snippet="example" %}
6955
```
7056

57+
The plugin `handleLink` can only be used [globally](#plugin-scope) on provider level.
58+
59+
### `getNoDataIllustration` and `getNoObjectIllustration`
60+
61+
By default, Metabase displays a sailboat image when a query returns no results. To use a different image, you can use `getNoDataIllustration` and `getNoObjectIllustration` plugins which can accept a custom base64-encoded image:
62+
63+
```typescript
64+
{% include_file "{{ dirname }}/snippets/plugins/custom-images.tsx" snippet="example" %}
65+
```
66+
67+
The plugins `getNoDataIllustration` and `getNoObjectIllustration` can only be used [globally](#plugin-scope) on provider level.
68+
7169
## Further reading
7270

7371
- [Interactive question plugins](./questions#interactive-question-plugins)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {
2+
InteractiveDashboard,
3+
type MetabaseAuthConfig,
4+
MetabaseProvider,
5+
} from "@metabase/embedding-sdk-react";
6+
7+
const authConfig = {} as MetabaseAuthConfig;
8+
9+
export default function App() {
10+
// [<snippet example>]
11+
12+
const img_base64 = "..."; // base64-encoded image
13+
14+
const plugins = {
15+
getNoDataIllustration: () => img_base64,
16+
getNoObjectIllustration: () => img_base64,
17+
};
18+
19+
return (
20+
<MetabaseProvider authConfig={authConfig} pluginsConfig={plugins}>
21+
<InteractiveDashboard dashboardId={1} />
22+
</MetabaseProvider>
23+
);
24+
// [<endsnippet example>]
25+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import {
2+
InteractiveDashboard,
3+
type MetabaseAuthConfig,
4+
MetabaseProvider,
5+
} from "@metabase/embedding-sdk-react";
6+
7+
const authConfig = {} as MetabaseAuthConfig;
8+
9+
export default function App() {
10+
// [<snippet example>]
11+
const plugins = {
12+
handleLink: (urlString: string) => {
13+
const url = new URL(urlString, window.location.origin);
14+
const isInternal = url.origin === window.location.origin;
15+
if (isInternal) {
16+
// Handle internal navigation (e.g., with your router)
17+
console.log("Navigate to:", url.pathname + url.search + url.hash);
18+
return { handled: true }; // prevent default navigation
19+
}
20+
return { handled: false }; // let the SDK do the default behavior
21+
},
22+
};
23+
24+
return (
25+
<MetabaseProvider authConfig={authConfig} pluginsConfig={plugins}>
26+
<InteractiveDashboard dashboardId={1} />
27+
</MetabaseProvider>
28+
);
29+
// [<endsnippet example>]
30+
}

_site/docs/v0.57/embedding/sdk/introduction.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5058,6 +5058,7 @@ <h2 id="sdk-limitations">SDK limitations</h2>
50585058
<li>Official collections</li>
50595059
<li>Subscriptions</li>
50605060
<li>Alerts</li>
5061+
<li>Click behavior with custom destinations to other items in the same Metabase (like to other questions or dashboards)</li>
50615062
<li>Server-side rendering (SSR)</li>
50625063
</ul>
50635064

_site/docs/v0.57/embedding/sdk/plugins.html

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,7 +4931,9 @@ <h1 id="embedded-analytics-sdk---plugins">Embedded analytics SDK - plugins</h1>
49314931

49324932
<p>The Metabase Embedded analytics SDK supports plugins to customize the behavior of components. These plugins can be used in a global context or on a per-component basis.</p>
49334933

4934-
<h2 id="global-plugins">Global plugins</h2>
4934+
<h2 id="plugin-scope">Plugin scope</h2>
4935+
4936+
<h3 id="global-plugins">Global plugins</h3>
49354937

49364938
<p>To use a plugin globally, add the plugin to the <code class="language-plaintext highlighter-rouge">MetabaseProvider</code>’s <code class="language-plaintext highlighter-rouge">pluginsConfig</code> prop:</p>
49374939

@@ -4946,7 +4948,7 @@ <h2 id="global-plugins">Global plugins</h2>
49464948
<span class="o">&lt;</span><span class="sr">/MetabaseProvider</span><span class="err">&gt;
49474949
</span></code></pre></div></div>
49484950

4949-
<h2 id="component-plugins">Component plugins</h2>
4951+
<h3 id="component-plugins">Component plugins</h3>
49504952

49514953
<p>To use a plugin on a per-component basis, pass the plugin as a prop to the component:</p>
49524954

@@ -4958,42 +4960,67 @@ <h2 id="component-plugins">Component plugins</h2>
49584960
<span class="sr">/</span><span class="err">&gt;
49594961
</span></code></pre></div></div>
49604962

4961-
<h2 id="handlelink"><code class="language-plaintext highlighter-rouge">handleLink</code></h2>
4963+
<p>See docs for specific components:</p>
4964+
4965+
<ul>
4966+
<li><a href="./questions#interactive-question-plugins">Interactive question plugins</a></li>
4967+
<li><a href="./dashboards#dashboard-plugins">Dashboard plugins</a></li>
4968+
</ul>
4969+
4970+
<h2 id="global-plugins-1">Global plugins</h2>
4971+
4972+
<h3 id="mapquestionclickactions"><code class="language-plaintext highlighter-rouge">mapQuestionClickActions</code></h3>
4973+
4974+
<p>The plugin <code class="language-plaintext highlighter-rouge">mapQuestionClickActions</code> lets you to customize what happens when people click on a data point on a dashboard or chart. <code class="language-plaintext highlighter-rouge">mapQuestionClickActions</code> can be used globally, or on component level.</p>
4975+
4976+
<p>See <a href="./questions#mapquestionclickactions"><code class="language-plaintext highlighter-rouge">mapQuestionClickActions</code> plugin</a> for more information and examples.</p>
4977+
4978+
<h3 id="handlelink"><code class="language-plaintext highlighter-rouge">handleLink</code></h3>
49624979

49634980
<p>To customize what happens when people click a link in your embedded questions and dashboards, use the global plugin <code class="language-plaintext highlighter-rouge">handleLink</code>:</p>
49644981

4965-
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">export</span> <span class="k">default</span> <span class="kd">function</span> <span class="nf">App</span><span class="p">()</span> <span class="p">{</span>
4966-
<span class="kd">const</span> <span class="nx">navigate</span> <span class="o">=</span> <span class="nf">useNavigate</span><span class="p">();</span> <span class="c1">// coming from whatever routing lib you're using</span>
4967-
4968-
<span class="kd">const</span> <span class="nx">plugins</span> <span class="o">=</span> <span class="p">{</span>
4969-
<span class="na">handleLink</span><span class="p">:</span> <span class="p">(</span><span class="na">urlString</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
4970-
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">URL</span><span class="p">(</span><span class="nx">urlString</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span><span class="p">);</span>
4971-
<span class="kd">const</span> <span class="nx">isInternal</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">origin</span> <span class="o">===</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span><span class="p">;</span>
4972-
<span class="k">if </span><span class="p">(</span><span class="nx">isInternal</span><span class="p">)</span> <span class="p">{</span>
4973-
<span class="c1">// client side navigation</span>
4974-
<span class="nf">navigate</span><span class="p">(</span><span class="nx">url</span><span class="p">.</span><span class="nx">pathname</span> <span class="o">+</span> <span class="nx">url</span><span class="p">.</span><span class="nx">search</span> <span class="o">+</span> <span class="nx">url</span><span class="p">.</span><span class="nx">hash</span><span class="p">);</span>
4975-
4976-
<span class="k">return</span> <span class="p">{</span> <span class="na">handled</span><span class="p">:</span> <span class="kc">true</span> <span class="p">};</span> <span class="c1">// prevent default navigation</span>
4977-
<span class="p">}</span>
4978-
<span class="k">return</span> <span class="p">{</span> <span class="na">handled</span><span class="p">:</span> <span class="kc">false</span> <span class="p">};</span> <span class="c1">// let the sdk do the default behavior</span>
4979-
<span class="p">},</span>
4980-
<span class="p">};</span>
4981-
4982-
<span class="k">return </span><span class="p">(</span>
4983-
<span class="o">&lt;</span><span class="nx">MetabaseProvider</span> <span class="nx">authConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">authConfig</span><span class="p">}</span> <span class="nx">pluginsConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">plugins</span><span class="p">}</span><span class="o">&gt;</span>
4984-
<span class="o">&lt;</span><span class="nx">nav</span> <span class="nx">style</span><span class="o">=&gt;</span>
4985-
<span class="o">&lt;</span><span class="nx">Link</span> <span class="nx">to</span><span class="o">=</span><span class="dl">"</span><span class="s2">/</span><span class="dl">"</span><span class="o">&gt;</span><span class="nx">Home</span><span class="o">&lt;</span><span class="sr">/Link</span><span class="err">&gt;
4986-
</span> <span class="o">&lt;</span><span class="nx">Link</span> <span class="nx">to</span><span class="o">=</span><span class="dl">"</span><span class="s2">/question</span><span class="dl">"</span><span class="o">&gt;</span><span class="nx">Question</span><span class="o">&lt;</span><span class="sr">/Link</span><span class="err">&gt;
4987-
</span> <span class="o">&lt;</span><span class="nx">Link</span> <span class="nx">to</span><span class="o">=</span><span class="dl">"</span><span class="s2">/about</span><span class="dl">"</span><span class="o">&gt;</span><span class="nx">About</span><span class="o">&lt;</span><span class="sr">/Link</span><span class="err">&gt;
4988-
</span> <span class="o">&lt;</span><span class="sr">/nav</span><span class="err">&gt;
4989-
</span> <span class="o">&lt;</span><span class="nx">div</span> <span class="nx">style</span><span class="o">=&gt;</span>
4990-
<span class="o">&lt;</span><span class="nx">Outlet</span> <span class="o">/&gt;</span>
4991-
<span class="o">&lt;</span><span class="sr">/div</span><span class="err">&gt;
4992-
</span> <span class="o">&lt;</span><span class="sr">/MetabaseProvider</span><span class="err">&gt;
4993-
</span> <span class="p">);</span>
4994-
<span class="p">}</span>
4982+
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">plugins</span> <span class="o">=</span> <span class="p">{</span>
4983+
<span class="na">handleLink</span><span class="p">:</span> <span class="p">(</span><span class="na">urlString</span><span class="p">:</span> <span class="kr">string</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
4984+
<span class="kd">const</span> <span class="nx">url</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">URL</span><span class="p">(</span><span class="nx">urlString</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span><span class="p">);</span>
4985+
<span class="kd">const</span> <span class="nx">isInternal</span> <span class="o">=</span> <span class="nx">url</span><span class="p">.</span><span class="nx">origin</span> <span class="o">===</span> <span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">origin</span><span class="p">;</span>
4986+
<span class="k">if </span><span class="p">(</span><span class="nx">isInternal</span><span class="p">)</span> <span class="p">{</span>
4987+
<span class="c1">// Handle internal navigation (e.g., with your router)</span>
4988+
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">"</span><span class="s2">Navigate to:</span><span class="dl">"</span><span class="p">,</span> <span class="nx">url</span><span class="p">.</span><span class="nx">pathname</span> <span class="o">+</span> <span class="nx">url</span><span class="p">.</span><span class="nx">search</span> <span class="o">+</span> <span class="nx">url</span><span class="p">.</span><span class="nx">hash</span><span class="p">);</span>
4989+
<span class="k">return</span> <span class="p">{</span> <span class="na">handled</span><span class="p">:</span> <span class="kc">true</span> <span class="p">};</span> <span class="c1">// prevent default navigation</span>
4990+
<span class="p">}</span>
4991+
<span class="k">return</span> <span class="p">{</span> <span class="na">handled</span><span class="p">:</span> <span class="kc">false</span> <span class="p">};</span> <span class="c1">// let the SDK do the default behavior</span>
4992+
<span class="p">},</span>
4993+
<span class="p">};</span>
4994+
4995+
<span class="k">return </span><span class="p">(</span>
4996+
<span class="o">&lt;</span><span class="nx">MetabaseProvider</span> <span class="nx">authConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">authConfig</span><span class="p">}</span> <span class="nx">pluginsConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">plugins</span><span class="p">}</span><span class="o">&gt;</span>
4997+
<span class="o">&lt;</span><span class="nx">InteractiveDashboard</span> <span class="nx">dashboardId</span><span class="o">=</span><span class="p">{</span><span class="mi">1</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
4998+
</span> <span class="o">&lt;</span><span class="sr">/MetabaseProvider</span><span class="err">&gt;
4999+
</span><span class="p">);</span>
49955000
</code></pre></div></div>
49965001

5002+
<p>The plugin <code class="language-plaintext highlighter-rouge">handleLink</code> can only be used <a href="#plugin-scope">globally</a> on provider level.</p>
5003+
5004+
<h3 id="getnodataillustration-and-getnoobjectillustration"><code class="language-plaintext highlighter-rouge">getNoDataIllustration</code> and <code class="language-plaintext highlighter-rouge">getNoObjectIllustration</code></h3>
5005+
5006+
<p>By default, Metabase displays a sailboat image when a query returns no results. To use a different image, you can use <code class="language-plaintext highlighter-rouge">getNoDataIllustration</code> and <code class="language-plaintext highlighter-rouge">getNoObjectIllustration</code> plugins which can accept a custom base64-encoded image:</p>
5007+
5008+
<div class="language-typescript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">img_base64</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">...</span><span class="dl">"</span><span class="p">;</span> <span class="c1">// base64-encoded image</span>
5009+
5010+
<span class="kd">const</span> <span class="nx">plugins</span> <span class="o">=</span> <span class="p">{</span>
5011+
<span class="na">getNoDataIllustration</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">img_base64</span><span class="p">,</span>
5012+
<span class="na">getNoObjectIllustration</span><span class="p">:</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nx">img_base64</span><span class="p">,</span>
5013+
<span class="p">};</span>
5014+
5015+
<span class="k">return </span><span class="p">(</span>
5016+
<span class="o">&lt;</span><span class="nx">MetabaseProvider</span> <span class="nx">authConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">authConfig</span><span class="p">}</span> <span class="nx">pluginsConfig</span><span class="o">=</span><span class="p">{</span><span class="nx">plugins</span><span class="p">}</span><span class="o">&gt;</span>
5017+
<span class="o">&lt;</span><span class="nx">InteractiveDashboard</span> <span class="nx">dashboardId</span><span class="o">=</span><span class="p">{</span><span class="mi">1</span><span class="p">}</span> <span class="sr">/</span><span class="err">&gt;
5018+
</span> <span class="o">&lt;</span><span class="sr">/MetabaseProvider</span><span class="err">&gt;
5019+
</span><span class="p">);</span>
5020+
</code></pre></div></div>
5021+
5022+
<p>The plugins <code class="language-plaintext highlighter-rouge">getNoDataIllustration</code> and <code class="language-plaintext highlighter-rouge">getNoObjectIllustration</code> can only be used <a href="#plugin-scope">globally</a> on provider level.</p>
5023+
49975024
<h2 id="further-reading">Further reading</h2>
49985025

49995026
<ul>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {
2+
InteractiveDashboard,
3+
type MetabaseAuthConfig,
4+
MetabaseProvider,
5+
} from "@metabase/embedding-sdk-react";
6+
7+
const authConfig = {} as MetabaseAuthConfig;
8+
9+
export default function App() {
10+
// [<snippet example>]
11+
12+
const img_base64 = "..."; // base64-encoded image
13+
14+
const plugins = {
15+
getNoDataIllustration: () => img_base64,
16+
getNoObjectIllustration: () => img_base64,
17+
};
18+
19+
return (
20+
<MetabaseProvider authConfig={authConfig} pluginsConfig={plugins}>
21+
<InteractiveDashboard dashboardId={1} />
22+
</MetabaseProvider>
23+
);
24+
// [<endsnippet example>]
25+
}

0 commit comments

Comments
 (0)