Closed mickelindahl closed 4 years ago
I faced the same issue except that I'm using fullcalendar-vue with Nuxt.js.
My workaround is to use the SPA mode,
e.g. in my package.json
:
"scripts": {
- "dev": "nuxt",
+ "dev": "nuxt --spa",
},
So Server Side Rendering (SSR) seems the cause of the issue but Next.js doesn't provide SPA mode. This wiki (https://github.com/zeit/next.js/wiki/FAQ) and this library (https://github.com/kadirahq/react-no-ssr) might help.
I tried with react-no-ssr and the problem unfortunately still remained.
I can fix this by replacing
var matchesMethod = Element.prototype.matches || Element.prototype.matchesSelector || Element.prototype.msMatchesSelector;
with
var matchesMethod=function(s) { var matches = (this.document || this.ownerDocument).querySelectorAll(s), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; };
and
var closestMethod = Element.prototype.closest || function (selector) { // polyfill var el = this; if (!document.documentElement.contains(el)) { return null; } do { if (elementMatches(el, selector)) { return el; } el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; };
with
var closestMethod = function (selector) { // polyfill var el = this; if (!document.documentElement.contains(el)) { return null; } do { if (elementMatches(el, selector)) { return el; } el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; };
Cheers /Mikael
I've stumbled upon the same issue, but this fix isn't working for me. Any other ideas?
Any news about this???
ReferenceError: Element is not defined
at /home/marcos/Documents/projects/dashboard-react/node_modules/@fullcalendar/core/main.js:107:25
at elementPropHash.className (/home/marcos/Documents/projects/dashboard-react/node_modules/@fullcalendar/core/main.js:7:68)
at Object.<anonymous> (/home/marcos/Documents/projects/dashboard-react/node_modules/@fullcalendar/core/main.js:10:2)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.setPrototypeOf.__proto__ (/home/marcos/Documents/projects/dashboard-react/node_modules/@fullcalendar/react/main.umd.js:7:103)
at Object.<anonymous> (/home/marcos/Documents/projects/dashboard-react/node_modules/@fullcalendar/react/main.umd.js:10:2)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
Having the same issue as @marcosdipaolo with Nextjs, I was ready over other recomendations, and now of them is lazy load and not use SSR. https://nextjs.org/docs#with-no-ssr. I will try to use in my project in day to see if it will actually trigger without SSR
Having the same issue as @marcosdipaolo with Nextjs, I was ready over other recomendations, and now of them is lazy load and not use SSR. https://nextjs.org/docs#with-no-ssr. I will try to use in my project in day to see if it will actually trigger without SSR
did you try that??? another solution?
@marcosdipaolo yep it works fine, by disabling SSR on the component. Thank you @marcosdipaolo for the reminder!
@marcosdipaolo yep it works fine, by disabling SSR on the component. Thank you @marcosdipaolo for the reminder!
Dou you have a code example?
@marcosdipaolo Simple as that
// @flow
import React from 'react'
import dynamic from 'next/dynamic'
import Page from '../../components/Page'
const DynamicCalendar = dynamic(
() => import('../../components/Admin/Calendar'),
{
ssr: false, <------- just set this part to false
}
);
export default () => (
<Page title='Calendar | Hair Line Salon'>
<DynamicCalendar/>
</Page>
)
// @flow
import * as React from 'react';
import FullCalendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
class EventCalendar extends React.Component<Props, State> {
calendarComponentRef: {
current: HTMLDivElement | null,
};
constructor(props: Props) {
super(props);
this.state = {
events: [],
calendarEvents: [],
calendarReminders: [],
};
this.calendarComponentRef = React.createRef();
}
render() {
const { calendarEvents, calendarReminders } = this.state;
return (
<>
<FullCalendar
ref={this.calendarComponentRef}
header={{
left: 'prev,next today',
center: 'title',
right: 'timeGridWeek,timeGridDay,listWeek',
}}
height='auto'
defaultView='timeGridDay'
plugins={[
dayGridPlugin,
timeGridPlugin,
]}
events={[
...calendarEvents,
...calendarReminders,
]}
allDaySlot={false}
/>
</>
);
}
}
export default EventCalendar;
facing the same
same. Can you put Mikael's solution into the repo?.. it works. By the way I'm not using next.js it's just React.
Does anybody know what the actual issue is here, why the calendar can't be server rendered?
Any workaround for just using React?
Same problem here. If i disable SSR it will work in development mode. But if i try to build i get the "Element is not defined" error.
it seems to be a SSR polyfill issue for window.Element... we managed to get rid of the issue on the server render by adding the following code before the library is loaded or at the start up of the app. Unsure of the full effects of the below however.
if(typeof Element === 'undefined') {
global.Element = function() {
}
}
We use a full-calendar-wrapper
component that wraps the @fullcalendar
library and then use the loadable/component
library to handle our imports for SSR like so:
import React, { Component } from 'react';
import loadable from '@loadable/component';
const FullCalendar = loadable(() => import('@fullcalendar/react'), { ssr: false });
const DayGrid = loadable(() => import('@fullcalendar/daygrid'));
const Interactions = loadable(() => import('@fullcalendar/interaction'));
class FullCalendarWrapper extends Component {
// Render
render() {
const { data } = this.props;
const { type, showForm, css } = this.state;
return (
<div className={'fc-block' + ' ' + type}>
{typeof window !== 'undefined' && (
<FullCalendar
ref={this.calendarRef}
defaultView='dayGridMonth'
header={{}}
height='parent'
plugins={[ DayGrid, Interactions ]}
dateClick={args => this.clickedDate(args)}
eventClick={args => this.clickedEvent(args)}
events={data}
/>
)}
</div>
)
}
}
export default FullCalendarWrapper;
Unfortunately, the code above doesn't work in some situations as the dayGrid
and Interactions
components can't be loaded via loadable()
. I had to convert those back to normal import statements and then wrap the whole <FullCalendarWrapper/>
component in a typeof window !== 'undefined'
statement so those imports don't run unless the window is available.
@ehubbell I ended up using the loadable/component
library.
Sorry for the delay in responding to your issue, I have just began triaging on this repo. Please see this post about the state of the repo (https://github.com/fullcalendar/fullcalendar-react/issues/66) for more info.
This incompatibility with SSR is not specific to React, the same issue was reported in the main repo: https://github.com/fullcalendar/fullcalendar/issues/4784 ↑ Please visit the above issue, give a 👍 to vote (?), press the 🔈Subscribe button to receive updates.
Hi,
Glitch to reproduce the bug https://glitch.com/edit/#!/join/30dcdcf3-668a-449d-aa74-bfe3ff4e5b2c
Using react-fullcalendar 4.1 together with nextjs 8.1 I get ReferenceError: Element is not defined error in node_modules/@fullcalendar/core/main.js
I can fix this by replacing
with
var matchesMethod=function(s) { var matches = (this.document || this.ownerDocument).querySelectorAll(s), i = matches.length; while (--i >= 0 && matches.item(i) !== this) {} return i > -1; };
and
var closestMethod = Element.prototype.closest || function (selector) { // polyfill var el = this; if (!document.documentElement.contains(el)) { return null; } do { if (elementMatches(el, selector)) { return el; } el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; };
with
var closestMethod = function (selector) { // polyfill var el = this; if (!document.documentElement.contains(el)) { return null; } do { if (elementMatches(el, selector)) { return el; } el = el.parentElement || el.parentNode; } while (el !== null && el.nodeType === 1); return null; };
Cheers /Mikael