I have a Next.js project with TypeScript. I take a reference from official document resulting to the followings.
BundledEditor.jsx:
// ** https://www.tiny.cloud/docs/tinymce/6/react-pm-bundle/ **//
import { Editor } from '@tinymce/tinymce-react'
// remove ssr, otherwise will cause ReferenceError: navigator is not defined
// TinyMCE so the global var exists
// eslint-disable-next-line no-unused-vars
import tinymce from 'tinymce/tinymce'
// DOM model
import 'tinymce/models/dom/model'
// Theme
import 'tinymce/themes/silver'
// Toolbar icons
import 'tinymce/icons/default'
// Editor styles
import 'tinymce/skins/ui/oxide/skin.min.css'
// importing the plugin js.
// if you use a plugin that is not listed here the editor will fail to load
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/anchor'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/autoresize'
import 'tinymce/plugins/autosave'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/code'
import 'tinymce/plugins/codesample'
import 'tinymce/plugins/directionality'
import 'tinymce/plugins/emoticons'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/help'
import 'tinymce/plugins/image'
import 'tinymce/plugins/importcss'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/media'
import 'tinymce/plugins/nonbreaking'
import 'tinymce/plugins/pagebreak'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/quickbars'
import 'tinymce/plugins/save'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/table'
import 'tinymce/plugins/template'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/visualchars'
import 'tinymce/plugins/wordcount'
// importing plugin resources
import 'tinymce/plugins/emoticons/js/emojis'
// Content styles, including inline UI like fake cursors
/* eslint import/no-webpack-loader-syntax: off */
// import contentCss from 'tinymce/skins/content/dark/content.css'
import contentCss from '!!raw-loader!tinymce/skins/content/default/content.min.css'
import contentUiCss from '!!raw-loader!tinymce/skins/ui/oxide/content.min.css'
export default function BundledEditor(props) {
const { init, ...rest } = props
// note that skin and content_css is disabled to avoid the normal
// loading process and is instead loaded as a string via content_style
return (
<Editor
init={{
...init,
skin: false,
content_css: false,
content_style: [contentCss, contentUiCss, init.content_style || ''].join('n')
}}
{...rest}
/>
)
}
I just import it on other file like this:
import BundledEditor from './BundledEditor';
It works, but if refresh, the page will show this error:
ReferenceError: navigator is not defined
So I change the import way like this:
// remove ssr, otherwise will cause ReferenceError: navigator is not defined
const BundledEditor = dynamic(() => import('../BundledEditor'), {
ssr: false
})
then fix the issue.
But when I try to type yarn build
to check the project.
It shows error:
info - Collecting page data ...ReferenceError: navigator is not defined
at /Users/motogod19/4iDPS/Sphere/sphere-brand-dev/node_modules/tinymce/tinymce.js:961:23
at Object.<anonymous> (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/node_modules/tinymce/tinymce.js:31525:3)
at Module._compile (node:internal/modules/cjs/loader:1254:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
at Module.load (node:internal/modules/cjs/loader:1117:32)
at Module._load (node:internal/modules/cjs/loader:958:12)
at Module.require (node:internal/modules/cjs/loader:1141:19)
at require (node:internal/modules/cjs/helpers:110:18)
at 3868 (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/.next/server/pages/apps/campaign/BundledEditor.js:28:33)
at __webpack_require__ (/Users/motogod19/4iDPS/Sphere/sphere-brand-dev/.next/server/webpack-runtime.js:25:42)
> Build error occurred
Error: Failed to collect page data for /apps/campaign/BundledEditor
I’m not familiar with Next.js, is any dynamic import should I do ?
2
Answers
navigator is not defined
means that you are bundling the code for server side, which do not have the browser related APIs. You need to bundle this for the client side (that is, for the browser).The issue is because
tinymce
do not support ssr (as evident from https://github.com/tinymce/tinymce/issues/3709)Since you are using Next.js 13 and
pages
router, change yourBundleEditor.jsx
to below:Both
npm run dev
andnpm run build
works fine.You are getting that error because the
tinymce
does not seem to be server-side rendering friendly, as executing browser specific code in the component body or at import. That has been said, usingtypeof window !== 'undefined'
as suggested in the other answer is not recommended at all, as it will very likely cause a hydration error.Using
dynamic
import withssr:false
should work. In your case, it did not, because you haveBundledEditor
inpages
directory, so it’s considered as a page for/BundledEditor
causing another error.Just move
BundledEditor
outsidepages
, in acomponents
folder for example, at the same level aspages
, and import it like so: