I am trying to use reveal.js in my React.js/Next.js website based on this https://revealjs.com/installation/#installing-from-npm
The error I get is:
Server Error
ReferenceError: navigator is not defined
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source
external%20%22reveal.js%22 (1:0) @ eval
> 1 | module.exports = require("reveal.js");
I read through the entire reveal site and searched, there is no reference to navigator or dependencies anywhere.
This is my code, (the CSS is included in my _app.js):
import Head from 'next/head'
import Link from 'next/link'
import ContainerFull from '../components/container-full'
import MoreStories from '../components/more-stories'
import HeroPost from '../components/hero-post'
import Intro from '../components/intro'
import Layout from '../components/layout'
import { getHomePage, getHomeSlides } from '../lib/api'
import { CMS_NAME } from '../lib/constants'
import Header from '../components/header'
import dynamic from 'next/dynamic'
const MySlides = dynamic(
  () => import('../components/slides'),
  { ssr: false }
)
export default function Page( {page, artwork} ) {
   return (
    <>
      <Layout>
        <Head>
          <title>{ page.seo.title }</title>
          <meta name="description" content={page.seo.metaDesc} />
        </Head>
        <Header />
        <ContainerFull>
          <h1>{ page.title }</h1>
          <MySlides />
          <div dangerouslySetInnerHTML={{ __html: page.content }} />
          {artwork.nodes && artwork.nodes.map((arts) => (
            <span>{arts.title}</span>
          ))}
        </ContainerFull>
      </Layout>
    </>
  )
}
export async function getStaticProps({ params }) {
  const data = await getHomePage()
  console.log(data)
  const art = await getHomeSlides()
  console.log(art)
  return {
    props: {
      page: data,
      artwork: art,
    },
  }
}
slides.js file
import Reveal from 'reveal.js'
import Markdown from 'reveal.js/plugin/markdown/markdown.esm.js'
import React, { useEffect } from "react"
const MySlides = () => {
  useEffect(() => {
    let deck = new Reveal({
        plugins: [ Markdown ]
    })
    deck.initialize()
  })
  return (
    <div>SlideShow</div>
  )
}
export default MySlides
Since Reveal and Markdown are client side modules which depend on navigator object, it's incorrect to import it in the first two lines. Instead, they should be imported in the useEffect block, as the block will be run in the client side according to the document at https://nextjs.org/docs/basic-features/data-fetching/client-side.
This is what works for me:
import { useEffect } from "react"
const MySlides = () => {
  useEffect(() => {
    // This will be executed in the browser (client-side).
    const clientSideInitialization = async () => {
      // load modules in browser
      const Reveal = await (await import("reveal.js")).default
      const Markdown = await (await import("reveal.js/plugin/markdown/markdown.esm")).default
      const deck = new Reveal({
        plugins: [Markdown]
      })
      deck.initialize()
    }
    clientSideInitialization()
  })
  return (
    <div>SlideShow</div>
  )
}
export default MySlides
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With