vue-apexcharts icon indicating copy to clipboard operation
vue-apexcharts copied to clipboard

Reference error - Window is not defined

Open Rednas83 opened this issue 4 years ago • 20 comments

Just trying vue-apexchart, but I get "window is not defined" after exactly folowing the installation instructions.

Tried to reproduce it with a codepen but I got an empty window https://codepen.io/rednas83/pen/BaLRORL

I based the codepen on this one, which is following a different approach? https://codepen.io/lukaszflorczak/pen/yrpWgZ

Any idea what could be the problem?

Also I think a working codepen could be usefull. Perhaps add a link on the github page?

Rednas83 avatar Dec 17 '20 10:12 Rednas83

Same issue in React. Works well in browser, but fails to compile the code even in development stage, because for SSR {window} is not defined.

hyperchance avatar Jan 13 '21 03:01 hyperchance

any update on this?

RahmanQureshi avatar Jun 16 '21 02:06 RahmanQureshi

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

RahmanQureshi avatar Jun 17 '21 19:06 RahmanQureshi

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

entity avatar Mar 19 '22 10:03 entity

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

Same problem, does anyone have a solution please? :)

KillianLeroux avatar Jun 27 '22 09:06 KillianLeroux

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

I'm facing the same issue here but with Vue, are there any similar alternatives to this but for Vue instead?

Same problem, does anyone have a solution please? :)

I got it working, sharing in case it helps future Googlers. 😄

<template>
    <apex-charts />
</template>

<script setup>
const ApexCharts = defineAsyncComponent(() => import("vue3-apexcharts"));
</script>

entity avatar Jun 27 '22 09:06 entity

Im working with Quasar Framework that use Vue3

so, i have this boot.js

import VueApexCharts from "vue3-apexcharts";
import { boot } from "quasar/wrappers";

export default boot(({ app }) => {
  app.use(VueApexCharts);
});

and i got Windows is not defined when try to use SSR, any idea about how implement this Globally?

 const ApexCharts = defineAsyncComponent(() => import("vue3-apexcharts"));`

nullr00tbyte avatar Aug 22 '22 20:08 nullr00tbyte

@nullr00tbyte

First, you need to declare in your quasar.config.js

    boot: [
      {
        server: false,
        path: '<your-boot-file-name>'
      }
    ],

See https://quasar.dev/quasar-cli-vite/boot-files

Then you need to wrap apexchart component with <q-no-ssr> so it only render on client side. Otherwise you will get Cannot read properties of null (reading 'nodeType') error.

<q-no-ssr>
  <apexchart type="donut" :options="donutOptions" :series="series"></apexchart>
</q-no-ssr>

yanisalfian avatar Feb 03 '23 11:02 yanisalfian

heychazza

Any workarounds for vue2?

vinosamari avatar Apr 18 '23 12:04 vinosamari

cannot use useRef, it is always null

aekiratli avatar Jul 31 '23 22:07 aekiratli

getting the same issue right now in my nuxt project

mbunico avatar Oct 13 '23 07:10 mbunico

heychazza

Any workarounds for vue2?

im getting same issue for vue2 . Any workaround or things to refactor?

anik8naik avatar Dec 20 '23 07:12 anik8naik

cannot use useRef, it is always null

You can wrap the component through rendering it via dynamic (i.e lazy loading) in the page.js instead of using dynamic in the apexchart component itself, then you can able to set the ref and it will never be null.

Waishnav avatar Jan 03 '24 07:01 Waishnav

any solution ?

JyotiKM29 avatar Jan 06 '24 11:01 JyotiKM29

Just tried it again and with a little help of copilot I managed to find a working solution for nuxt users. I also rewritten it for the composition api with the script setup tag.

<template>
  <component :is="chartComponent" width="500" type="bar" :options="chartOptions" :series="series" />
</template>

<script setup lang="ts">
let chartComponent = shallowRef(null);
onMounted(async () => {
  const VueApexCharts = (await import('vue3-apexcharts')).default;
  chartComponent.value = VueApexCharts;
});

const chartOptions = ref({
  chart: {
    id: "vuechart-example",
  },
  xaxis: {
    categories: [1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998],
  },
})

const series = ref([
  {
    name: "series-1",
    data: [30, 40, 35, 50, 49, 60, 70, 92],
  },
])
</script>

@brianlagunas Can you also add this solution to the docs for nuxt users?

Rednas83 avatar Jan 07 '24 10:01 Rednas83

this was helpful... it worked for vue2 EOL version 2.7.16.

anik8iazi avatar Jan 08 '24 05:01 anik8iazi

So yeah after implementing this solution i am getting this error now

Error 1:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'toString')

Call Stack
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:410839)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:406572)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:37170)
t.eval [as create]
node_modules/apexcharts/dist/apexcharts.common.js (6:4476)
eval
node_modules/apexcharts/dist/apexcharts.common.js (14:36561)
new Promise
<anonymous>
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:21686)

So this error occurs in development and in production server this works fine.

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

This only helped solving the error in production and compilation error. I am still facing issues in development server.

Error 2: I am also getting this strange type error and I don't know how to sort this out. Type '{ series: { name: string; data: number[]; }[]; chart: { height: number; zoom: { enabled: boolean; }; }; dataLabels: { enabled: boolean; }; stroke: { width: number[]; curve: string; dashArray: number[]; }; title: { text: string; align: string; }; ... 4 more ...; grid: { ...; }; }' is not assignable to type 'ApexOptions'. The types of 'stroke.curve' are incompatible between these types. Type 'string' is not assignable to type '"straight" | "smooth" | "stepline" | "monotoneCubic" | ("straight" | "smooth" | "stepline" | "monotoneCubic")[] | undefined'.ts(2322) react-apexcharts.d.ts(29, 5): The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Props'

Actual Code, This is nextJS.

`
import React, { useState } from "react";
// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
interface LineChartProps {
    invoiceCount: number[];
    jobCount: number[];
}
// Function to generate the last 12 days including today
const generateLast12Days = () => {
    const today = new Date();
    const last12Days = [];
    for (let i = 14; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(today.getDate() - i);
        last12Days.push(date);
    }
    return last12Days;
};

// Function to format date as 'dd MMM'
const formatDate = (date: Date) => {
    const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'short' };
    return new Intl.DateTimeFormat('en-US', options).format(date);
};

export const LineChart2Weeks: React.FC<LineChartProps> = ({ invoiceCount, jobCount }: LineChartProps) => {
    const [chartOption, setChartOption] = useState({
        options: {
            series: [{
                name: "Session Duration",
                data: invoiceCount
            },
            {
                name: "Page Views",
                data: jobCount
            }
            ],
            chart: {
                height: 350,
                zoom: {
                    enabled: false
                },
            },
            dataLabels: {
                enabled: false
            },
            stroke: {
                width: [5, 7, 5],
                curve: 'straight',
                dashArray: [0, 8, 5]
            },
            title: {
                text: 'Page Statistics',
                align: 'left'
            },
            legend: {
                tooltipHoverFormatter: function (val: any, opts: any) {
                    return val + ' - <strong>' + opts.w.globals.series[opts.seriesIndex][opts.dataPointIndex] + '</strong>'
                }
            },
            markers: {
                size: 0,
                hover: {
                    sizeOffset: 6
                }
            },
            xaxis: {
                categories: ['01 Jan', '02 Jan', '03 Jan', '04 Jan', '05 Jan', '06 Jan', '07 Jan', '08 Jan', '09 Jan',
                    '10 Jan', '11 Jan', '12 Jan'
                ],
            },
            tooltip: {
                y: [
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val;
                            }
                        }
                    }
                ]
            },
            grid: {
                borderColor: '#f1f1f1',
            }
        }
    }
    )
    return (

        <div className="mt-10">
            <h1>2-Weeks Statistics</h1>
            <Chart
                options={chartOption.options}
                series={chartOption.options.series}
                type="line"
                width="500"
            />
        </div>

    )
}
`

Ni9Logic avatar Feb 18 '24 13:02 Ni9Logic

So yeah after implementing this solution i am getting this error now

Error 1:

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'toString')

Call Stack
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:410839)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (6:406572)
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:37170)
t.eval [as create]
node_modules/apexcharts/dist/apexcharts.common.js (6:4476)
eval
node_modules/apexcharts/dist/apexcharts.common.js (14:36561)
new Promise
<anonymous>
t.value
node_modules/apexcharts/dist/apexcharts.common.js (14:21686)

So this error occurs in development and in production server this works fine.

meh, found solutions in other threads. for those curious add packages react-apexcharts and apexcharts, then use this import (for nextjs apps):

// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const ApexCharts = dynamic(() => import('react-apexcharts'), { ssr: false });

This only helped solving the error in production and compilation error. I am still facing issues in development server.

Error 2: I am also getting this strange type error and I don't know how to sort this out. Type '{ series: { name: string; data: number[]; }[]; chart: { height: number; zoom: { enabled: boolean; }; }; dataLabels: { enabled: boolean; }; stroke: { width: number[]; curve: string; dashArray: number[]; }; title: { text: string; align: string; }; ... 4 more ...; grid: { ...; }; }' is not assignable to type 'ApexOptions'. The types of 'stroke.curve' are incompatible between these types. Type 'string' is not assignable to type '"straight" | "smooth" | "stepline" | "monotoneCubic" | ("straight" | "smooth" | "stepline" | "monotoneCubic")[] | undefined'.ts(2322) react-apexcharts.d.ts(29, 5): The expected type comes from property 'options' which is declared here on type 'IntrinsicAttributes & Props'

Actual Code, This is nextJS.

`
import React, { useState } from "react";
// https://github.com/apexcharts/react-apexcharts/issues/240
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('react-apexcharts'), { ssr: false });
interface LineChartProps {
    invoiceCount: number[];
    jobCount: number[];
}
// Function to generate the last 12 days including today
const generateLast12Days = () => {
    const today = new Date();
    const last12Days = [];
    for (let i = 14; i >= 0; i--) {
        const date = new Date(today);
        date.setDate(today.getDate() - i);
        last12Days.push(date);
    }
    return last12Days;
};

// Function to format date as 'dd MMM'
const formatDate = (date: Date) => {
    const options: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'short' };
    return new Intl.DateTimeFormat('en-US', options).format(date);
};

export const LineChart2Weeks: React.FC<LineChartProps> = ({ invoiceCount, jobCount }: LineChartProps) => {
    const [chartOption, setChartOption] = useState({
        options: {
            series: [{
                name: "Session Duration",
                data: invoiceCount
            },
            {
                name: "Page Views",
                data: jobCount
            }
            ],
            chart: {
                height: 350,
                zoom: {
                    enabled: false
                },
            },
            dataLabels: {
                enabled: false
            },
            stroke: {
                width: [5, 7, 5],
                curve: 'straight',
                dashArray: [0, 8, 5]
            },
            title: {
                text: 'Page Statistics',
                align: 'left'
            },
            legend: {
                tooltipHoverFormatter: function (val: any, opts: any) {
                    return val + ' - <strong>' + opts.w.globals.series[opts.seriesIndex][opts.dataPointIndex] + '</strong>'
                }
            },
            markers: {
                size: 0,
                hover: {
                    sizeOffset: 6
                }
            },
            xaxis: {
                categories: ['01 Jan', '02 Jan', '03 Jan', '04 Jan', '05 Jan', '06 Jan', '07 Jan', '08 Jan', '09 Jan',
                    '10 Jan', '11 Jan', '12 Jan'
                ],
            },
            tooltip: {
                y: [
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val + " (created)"
                            }
                        }
                    },
                    {
                        title: {
                            formatter: function (val: any) {
                                return val;
                            }
                        }
                    }
                ]
            },
            grid: {
                borderColor: '#f1f1f1',
            }
        }
    }
    )
    return (

        <div className="mt-10">
            <h1>2-Weeks Statistics</h1>
            <Chart
                options={chartOption.options}
                series={chartOption.options.series}
                type="line"
                width="500"
            />
        </div>

    )
}
`

If someone else faces this issues this is how I fixed it. It was basically saying that type of curve is not correct. stroke: { width: [5, 7, 5], curve: 'smooth', dashArray: [0, 8, 5] },

Ni9Logic avatar Feb 18 '24 14:02 Ni9Logic

I encountered this problem with React + next.js, I had to add 'use client' at the top of my component file.

malgorzata-stefanowicz avatar Feb 20 '24 09:02 malgorzata-stefanowicz

I encountered the same issue and resolved it with the solution provided above.

FarhanAnwar523 avatar Feb 22 '24 12:02 FarhanAnwar523