Skip to content

Instantly share code, notes, and snippets.

@WesThorburn
Last active December 25, 2023 12:05
Show Gist options
  • Save WesThorburn/7bcc930e9b48e002be67de4a00cc9420 to your computer and use it in GitHub Desktop.
Save WesThorburn/7bcc930e9b48e002be67de4a00cc9420 to your computer and use it in GitHub Desktop.
Use Chart.js with Nuxt v2.11.0

Use Chart.js with Nuxt v2.11.0

Line chart example

  • Run npm i vue-chartjs
  • Run npm i chart.js hchs-vue-charts
  • Create a file called chart.js and save it in the /plugins directory
  • Give chart.js the following contents
import Vue from 'vue'
import { Line } from 'vue-chartjs'

Vue.component('line-chart', {
	extends: Line,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})
  • Include line-chart.js in nuxt.config.js plugins like so
plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
],
  • Nuxt may have to be restarted at this point: npm run dev or nuxt
  • Use the line chart in your views like so:
  <template>
    <client-only>
        <line-chart :data="chartData"></line-chart>
    </client-only>
  </template>

  <script>
  export default {
    data() {
      return {
        chartData: {
          datasets: [{
            label: 'Title',
            data: [45, 55, 48, 35, 12]
          }]
        }
      };
    }
  }
  </script>
  • The chart will still render without client-only however the client side DOM tree will no longer match the server render and a console error will be shown.

Multi chart example

  • You can add multiple Chart.js types to your chart.js plugin file like so:
import Vue from 'vue'
import { Line } from 'vue-chartjs'
import { Pie } from 'vue-chartjs'

Vue.component('line-chart', {
	extends: Line,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})

Vue.component('pie-chart', {
	extends: Pie,
	props: ['data', 'options'],
	mounted () {
		this.renderChart(this.data, this.options)
	}
})
@shiouming
Copy link

BTW, may I know why it has to be implemented as Nuxt plugin rather than standard Vue component?

Initially I tried to implement the chart as Vue component, but the import statement (from vue-chartjs/legacy) seems to cause runtime error Cannot use import statement outside a module. When I search this error message in google, some responses in StackOverflow suggest to implement thing as Nuxt plugin instead of component. Eventually I landed on this page.

Copy link

ghost commented Aug 10, 2022

This worked well for me with everyone's tips. I had to remove <client-only>...</client-only> .. it was causing some screwy page rendering behavior. My charts were showing up only after saving my Nuxt project, but not on a page refresh. Removing that resolved the issue for me and I haven't noticed any problems or console errors without it

I'm using chartsjs in markdown files with embedded Vue components.

Thank you all for your input on this.

Below is what worked for me.


Relevant package versions:

"dependencies": {
  "vue": "^2.7.8",
  "nuxt": "^2.15.8",
  "chart.js": "^3.8.0",
  "vue-chartjs": "^4.1.1",
  "hchs-vue-charts": "^1.2.8",
},

/plugins/chart.js

import Vue from 'vue'
import { Line } from 'vue-chartjs/legacy'
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement
} from 'chart.js'

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement
)

Vue.component('line-chartjs', {
  extends: Line
})

nuxt.config.js

  plugins: [
    { src: '~/plugins/chart.js', mode: 'client' }
  ],

markdown file: (I'm doing some custom work here.. so the format will look a bit off)

---
title: Chart Test
description: 
---

<line-chart :labels="['a', 'b', 'c', 'd', 'e']" :datasets="[ { label:'a', data:[2,20,50,100,10] }, { label:'b', data:[25,2,15,80,60] }, { label:'c', data:[25,32,15,810,60] }, { label:'d', data:[215,2,15,80,610] } ]"></line-chart>

Custom component:

<template>
  <div class="myclass">
    <line-chartjs :chart-data="chartData" :chart-options="options" />
  </div>
</template>

@ghonchesefidi
Copy link

Good job. Thanks for this useful gist!

@ghonchesefidi
Copy link

I was able to fix the issue by changing the following code:

/plugins/chart.js :

import Vue from "vue";
import { Line } from "vue-chartjs/legacy";
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement,
} from "chart.js";

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
);

Vue.component("line-chart", {
  extends: Line,
});

nuxt.config.js:

plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
]

And then using the component as:

<template>
  <div>
    <client-only placeholder="Loading...">
      <line-chart
        :chart-options="options"
        :chart-data="data"
        :height="100"
        :width="300"
        chart-id="lineChart"
      />
    </client-only>
  </div>
</template>

Nuxt/vue/chart.js versions used:

{
   "chart.js": "^3.7.1",
   "vue-chartjs": "^4.0.6",
   "nuxt": "^2.15.7"
}

Thanks. This worked for me
"chart.js": "^3.9.1"
"vue-chartjs": "^4.1.1"
"nuxt": "^2.15.8"
"vue": "^2.6.14"

@yakserr
Copy link

yakserr commented Dec 14, 2022

I was able to fix the issue by changing the following code:
/plugins/chart.js :

import Vue from "vue";
import { Line } from "vue-chartjs/legacy";
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
  PointElement,
} from "chart.js";

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  PointElement,
  BarElement,
  CategoryScale,
  LinearScale,
  LineElement,
);

Vue.component("line-chart", {
  extends: Line,
});

nuxt.config.js:

plugins: [
	{src: '~/plugins/chart.js', mode: 'client'}
]

And then using the component as:

<template>
  <div>
    <client-only placeholder="Loading...">
      <line-chart
        :chart-options="options"
        :chart-data="data"
        :height="100"
        :width="300"
        chart-id="lineChart"
      />
    </client-only>
  </div>
</template>

Nuxt/vue/chart.js versions used:

{
   "chart.js": "^3.7.1",
   "vue-chartjs": "^4.0.6",
   "nuxt": "^2.15.7"
}

Thanks. This worked for me "chart.js": "^3.9.1" "vue-chartjs": "^4.1.1" "nuxt": "^2.15.8" "vue": "^2.6.14"

I got an error "Cannot find module 'vue-chartjs' from" do you know how to solve?
I use same version.

@Maelstromeous
Copy link

@ghost Thank you! You've saved my bacon here!

@vince015
Copy link

I'm getting this error just from installing
Screen Shot 2023-08-21 at 09 28 38

package.json

"dependencies": {
    "nuxt": "^2.15.8",
    "nuxt-buefy": "^0.4.13",
    "vue": "^2.6.14",
},
"devDependencies": {
    "node-sass": "^9.0.0",
    "sass": "^1.64.2",
    "sass-loader": "^10.4.1",
    "webpack": "^4.46.0"
}

@Ali-SaZa
Copy link

I'm getting this error:
ERROR in ./node_modules/vue-chartjs/dist/index.js 216:37
Module parse failed: Unexpected token (216:37)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const ref = shallowRef(null);
| const reforwardRef = (chartRef)=>{

            ref.value = chartRef?.chart;

| };
| expose({

package.json

"nuxt": "^2.15.8", "vue": "^2.7.10",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment