Using WebComponents with Vue app
Vue supports Web Components out of the box. There are a few steps that you need to do to integrate the GoodData visualizations into the Vue app using WebComponents.
Load WebComponents library
Add a new <script>
tag to your main HTML file (index.html
in the project root folder).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
+ <script type="module" async src="{your-gd-server-url}/components/{workspace-id}.js?auth=sso"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
See the Load the library section on the WebComponents introduction page. Make sure to go through the Prerequisites and limitations section.
Configure Custom Elements
We need to tell Vue which elements are implemented using WebComponents. Otherwise, Vue will try to find Vue components by the tag name and will throw an error when not found.
Update your vite.config.js
file:
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [vue(), vueJsx()],
+ plugins: [vue({
+ template: {
+ compilerOptions: {
+ isCustomElement: tag => tag.startsWith('gd-')
+ }
+ }
+ }), vueJsx()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
Embed visualizations
You can now use gd-insight
and gd-dashboard
elements anywhere in your Vue template.
For example, in src/App.vue
file.
<template>
<gd-insight insight="my-insight-id" style="height:500px"></gd-insight>
<gd-dashboard dashboard="my-dashboard-id"></gd-dashboard>
</template>
You can copy the insight id and dashboard id from the URL bar of your web browser, from the Analyze and Dashboards pages respectively. At this point you should see an insight and a dashboard rendering on the screen.
We set the height of the gd-insight
to a static value as it's expecting a flex layout and would collapse to a 0
height
otherwise.
Define dashboardId and insightId dynamically
You can use attribute binding to define the IDs dynamically from the Vue component code.
<script setup>
+ const insightId = 'my-insight-id';
+ const dashboardId = 'my-dashboard-id'
</script>
<template>
- <gd-insight insight="my-insight-id" style="height:500px"></gd-insight>
- <gd-dashboard dashboard="my-dashboard-id"></gd-dashboard>
+ <gd-insight :insight="insightId" style="height:500px"></gd-insight>
+ <gd-dashboard :dashboard="dashboardId"></gd-dashboard>
</template>
Add event listeners
Both gd-insight
and gd-dashboard
are dispatching custom events.
Insight event listener
In case of gd-insight
you can use the Vue event binding syntax.
<script setup>
const insightId = 'my-insight-id';
const dashboardId = 'my-dashboard-id';
+ const onInsightLoaded = e => console.log(e.detail);
</script>
<template>
- <gd-insight :insight="insightId" style="height:500px"></gd-insight>
+ <gd-insight :insight="insightId" @insightLoaded="onInsightLoaded" style="height:500px"></gd-insight>
<gd-dashboard :dashboard="dashboardId"></gd-dashboard>
</template>
Read more about Insight events.
Dashboard event listener
The setup for gd-dashboard
is more complicated, as our event names do not follow the Vue naming convention. You would
need to obtain a reference to the DOM object and add event listeners directly. Keep in mind that you
also need to remove the listeners on the component unmount.
<script setup>
import {onMounted, onUnmounted, ref} from "vue";
const insightId = 'my-insight-id';
const dashboardId = 'my-dashboard-id';
const onInsightLoaded = e => console.log(e.detail);
+ const onDashboardLoaded = e => console.log(e.detail);
+ const dashboard = ref(null);
+ const EVENT_NAME = 'GDC.DASH/EVT.INITIALIZED';
+
+ onMounted(() => {
+ dashboard.value?.addEventListener(EVENT_NAME, onDashboardLoaded);
+ })
+
+ onUnmounted(() => {
+ dashboard.value?.removeEventListener(EVENT_NAME, onDashboardLoaded);
+ })
</script>
<template>
<gd-insight :insight="insightId" @insightLoaded="onInsightLoaded" style="height:500px"></gd-insight>
- <gd-dashboard :dashboard="dashboardId"></gd-dashboard>
+ <gd-dashboard :dashboard="dashboardId" ref="dashboard"></gd-dashboard>
</template>
[Read more about Dashboard events]webcomponents_dashboard#supported-events.