charting-library-examples icon indicating copy to clipboard operation
charting-library-examples copied to clipboard

ReferenceError: window is not defined

Open rodrigopluz opened this issue 2 years ago • 3 comments

Describe the bug

Hello, my application is written in nextjs with typescript, and I'm trying to use the react-typescript example, available in the repository. However it is returning this error below, when I call the new widget(widgetOptions)

Captura de tela de 2022-09-13 09-01-17

Additional context

My component is written like this:

import React, { createRef } from 'react';
import { Content, Title } from './styles';
import {
  widget,
  LanguageCode,
  ResolutionString,
  IChartingLibraryWidget,
  ChartingLibraryWidgetOptions,
} from '../../../public/charting_library/charting_library';

export interface ChartContainerProps {
  symbol: ChartingLibraryWidgetOptions['symbol'];
  interval: ChartingLibraryWidgetOptions['interval'];

  // BEWARE: no trailing slash is expected in feed URL
  datafeedUrl: string;
  libraryPath: ChartingLibraryWidgetOptions['library_path'];
  chartsStorageUrl: ChartingLibraryWidgetOptions['charts_storage_url'];
  chartsStorageApiVersion: ChartingLibraryWidgetOptions['charts_storage_api_version'];
  clientId: ChartingLibraryWidgetOptions['client_id'];
  userId: ChartingLibraryWidgetOptions['user_id'];
  fullscreen: ChartingLibraryWidgetOptions['fullscreen'];
  autosize: ChartingLibraryWidgetOptions['autosize'];
  studiesOverrides: ChartingLibraryWidgetOptions['studies_overrides'];
  container: ChartingLibraryWidgetOptions['container'];
}

export interface ChartContainerState {}

const getLanguageFromURL = (): LanguageCode | null => {
  const regex = new RegExp('[\\?&]lang=([^&#]*)');
  const results = regex.exec(location.search);

  return results === null
    ? null
    : decodeURIComponent(results[1].replace(/\+/g, ' ')) as LanguageCode;
};

const TradingGraph = () => {
  const defaultProps: Omit<ChartContainerProps, 'container'> = {
    symbol: 'AAPL',
    interval: 'D' as ResolutionString,
    datafeedUrl: 'https://demo_feed.tradingview.com',
    libraryPath: '/charting_library/',
    chartsStorageUrl: 'https://saveload.tradingview.com',
    chartsStorageApiVersion: '1.1',
    clientId: 'tradingview.com',
    userId: 'public_user_id',
    fullscreen: false,
    autosize: true,
    studiesOverrides: {},
  };

  let tvWidgets: IChartingLibraryWidget | null = null;
  let ref: React.RefObject<HTMLDivElement> = createRef();

  const widgetOptions: ChartingLibraryWidgetOptions = {
    ...defaultProps,
    // tslint:disable-next-line:no-any
    datafeed: defaultProps.datafeedUrl as any,
    locale: getLanguageFromURL || 'en',
    container: ref.current as HTMLElement,
    enabled_features: ['study_templates'],
    disabled_features: ['use_localstorage_for_settings'],
  };

  if (typeof window !== 'undefined') {
    const tvWidget = new widget(widgetOptions);
    console.log(tvWidget);

    tvWidgets = tvWidget;
    tvWidget.onChartReady(() => {
      tvWidget.headerReady().then(() => {
        const button = tvWidget.createButton();
        button?.setAttribute(
          'title',
          'Click to show a notification popup',
        );
        button?.classList.add('apply-common-tooltip');
        button?.addEventListener('click', () =>
          tvWidget.showNoticeDialog({
            title: 'Notification',
            body: 'TradingView Charting Library API works correctly',
            callback: () => {
              console.log('Noticed!');
            },
          }),
        );
        // button?.innerHTML = 'Check API';
      });
    });

    if (tvWidgets !== null) {
      tvWidgets.remove();
      tvWidgets = null;
    }
  }

  return (
    <Content className="row">
      <Title>Graphics</Title>
      <div ref={ref} className={'TVChartContainer'} />
    </Content>
  );
};

export default TradingGraph;

And even using the given example syntax, it's the same error it returns. and this bug is the same for nextjs-javascript example

rodrigopluz avatar Sep 13 '22 21:09 rodrigopluz

Make sure you're adding the

And depending on your version of Next.js you may need to use the custom Script tag instead:

import Document, { Html, Head, Main, NextScript } from 'next/document'
import Script from 'next/script'

class MyDocument extends Document {
  render() {
    return (
      <Html>
        <Head>
          <Script
            src="/datafeeds/udf/dist/bundle.js"
            strategy="beforeInteractive"
          ></Script>
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

export default MyDocument

tlrjs avatar Sep 14 '22 20:09 tlrjs

Hello, @tjshipe

Unfortunately it didn't work the way you suggested. It continues to return the same error, when I apply the call and the example within my application. I also tested with different versions of next.js in my project and the same error is shown.

The versions of next.js in my project were tested - 12.1.0; 12.1.6; 12.2.4

the code below is from my project's _document.tsx

import Script from 'next/script';
import Document, {
  Html,
  Head,
  Main,
  NextScript,
} from 'next/document';
import { ServerStyleSheet } from 'styled-components';

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="pt-BR">
        <Head>
          <Script
            id="graphic"
            strategy="beforeInteractive"
            src="/datafeeds/udf/dist/bundle.js"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

rodrigopluz avatar Sep 19 '22 13:09 rodrigopluz

@rodrigopluz How/where are you importing the TradingGraph component?

tlrjs avatar Sep 21 '22 15:09 tlrjs

@rodrigopluz were you able to fix this problem? I'm having the same issue if anyone can help out. I am trying to follow this nextjs example.

My chart_library and datafeeds folders are located in the root directory under public/static

My _document.js has this

...
<script
              type="text/javascript"
              src="public/static/charting_library/charting_library.js">
          </script>
<script src="public/static/datafeeds/udf/dist/bundle.js"></script>

any ideas on why I get the same error?

0xAskar avatar Nov 22 '22 18:11 0xAskar

Hello @0xAskar, yes I managed to solve the problem as follows.

In the _document.tsx file I imported

import Script from 'next/script';

and where do you call the <script ...

you change to

<Script strategy="afterInteractive" src="/static/datafeeds/udf/dist/bundle.js" />

and in my TradingGraph.tsx component, I wrote it like this.

import React, { createRef } from 'react';
import { Content } from './styles';

import {
  widget,
  Timezone,
  ThemeName,
  LanguageCode,
  ResolutionString,
  IChartingLibraryWidget,
  ChartingLibraryWidgetOptions,
} from '../../../public/static/charting_library';

const getLanguageFromURL = (): LanguageCode | null => {
  const regex = new RegExp('[\\?&]lang=([^&#]*)');
  const results = regex.exec(location.search);
  return results === null
    ? null
    : (decodeURIComponent(
        results[1].replace(/\+/g, ' '),
      ) as LanguageCode);
};

export class TradingGraph extends React.PureComponent {
  tvWidget: IChartingLibraryWidget | null = null;
  ref: React.RefObject<HTMLDivElement> = createRef();

  componentDidMount() {
    const widgetOptions = {
      symbol: 'ADBE',
      datafeed: new (
        window as any
      ).Datafeeds.UDFCompatibleDatafeed(
        'https://demo_feed.tradingview.com',
      ),
      interval: '1D' as ResolutionString,
      timezone: 'America/Sao_Paulo' as Timezone,
      container: this.ref.current as HTMLElement,
      library_path: '/static/charting_library/',
      locale: getLanguageFromURL() || ('pt' as LanguageCode),
      disabled_features: [''],
      enabled_features: [''],
      charts_storage_api_version:
        '1.4' as ChartingLibraryWidgetOptions['charts_storage_api_version'],
      client_id: 'tradingview.com',
      theme: 'Dark' as ThemeName,
      user_id: 'public_user_id',
    };

    const tvWidget = new widget(widgetOptions);
    this.tvWidget = tvWidget;

    tvWidget.onChartReady(() => {
      tvWidget.headerReady().then(() => {
        const button = tvWidget.createButton();
        button.setAttribute(
          'title',
          'Click to show a notification popup',
        );
        button.classList.add('apply-common-tooltip');
        button.addEventListener('click', () =>
          tvWidget.showNoticeDialog({
            title: 'Notification',
            body: 'TradingView Charting Library API works correctly',
            callback: () => {
            },
          }),
        );
        button.innerHTML = 'Check API';
      });
    });
  }

  componentWillUnmount() {
    if (this.tvWidget !== null) {
      this.tvWidget.remove();
      this.tvWidget = null;
    }
  }

  render() {
    return (
      <Content>
        <div ref={this.ref} className={'TVChartContainer'} />
      </Content>
    );
  }
}

rodrigopluz avatar Nov 22 '22 18:11 rodrigopluz

@rodrigopluz thanks for the response! the script tag fixed it, but now i seem to get a datafeed udf undefined error. Did you encounter this before? I will also attached my code image

import * as React from 'react';
import styles from './index.module.css';
import { widget, version } from '../../public/static/charting_library';

function getLanguageFromURL() {
	const regex = new RegExp('[\\?&]lang=([^&#]*)');
	const results = regex.exec(window.location.search);
	return results === null ? null : decodeURIComponent(results[1].replace(/\+/g, ' '));
}

export class TVChartContainer extends React.PureComponent {
	static defaultProps = {
		symbol: 'AAPL',
		interval: 'D',
		datafeedUrl: 'https://demo_feed.tradingview.com',
		libraryPath: '/static/charting_library/',
		chartsStorageUrl: 'https://saveload.tradingview.com',
		chartsStorageApiVersion: '1.1',
		clientId: 'tradingview.com',
		userId: 'public_user_id',
		fullscreen: false,
		autosize: true,
		studiesOverrides: {},
	};

	tvWidget = null;

	constructor(props) {
		super(props);

		this.ref = React.createRef();
	}

	componentDidMount() {
		const widgetOptions = {
			symbol: this.props.symbol,
			// BEWARE: no trailing slash is expected in feed URL
			datafeed: new window.Datafeeds.UDFCompatibleDatafeed(this.props.datafeedUrl),
			interval: this.props.interval,
			container: this.ref.current,
			library_path: this.props.libraryPath,

			locale: getLanguageFromURL() || 'en',
			disabled_features: ['use_localstorage_for_settings'],
			enabled_features: ['study_templates'],
			charts_storage_url: this.props.chartsStorageUrl,
			charts_storage_api_version: this.props.chartsStorageApiVersion,
			client_id: this.props.clientId,
			user_id: this.props.userId,
			fullscreen: this.props.fullscreen,
			autosize: this.props.autosize,
			studies_overrides: this.props.studiesOverrides,
		};

		const tvWidget = new widget(widgetOptions);
		this.tvWidget = tvWidget;

		tvWidget.onChartReady(() => {
			tvWidget.headerReady().then(() => {
				const button = tvWidget.createButton();
				button.setAttribute('title', 'Click to show a notification popup');
				button.classList.add('apply-common-tooltip');
				button.addEventListener('click', () => tvWidget.showNoticeDialog({
					title: 'Notification',
					body: 'TradingView Charting Library API works correctly',
					callback: () => {
						console.log('Noticed!');
					},
				}));

				button.innerHTML = 'Check API';
			});
		});
	}

	componentWillUnmount() {
		if (this.tvWidget !== null) {
			this.tvWidget.remove();
			this.tvWidget = null;
		}
	}

	render() {
		return (	
			<>
				<header className={styles.VersionHeader}>
					<h1>TradingView Charting Library and Next.js Integration Example</h1>
				</header>
				<div ref={this.ref} className={styles.TVChartContainer} />
			</>
		);
	}
}

0xAskar avatar Nov 22 '22 18:11 0xAskar

try this, in your component call

const TradingGraph: any = dynamic(
  () =>
    import('../../components/TradingGraph').then(
      module => module.TradingGraph as any,
    ),
  {
    ssr: false,
  },
);

rodrigopluz avatar Nov 22 '22 18:11 rodrigopluz

@rodrigopluz So, I do already have this in my component. What is important to note is that I updated the error above as well to include the datafeed error. I had to update my import to fix the other problem, but I'm unsure why the datafeedUrl is undefined. Do you use the demo trading feed url as well and it works? if so, do you see any other problem. I'll add my component code in here.

import dynamic from 'next/dynamic';

const TVChartContainer = dynamic(
	() =>
		import('../../components/TVChartContainer').then(mod => mod.TVChartContainer),
	{ ssr: false },
);

const Index = () => {
	return (<TVChartContainer />);
};

export default Index;

then here's the component code

import * as React from 'react';
import styles from './index.module.css';
import { widget, version } from '../../public/static/charting_library';

function getLanguageFromURL() {
	const regex = new RegExp('[\\?&]lang=([^&#]*)');
	const results = regex.exec(window.location.search);
	return results === null ? null : decodeURIComponent(results[1].replace(/\+/g, ' '));
}

export class TVChartContainer extends React.PureComponent {
	static defaultProps = {
		symbol: 'AAPL',
		interval: 'D',
		datafeedUrl: 'https://demo_feed.tradingview.com',
        // datafeedUrl: "/static/datafeeds/",
		libraryPath: '/static/charting_library/',
		chartsStorageUrl: 'https://saveload.tradingview.com',
		chartsStorageApiVersion: '1.1',
		clientId: 'tradingview.com',
		userId: 'public_user_id',
		fullscreen: false,
		autosize: true,
		studiesOverrides: {},
	};

	tvWidget = null;

	constructor(props) {
		super(props);

		this.ref = React.createRef();
	}

	componentDidMount() {
		const widgetOptions = {
			symbol: this.props.symbol,
			// BEWARE: no trailing slash is expected in feed URL
			datafeed: new window.Datafeeds.UDFCompatibleDatafeed(this.props.datafeedUrl),
			interval: this.props.interval,
			container: this.ref.current,
			library_path: this.props.libraryPath,

			locale: getLanguageFromURL() || 'en',
			disabled_features: ['use_localstorage_for_settings'],
			enabled_features: ['study_templates'],
			charts_storage_url: this.props.chartsStorageUrl,
			charts_storage_api_version: this.props.chartsStorageApiVersion,
			client_id: this.props.clientId,
			user_id: this.props.userId,
			fullscreen: this.props.fullscreen,
			autosize: this.props.autosize,
			studies_overrides: this.props.studiesOverrides,
		};
        console.log(new widget())
		const tvWidget = new widget(widgetOptions);
		this.tvWidget = tvWidget;

		tvWidget.onChartReady(() => {
			tvWidget.headerReady().then(() => {
				const button = tvWidget.createButton();
				button.setAttribute('title', 'Click to show a notification popup');
				button.classList.add('apply-common-tooltip');
				button.addEventListener('click', () => tvWidget.showNoticeDialog({
					title: 'Notification',
					body: 'TradingView Charting Library API works correctly',
					callback: () => {
						console.log('Noticed!');
					},
				}));

				button.innerHTML = 'Check API';
			});
		});
	}

	componentWillUnmount() {
		if (this.tvWidget !== null) {
			this.tvWidget.remove();
			this.tvWidget = null;
		}
	}

	render() {
		return (	
			<>
				<header className={styles.VersionHeader}>
					<h1>TradingView Charting Library and Next.js Integration Example</h1>
				</header>
				<div ref={this.ref} className={styles.TVChartContainer} />
			</>
		);
	}
}

0xAskar avatar Nov 22 '22 19:11 0xAskar

Where do you place the chart_library and datafeeds library as well? @rodrigopluz I'm just confused why this is causing the problem

0xAskar avatar Nov 22 '22 19:11 0xAskar

if you look at the example I gave, I'm not using the static defaultProps, and all the parameters I pass in the const widgetOptions itself.

try this way.

rodrigopluz avatar Nov 22 '22 19:11 rodrigopluz

Okay I will try your way @rodrigopluz . Give me one second. Thank you for your help

0xAskar avatar Nov 22 '22 19:11 0xAskar

I refer to it that way

const widgetOptions = {
       symbol: 'AAPL',
       interval: 'D',
       datafeedUrl: 'https://demo_feed.tradingview.com',
       libraryPath: '/static/charting_library/',
       chartsStorageUrl: 'https://saveload.tradingview.com',
       chartsStorageApiVersion: '1.1',
       clientId: 'tradingview.com',
       userId: 'public_user_id',
       fullscreen: false,
       autosize: true,
       studiesOverrides: {},
}

rodrigopluz avatar Nov 22 '22 19:11 rodrigopluz

okay @rodrigopluz if you want to talk in the TradingView Discord. If not, we made some progress but am still stuck. My screen is just black, no errors. Here are all the files that are relevant. I'm using the code you sent above. Also to note, my charting_library and datafeeds library are in the public/static libraries. Do you see anything that could cause the blank screen?

here is the component code

import React, { createRef } from 'react';

import {
  widget,
  Timezone,
  ThemeName,
  LanguageCode,
  ResolutionString,
  IChartingLibraryWidget,
  ChartingLibraryWidgetOptions,
} from '../../public/static/charting_library';

const getLanguageFromURL = ()=> {
  const regex = new RegExp('[\\?&]lang=([^&#]*)');
  const results = regex.exec(location.search);
  return results === null
    ? null
    : (decodeURIComponent(
        results[1].replace(/\+/g, ' '),
      ));
};

export class TradingGraph extends React.PureComponent {
  tvWidget = null;
  ref= createRef();

  componentDidMount() {
    const widgetOptions = {
      symbol: 'ADBE',
      datafeed: new (
        window 
      ).Datafeeds.UDFCompatibleDatafeed(
        'https://demo_feed.tradingview.com',
      ),
      interval: '1D',
      timezone: 'America/Sao_Paulo',
      container: this.ref.current,
      library_path: '/static/charting_library/',
      locale: getLanguageFromURL() || ('pt'),
      disabled_features: [''],
      enabled_features: [''],
      charts_storage_api_version:
        '1.4',
      client_id: 'tradingview.com',
      theme: 'Dark',
      user_id: 'public_user_id',
    };

    const tvWidget = new widget(widgetOptions);
    this.tvWidget = tvWidget;

    tvWidget.onChartReady(() => {
      tvWidget.headerReady().then(() => {
        const button = tvWidget.createButton();
        button.setAttribute(
          'title',
          'Click to show a notification popup',
        );
        button.classList.add('apply-common-tooltip');
        button.addEventListener('click', () =>
          tvWidget.showNoticeDialog({
            title: 'Notification',
            body: 'TradingView Charting Library API works correctly',
            callback: () => {
            },
          }),
        );
        button.innerHTML = 'Check API';
      });
    });
  }

  componentWillUnmount() {
    if (this.tvWidget !== null) {
      this.tvWidget.remove();
      this.tvWidget = null;
    }
  }

  render() {
    return (
      <div>
        <div ref={this.ref} className={'TVChartContainer'} />
      </div>
    );
  }
}

there is also the page code i already sent above (unchanged).

here's my document.js code

import Document, { Html, Head, Main, NextScript } from "next/document";
import Script from 'next/script';

class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <script
            async
            src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS}`}
          />
          {/* <script
              type="text/javascript"
              src="public/static/charting_library/charting_library.js">
          </script> */}
          <Script src="/static/datafeeds/udf/dist/bundle.js"/>
          .... (other code)
        </noscript>
      </Html>
    );
  }
}

export default MyDocument;

0xAskar avatar Nov 22 '22 19:11 0xAskar

what I was referring to, you change your code, it would be just that part

const widgetOptions = {
        symbol: 'AAPL',
        interval: 'D',
        datafeedUrl: 'https://demo_feed.tradingview.com',
        libraryPath: '/static/charting_library/',
        chartsStorageUrl: 'https://saveload.tradingview.com',
        chartsStorageApiVersion: '1.1',
        clientId: 'tradingview.com',
        userId: 'public_user_id',
        fullscreen: false,
        autosize: true,
        studiesOverrides: {},
}

the rest of your code was correct, in my component I'm using typescript, but this snippet that I put here for you, is not typed.

rodrigopluz avatar Nov 22 '22 19:11 rodrigopluz

Okay, I just updated it; however, my screen is still just blank, here's the code now with a screenshot of the page image

import React, { createRef } from 'react';

import {
  widget,
  Timezone,
  ThemeName,
  LanguageCode,
  ResolutionString,
  IChartingLibraryWidget,
  ChartingLibraryWidgetOptions,
} from '../../public/static/charting_library';

const getLanguageFromURL = ()=> {
  const regex = new RegExp('[\\?&]lang=([^&#]*)');
  const results = regex.exec(location.search);
  return results === null
    ? null
    : (decodeURIComponent(
        results[1].replace(/\+/g, ' '),
      ));
};

export class TradingGraph extends React.PureComponent {
  tvWidget = null;
  ref= createRef();

  componentDidMount() {
    const widgetOptions = {
        symbol: 'AAPL',
        interval: 'D',
        datafeedUrl: 'https://demo_feed.tradingview.com',
        libraryPath: '/static/charting_library/',
        chartsStorageUrl: 'https://saveload.tradingview.com',
        chartsStorageApiVersion: '1.1',
        clientId: 'tradingview.com',
        userId: 'public_user_id',
        fullscreen: false,
        autosize: true,
        studiesOverrides: {},
}   

    const tvWidget = new widget(widgetOptions);
    this.tvWidget = tvWidget;

    tvWidget.onChartReady(() => {
      tvWidget.headerReady().then(() => {
        const button = tvWidget.createButton();
        button.setAttribute(
          'title',
          'Click to show a notification popup',
        );
        button.classList.add('apply-common-tooltip');
        button.addEventListener('click', () =>
          tvWidget.showNoticeDialog({
            title: 'Notification',
            body: 'TradingView Charting Library API works correctly',
            callback: () => {
            },
          }),
        );
        button.innerHTML = 'Check API';
      });
    });
  }

  componentWillUnmount() {
    if (this.tvWidget !== null) {
      this.tvWidget.remove();
      this.tvWidget = null;
    }
  }

  render() {
    return (
      <div>
        <div ref={this.ref} className={'TVChartContainer'} />
      </div>
    );
  }
}

0xAskar avatar Nov 22 '22 20:11 0xAskar

try to see if the calling path of charting_library would be the same.

like how many returns you need to have... '../../public/static/charting_library' or '../public/static/charting_library'

import {
   widget,
} from '../../public/static/charting_library';

something else, this amount you don't need

Timezone,
ThemeName,
LanguageCode,
ResolutionString,
IChartingLibraryWidget,
ChartingLibraryWidgetOptions,

rodrigopluz avatar Nov 22 '22 20:11 rodrigopluz

@rodrigopluz good point that i don't need those things. but my path is already correct. cause if not, then it throws an error. not sure what to do though? What is interesting is that, none of my console.logs are triggering inside the component. So it seems like maybe the dynamic import not working

0xAskar avatar Nov 22 '22 20:11 0xAskar

tests by removing the dynamic. to see if it returns an error.

this problem of getting a black screen, I didn't have this problem.

rodrigopluz avatar Nov 22 '22 20:11 rodrigopluz

so if i get rid of the dynamic it gets the datafeeds is not defined problem again. here's my question to you, what is component named and what file is it located? is it components/TradingGraph and then in an index.js file?

The way that i structured the page index is:

import dynamic from 'next/dynamic';
// import TVChartContainer from "../../components/TVChartContainer/index.js"
const TradingGraph = dynamic(
  () =>
    import('../../components/TVChartContainer/index').then(
      module => module.TradingGraph,
    ),
  {
    ssr: false,
  },
);

const Index = () => {
	return (
        <div>
    <TradingGraph />
    </div>
    );
};

export default Index;

0xAskar avatar Nov 22 '22 20:11 0xAskar

Actually, I now get this error: The datafeed seems to be undefined image

0xAskar avatar Nov 22 '22 20:11 0xAskar

this is the error that was returning me, and then I did it the way I gave you.

try to change the version of charts_storage_api_version for 1.4

rodrigopluz avatar Nov 22 '22 20:11 rodrigopluz

@rodrigopluz the problem is, i am doing the way you're doing it, and I'm still reaching the problem. It seems like you need to add new windows.datafeeds.... but i'm getting a new error of windows.datafeeds is undefined. i'm having same error as this person https://github.com/tradingview/charting-library-examples/issues/310

where is your document.js file located?

0xAskar avatar Nov 22 '22 20:11 0xAskar

actually, i was able to get window.datafeeds, but now i still get this same error image

0xAskar avatar Nov 22 '22 21:11 0xAskar

look, take a look again at your _document.js file

I think it should be that way.

class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head>
          <Script
            async
            strategy="afterInteractive"
            src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS}`}
          />
          <Script strategy="afterInteractive" src="/static/datafeeds/udf/dist/bundle.js"/>
          .... (other code)
        </Head>
      </Html>
    );
  }
}

rodrigopluz avatar Nov 22 '22 21:11 rodrigopluz

unforunately, I still get the same error. weirdly enough.

again here's the component code:

import React, { createRef } from 'react';
import Styles from "./index.module.css"
import {
  widget,
  ChartingLibraryWidgetOptions,
} from '../../public/static/charting_library';

const getLanguageFromURL = ()=> {
  const regex = new RegExp('[\\?&]lang=([^&#]*)');
  const results = regex.exec(location.search);
  return results === null
    ? null
    : (decodeURIComponent(
        results[1].replace(/\+/g, ' '),
      ));
};

export class TVChartContainer extends React.PureComponent {
  tvWidget = null;
  ref= createRef();
  componentDidMount() {
    console.log(window.Datafeeds)
    const widgetOptions = {
        symbol: 'AAPL',
        interval: 'D',
        // datafeedUrl: 'https://demo_feed.tradingview.com',
        datafeedUrl: new window.Datafeeds.UDFCompatibleDatafeed('https://demo_feed.tradingview.com'),
        libraryPath: '/static/charting_library/',
        chartsStorageUrl: 'https://saveload.tradingview.com',
        chartsStorageApiVersion: '1.1',
        clientId: 'tradingview.com',
        userId: 'public_user_id',
        fullscreen: false,
        autosize: true,
        studiesOverrides: {},
}   
console.log(widgetOptions.datafeedUrl)

    const tvWidget = new widget(widgetOptions);
    this.tvWidget = tvWidget;
    console.log("are we in here?")
    tvWidget.onChartReady(() => {
        console.log("hello?")
      tvWidget.headerReady().then(() => {
        const button = tvWidget.createButton();
        button.setAttribute(
          'title',
          'Click to show a notification popup',
        );
        button.classList.add('apply-common-tooltip');
        button.addEventListener('click', () =>
          tvWidget.showNoticeDialog({
            title: 'Notification',
            body: 'TradingView Charting Library API works correctly',
            callback: () => {
            },
          }),
        );
        button.innerHTML = 'Check API';
      });
    });
  }

  componentWillUnmount() {
    if (this.tvWidget !== null) {
      this.tvWidget.remove();
      this.tvWidget = null;
    }
  }

  render() {
    return (
      <div>
        <div ref={this.ref} className={Styles.TVChartContainer} />
      </div>
    );
  }
}

0xAskar avatar Nov 22 '22 21:11 0xAskar