logoSemaphor

Vue

Embed Semaphor dashboard in your Vue app

Vue Component

This section outlines the process to render the Semaphor dashboard into your Vue app. If you don’t have a React project yet, you can set one up using Vite's guide.

1. Install Semaphor Package

Install the appropriate package based on your Vue version. Make sure the package version aligns with the Vue version listed in your package.json

npm i vue-semaphor

2. Obtain the Auth Token

Use the following code to fetch the AuthToken by passing your DASHBOARD_ID and DASHBOARD_SECRET, which you can find in the Semaphor console. In production, you will need to obtain the token from the server side.

const DASHBOARD_ID = 'd_cf007a8b-19bc-46ad-8787-2915445b7b86'; // Replace with your actual dashboard ID
const DASHBOARD_SECRET = 'ds_f32f0b30-b7e1-40f9-ba6a-9804a5b9d635'; // Replace with your actual dashboard secret
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token'; 
 
async function fetchToken() {
  try {
    const response = await fetch(TOKEN_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        dashboardId: DASHBOARD_ID,
        dashboardSecret: DASHBOARD_SECRET,
      }),
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
 
    const tk = await response.json();
    if (tk?.accessToken) {
      token.value = tk;
      //console.log('token', token.value);
    }
  } catch (error) {
    console.error('There was an error!', error);
  }
}

Security Note

Do not expose DASHBOARD_SECRET in client-side code in production. Use a backend service to fetch the token securely.

3. Render the Dashboard

App.vue
<template>
  <div>
    <Dashboard
      v-if="token"
      :token="token"
      :id="DASHBOARD_ID"
      currentTheme="system"
    />
  </div>
</template>

Full Code

IMPORTANT: Make sure to import vue-semaphor/dist/style.css either at the beginning of your component or in your global CSS file. Your dashboard will not render as expected without base styles.

Below is the complete example that you can copy and paste into your application.

App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { Dashboard, AuthToken, TStyle } from 'vue-semaphor';
import 'vue-semaphor/dist/style.css'; // IMPORTANT! Include the CSS file. This is the default  style, you can customize it.
 
const DASHBOARD_ID = 'd_cf007a8b-19bc-46ad-8787-2915445b7b86';
const DASHBOARD_SECRET = 'ds_f32f0b30-b7e1-40f9-ba6a-9804a5b9d635';
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
 
const token = ref<AuthToken | null>(null);
 
// Define your custom styles here. Refer to the themes and styles section of the doc.
const customStyle: TStyle = {
  default: {
    chart: {
      dataset: {
        backgroundColor: ['red', 'blue', 'green', 'purple'],
        borderColor: ['red', 'blue', 'green', 'purple'],
      },
    },
  },
};
 
function handleSemaphorEvent(event: unknown) {
  console.log('Event:', event);
}
 
async function fetchToken() {
  try {
    const response = await fetch(TOKEN_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        dashboardId: DASHBOARD_ID,
        dashboardSecret: DASHBOARD_SECRET,
      }),
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
 
    const tkn = await response.json();
    if (tkn?.accessToken) {
      token.value = tkn;
    }
  } catch (error) {
    console.error('There was an error!', error);
  }
}
fetchToken();
</script>
 
<template>
  <div></div>
  <div v-if="!token">Loading...</div>
  <Dashboard
    v-if="token"
    :token="token"
    :id="DASHBOARD_ID"
    :customStyle="customStyle"
    :currentTheme="'system'"
    :onEvent="handleSemaphorEvent"
  />
</template>

Nuxt

If you are using Nextjs, make sure to import the component dynamically as shown below.

App.vue
<template>
  <div v-if="!token">Loading...</div>
  <Dashboard v-if="token" :token="token" :id="DASHBOARD_ID" />
</template>
 
<script setup>
import { ref, onMounted } from 'vue';
 
// Dynamically import components
let Dashboard;
let AuthToken;
import('vue-semaphor').then((module) => {
  Dashboard = module.Dashboard;
  AuthToken = module.AuthToken;
});
 
// Constants
const DASHBOARD_ID = 'd_cf007a8b-19bc-46ad-8787-2915445b7b86';
const DASHBOARD_SECRET = 'ds_f32f0b30-b7e1-40f9-ba6a-9804a5b9d635';
const TOKEN_URL = 'https://semaphor.cloud/api/v1/token';
import 'vue-semaphor/dist/style.css';
 
// Reactive state
const token = ref(null);
 
// Fetch token
async function fetchToken() {
  try {
    const response = await fetch(TOKEN_URL, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        dashboardId: DASHBOARD_ID,
        dashboardSecret: DASHBOARD_SECRET,
      }),
    });
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
 
    const tk = await response.json();
    if (tk?.accessToken) {
      token.value = tk;
    }
  } catch (error) {
    console.error('There was an error!', error);
  }
}
 
// Lifecycle hook to fetch token on mount
onMounted(() => {
  fetchToken();
});
</script>

Integrate as Web Component

You can also use the Web Component directly inside of your Vue project. To do that, first get the semaphor package.

npm i semaphor

Create a wrapper component as shown below and then import that as a regular Vue component inside of your project.

dashboard.vue
<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { AuthToken, DashboardWC, Theme, TStyle } from 'semaphor';
 
// Define the custom element globally
if (!customElements.get('semaphor-dashboard')) {
  customElements.define('semaphor-dashboard', DashboardWC);
}
 
export default defineComponent({
  name: 'Dashboard',
  props: {
    id: {
      type: String,
      required: true,
    },
    token: {
      type: Object as PropType<AuthToken>,
      required: true,
    },
    currentTheme: {
      type: String as PropType<Theme>,
      required: false,
    },
    customStyle: {
      type: Object as PropType<TStyle>,
      required: false,
    },
    onEvent: {
      type: Function as PropType<Function>,
      default: () => {},
      required: false,
    },
  },
 
  beforeMount() {
    // Register the onEvent callback on the window object if it exists. The function name must correspond to the call back name in the code.
    const onEventFunctionName: string = this.onEvent?.name || 'onEvent';
    (window as any)[onEventFunctionName] = this.onEvent;
    // }
  },
);
</script>
 
<template>
  <semaphor-dashboard
    :authToken.prop="token"
    :id.prop="id"
    :currentTheme.prop="currentTheme"
    :customStyle.prop="customStyle"
    :onEvent.prop="onEvent"
  />
</template>

Key Considerations

  • Security Note: Keep the DASHBOARD_SECRET secure and do not expose it in client-side code in production. The examples above are for demonstration purposes. When deploying in production, obtain the authentication token from a secure, server-side environment.

On this page