There are some tutorials out there (e.g. https://medium.com/geekculture/chart-js-in-nuxt-js-how-to-implement-c255a2657b02) that show how to integrate Chart.js with an earlier version of Nuxt 3 or even Nuxt 2. But they do not work for various reasons. This tutorial e.g. https://dev.to/anggakswr/chart-js-in-nuxt-js-4hjf causes a 500 error:
Cannot read properties of undefined (reading 'component')
at ./plugins/charts.js:6:31
at async ViteNodeRunner.directRequest (./node_modules/vite-
node/dist/client.mjs:331:5)
Also, there are different approaches: one tutorial/example uses the "Nuxt plugin" way, another the "Nuxt component" way...
I tried the plugin-way based on the docu here: https://nuxt.com/docs/guide/directory-structure/plugins#vue-plugins:
// plugins/charts.js
import { Bar } from "vue-chartjs"
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(Bar)
})
But as soon as I run npm run dev
, I get this warning:
[Vue warn]: A plugin must either be a function or an object with an "install" function.
And later:
[Vue warn]: Failed to resolve component: BarChart
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
at <Chart onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >
Here is a codesandbox: https://codesandbox.io/p/sandbox/gracious-lumiere-88bw4j
What do I have to do to get (vue-)chart.js working?
Install chart.js
npm i vue-chartjs chart.js
There are two possible options you can implement it.
1. Globally register ChartJS
~/plugins/chartjs.ts
import { Chart, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
export default defineNuxtPlugin(() => {
Chart.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend)
})
Component usage example.
<script lang="ts" setup>
import { Bar } from 'vue-chartjs'
const chartData = ref({
labels: ['January', 'February', 'March', 'April', 'May'],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: [40, 20, 12, 50, 10],
},
],
})
const chartOptions = ref({
responsive: true,
maintainAspectRatio: false,
})
</script>
<template>
<div>
<Bar
:data="chartData"
:options="chartOptions"
/>
</div>
</template>
2. Manually register ChatJS
<script lang="ts" setup>
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
import { Bar } from 'vue-chartjs'
// Register
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)
const chartData = ref({
labels: ['January', 'February', 'March', 'April', 'May'],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: [40, 20, 12, 50, 10],
},
],
})
const chartOptions = ref({
responsive: true,
maintainAspectRatio: false,
})
</script>
<template>
<div>
<Bar
:data="chartData"
:options="chartOptions"
/>
</div>
</template>
<style scoped lang="css"></style>
Both will work depending on your needs.
Note: Due to tree-shaking, you will need to replace BarElement in the above imports with the relevant Element(s) if you require a different chart type.