Background
I am currently working with Nuxt and need to render some C3 charts in a vue component. C3 is calling Window
in the library so it throws an error on the C3 library import statement.
window is not defined
I know this is happening because it is server side rendering and it needs the browser to access window
. I also know I need to tell Nuxt
to allow this specific component, or part of the component to be rendered once it is in the browser.
I know C3 is built on top of D3 so I figured I would try to get that to load as well. I read that this is how you handle non server side rendered libraries.
Example Code
nuxt.config.js
plugins: [
{ src: '~plugins/d3', ssr: false },
{ src: '~plugins/c3', ssr: false },
],
build: {
vendor: ['d3', 'c3'],
},
/plugins/d3.js
import * as d3 from 'd3';
export default d3;
/plugins/c3.js
import c3 from 'c3';
export default c3;
Once I add these configurations I then move to the component I want to use them in,
import * as d3 from 'd3';
import c3 from 'c3';
import 'c3/c3.css';
This allows D3 to work. But when I import C3, it still throws the same error. So, I read that I should try this,
let c3 = null;
if (process.browser) {
c3 = require('c3');
}
That still does not work and C3 still throws an error. The new error is,
c3 is not defined.
I am rendering the C3 Charts in mount
mounted() {
const chart = c3.generate({
bindto: '#result-chart',
data: {
columns: [['data1', 30], ['data2', 120]],
type: 'pie',
},
});
},
Question
As I understand it now the if statement is working and allowing the page to continue rendering while skipping over the import. But now that it has skipped over it, how do I actually render the graph once the page is available to the browser? With my current implementation C3 is never in scope.
One more error I saw at one point was generator is undefined. I could not figure out where that was coming from, but just in case that helps.
From your description you import d3 and c3 twice, by using nuxt plugin and in your component. I think you could do it in the following way:
/plugins/chart.js
import * as d3 from 'd3';
import c3 from 'c3';
export default (ctx, inject) => {
inject("d3", d3);
inject("c3", c3);
};
/nuxt.config.js
plugins: [
{ src: "~/plugins/chart", ssr: false }
]
inject
method will insert d3 and c3 object into nuxt context, so that you can call them using this.$d3
and this.$c3
, for instance:
mounted() {
const chart = this.$c3.generate({
bindto: '#result-chart',
data: {
columns: [['data1', 30], ['data2', 120]],
type: 'pie',
},
});
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With