I'm using NextJS and Fullcalendar.
I tried to use fullcalendar
using dynamic import like inthis example (for more info, this example solution comes from here ).
It worked, But there was a problem. Almost every 1 out of 5 refreshing attempts ended in error Please import the top-level fullcalendar lib before attempting to import a plugin
( like this , but versions are correct in my case)
After that, I found out that the modules option for next/dynamic has been deprecated. I thought it was a source of my problem (I'm not sure 100%, but at least it was deprecated and needed to be updated).
As docs says, newer way to handle dynamic imports is like this:
const DynamicComponent = dynamic(() =>
import('../components/hello').then((mod) => mod.Hello)
)
But because we need multiple imports I found this solution .
For now, It seems like everything should be working, but my code has no effect.
import dynamic from "next/dynamic";
import { useEffect, useState } from "react";
import "@fullcalendar/common/main.css"; // @fullcalendar/react imports @fullcalendar/common
import "@fullcalendar/daygrid/main.css"; // @fullcalendar/timegrid imports @fullcalendar/daygrid
import "@fullcalendar/timegrid/main.css"; // @fullcalendar/timegrid is a direct import
import "./Fullcalendar.module.scss";
let CalendarComponent;
const Calendar = dynamic(() =>
import("@fullcalendar/react").then((module) => module.Calendar)
);
const dayGridPlugin = dynamic(() =>
import("@fullcalendar/daygrid").then((module) => module.dayGridPlugin)
);
export default function FullCalendar(props) {
const [calendarLoaded, setCalendarLoaded] = useState(false);
useEffect(() => {
CalendarComponent = () => (
<Calendar
{...props}
plugins={[dayGridPlugin]}
initialView="dayGridMonth"
/>
);
setCalendarLoaded(true);
}, []);
let showCalendar = (props) => {
if (!calendarLoaded) return <div>Loading ...</div>;
return <CalendarComponent {...props} />;
};
return <div>{showCalendar(props)}</div>;
}
I also find another way to use next transpile modules . But they say that "there is currently no way to transpile only parts of a package, it's all or nothing"
.
In fact, I have something in next.config.js
. Editing this file into transpile modules is another mysterious adventure, full of problems.
What should I have to do?
Making FullCalendar work properly with Next.js requires some initial setup and a few changes to your initial code.
First, let's install next-transpile-modules
to process fullcalendar
's ES modules. Make sure to include all @fullcalendar
dependencies you use.
// next.config.js
const withTM = require('next-transpile-modules')([
'@fullcalendar/common',
'@fullcalendar/react',
'@fullcalendar/daygrid'
]);
module.exports = withTM({
// any other next.js settings here
});
Next, add a custom Babel configuration to ignore CSS imports used in fullcalendar
- babel-plugin-transform-require-ignore
plugin will need to be installed. This prevents the Global CSS cannot be imported from within node_modules
error from Next.js.
// babel.config.js
module.exports = {
presets: [
'@babel/preset-react'
],
overrides: [
{
include: ['./node_modules'],
plugins: [
[
'babel-plugin-transform-require-ignore',
{
extensions: ['.css']
}
]
]
}
]
};
You'll have to include fullcalendar
's global CSS in _app.js
to compensate for this. Global CSS can only be imported from this file in Next.js.
// _app.js
import '@fullcalendar/common/main.css'
import '@fullcalendar/daygrid/main.css'
import '@fullcalendar/timegrid/main.css'
Finally, you can simplify and refactor your FullCalendar
component. Here you don't have to dynamically import its fullcalendar
dependencies, we'll dynamically import the component itself when using it.
// components/FullCalendar.jsx
import Calendar from '@fullcalendar/react';
import dayGridPlugin from '@fullcalendar/daygrid';
import styles from './Fullcalendar.module.scss';
export default function FullCalendar(props) {
return (
<Calendar {...props} plugins={[dayGridPlugin]} initialView="dayGridMonth" />
);
}
Then, dynamically import your custom component wherever it's used.
import dynamic from 'next/dynamic';
const FullCalendar = dynamic(() => import('../components/FullCalendar'), {
ssr: false
});
const SomePage = () => {
return <FullCalendar />;
}
export default SomePage;
For reference, this is based on the official example from fullcalendar
, with some adaptations to make it work with next-transiple-modules
v6.4.0.
We solve this problem
Step 1: First follow the above answer of "juliomalves" for next.config.js. And also import CSS files in "_app.js" file, also follow the above answer for that.
Step 2: Write all full calendar code as we write in react js, but make it a separate component.
Step 3: Next import the "Calendar" component using NextJS dynamic import.
import dynamic from 'next/dynamic';
const Calendar = dynamic(()=> import('../path/to/component/Calendar'),{ssr:false})
It should work now!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.