Skip to content

Could not use the library after install #309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
to-ivanliang opened this issue Feb 24, 2025 · 2 comments
Open

Could not use the library after install #309

to-ivanliang opened this issue Feb 24, 2025 · 2 comments

Comments

@to-ivanliang
Copy link

to-ivanliang commented Feb 24, 2025

After install with pnpm install react-pdf-highlighter,

And tried with your example code

import React, { useState, useEffect, useCallback, useRef } from 'react'

import {
  AreaHighlight,
  Highlight,
  PdfHighlighter,
  PdfLoader,
  Popup,
  Tip,
} from 'react-pdf-highlighter'
import type {
  Content,
  IHighlight,
  NewHighlight,
  ScaledPosition,
} from 'react-pdf-highlighter'
import 'react-pdf-highlighter/dist/style.css'

// import { Sidebar } from './Sidebar'
// import { Spinner } from './Spinner'
// import { testHighlights as _testHighlights } from './test-highlights'

// import './style/App.css'
// import '../../dist/style.css'

// const testHighlights: Record<string, Array<IHighlight>> = _testHighlights

const getNextId = () => String(Math.random()).slice(2)

const parseIdFromHash = () => document.location.hash.slice('#highlight-'.length)

const resetHash = () => {
  document.location.hash = ''
}

const HighlightPopup = ({ comment }: { comment: { text: string; emoji: string } }) =>
  comment.text ? (
    <div className="Highlight__popup">
      {comment.emoji} {comment.text}
    </div>
  ) : null

const PRIMARY_PDF_URL = 'https://arxiv.org/pdf/1708.08021'
const SECONDARY_PDF_URL = 'https://arxiv.org/pdf/1604.02480'

export function PDFViewer() {
  const searchParams = new URLSearchParams(document.location.search)
  const initialUrl = searchParams.get('url') || PRIMARY_PDF_URL

  const [url, setUrl] = useState(initialUrl)
  const [highlights, setHighlights] = useState<Array<IHighlight>>(
    []
    // testHighlights[initialUrl] ? [...testHighlights[initialUrl]] : []
  )

  // const resetHighlights = () => {
  //   setHighlights([])
  // }

  // const toggleDocument = () => {
  //   const newUrl = url === PRIMARY_PDF_URL ? SECONDARY_PDF_URL : PRIMARY_PDF_URL
  //   setUrl(newUrl)
  //   setHighlights(testHighlights[newUrl] ? [...testHighlights[newUrl]] : [])
  // }

  const scrollViewerTo = useRef((highlight: IHighlight) => {})

  const scrollToHighlightFromHash = useCallback(() => {
    const highlight = getHighlightById(parseIdFromHash())
    if (highlight) {
      scrollViewerTo.current(highlight)
    }
  }, [])

  useEffect(() => {
    window.addEventListener('hashchange', scrollToHighlightFromHash, false)
    return () => {
      window.removeEventListener('hashchange', scrollToHighlightFromHash, false)
    }
  }, [scrollToHighlightFromHash])

  const getHighlightById = (id: string) => {
    return highlights.find((highlight) => highlight.id === id)
  }

  const addHighlight = (highlight: NewHighlight) => {
    console.log('Saving highlight', highlight)
    setHighlights((prevHighlights) => [
      { ...highlight, id: getNextId() },
      ...prevHighlights,
    ])
  }

  const updateHighlight = (
    highlightId: string,
    position: Partial<ScaledPosition>,
    content: Partial<Content>
  ) => {
    console.log('Updating highlight', highlightId, position, content)
    setHighlights((prevHighlights) =>
      prevHighlights.map((h) => {
        const { id, position: originalPosition, content: originalContent, ...rest } = h
        return id === highlightId
          ? {
              id,
              position: { ...originalPosition, ...position },
              content: { ...originalContent, ...content },
              ...rest,
            }
          : h
      })
    )
  }

  return (
    <div className="App" style={{ display: 'flex', height: '100vh' }}>
      {/* <Sidebar
        highlights={highlights}
        resetHighlights={resetHighlights}
        toggleDocument={toggleDocument}
      /> */}
      <div
        style={{
          height: '100vh',
          width: '75vw',
          position: 'relative',
        }}
      >
        <PdfLoader url={url} beforeLoad={<div>Loading...</div>}>
          {(pdfDocument) => (
            <PdfHighlighter
              pdfDocument={pdfDocument}
              enableAreaSelection={(event) => event.altKey}
              onScrollChange={resetHash}
              scrollRef={(scrollTo) => {
                scrollViewerTo.current = scrollTo
                scrollToHighlightFromHash()
              }}
              onSelectionFinished={(
                position,
                content,
                hideTipAndSelection,
                transformSelection
              ) => (
                <Tip
                  onOpen={transformSelection}
                  onConfirm={(comment) => {
                    addHighlight({ content, position, comment })
                    hideTipAndSelection()
                  }}
                />
              )}
              highlightTransform={(
                highlight,
                index,
                setTip,
                hideTip,
                viewportToScaled,
                screenshot,
                isScrolledTo
              ) => {
                const isTextHighlight = !highlight.content?.image

                const component = isTextHighlight ? (
                  <Highlight
                    isScrolledTo={isScrolledTo}
                    position={highlight.position}
                    comment={highlight.comment}
                  />
                ) : (
                  <AreaHighlight
                    isScrolledTo={isScrolledTo}
                    highlight={highlight}
                    onChange={(boundingRect) => {
                      updateHighlight(
                        highlight.id,
                        { boundingRect: viewportToScaled(boundingRect) },
                        { image: screenshot(boundingRect) }
                      )
                    }}
                  />
                )

                return (
                  <Popup
                    popupContent={<HighlightPopup {...highlight} />}
                    onMouseOver={(popupContent) =>
                      setTip(highlight, (highlight) => popupContent)
                    }
                    onMouseOut={hideTip}
                    key={index}
                  >
                    {component}
                  </Popup>
                )
              }}
              highlights={highlights}
            />
          )}
        </PdfLoader>
      </div>
    </div>
  )
}

Got the error:

Error: Cannot find package '/Users/ivanliang/Documents/project/marketplace/marketplace-web-next/node_modules/.pnpm/react-pdf-highlighter@8.0.0-rc.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-pdf-highlighter/dist/node_modules/pdfjs-dist/index.js' imported from /Users/ivanliang/Documents/project/marketplace/marketplace-web-next/node_modules/.pnpm/react-pdf-highlighter@8.0.0-rc.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/react-pdf-highlighter/dist/src/components/PdfLoader.js
Did you mean to import "pdfjs-dist/build/pdf.mjs"?

My env: node 20.18.0 nextjs 15.0.3 react: 18.3.1

Is this something related to the environment?

@asilvester-nw
Copy link

I'm experiencing the same issue as well.

@asilvester-nw
Copy link

asilvester-nw commented Feb 25, 2025

@to-ivanliang I've found a solution for this in my build. It was my "vite.config.ts" file, I needed to add the react-pdf-highlighter to the ssr paramter.

 import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";
import path from "path";
import { reactRouterDevTools } from "react-router-devtools";

export default defineConfig(({ isSsrBuild }) => ({
  build: {
    rollupOptions: isSsrBuild
      ? {
          input: "./server/app.ts",
        }
      : undefined,
  },
  plugins: [reactRouter(), tsconfigPaths()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./app"),
    },
  },
  /*
   * Use noExternal to bundle dependencies like 'react-pdf-highlighter' during SSR builds.
   * This ensures compatibility by handling:
   *  - Browser-specific code for Node.js environments
   *  - CSS imports and assets through Vite's build process.
   *  - Non-CommonJS modules for SSR compatibility.
   * Without this, issues like missing CSS imports, browser API errors, and module compatibility problems can occur.
   */
  ssr: {
    noExternal: ["react-pdf-highlighter"],
  },
  define: {
    "process.env": {},
    global: {},
  },
}));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants