docsearch icon indicating copy to clipboard operation
docsearch copied to clipboard

"Named export DocSearch not found" error in Remix framework

Open pawelgalazka opened this issue 1 year ago • 4 comments

Description

When importing DocSearch React component in Remix framework web app, following error is thrown when running application:

[vite] Internal server error: [vite] Named export 'DocSearch' not found. The requested module '@docsearch/react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@docsearch/react';
const {DocSearch} = pkg;

Steps to reproduce

  1. Create Remix app through npx create-remix@latest
  2. Add DocSearch import to app/routes/_index.tsx:
import { DocSearch } from '@docsearch/react';

import '@docsearch/css';
  1. Run application in dev mode: npm run dev
  2. Visit local page: http://localhost:5173/

Expected behavior

Error:

Internal server error: [vite] Named export 'DocSearch' not found.

should not be produced when running web app in Remix framework. Instead DocSearch search component should be rendered.

Environment

  • OS: Mac
  • Browser: Chrome
  • DocSearch version: 3.6.0

pawelgalazka avatar Jun 17 '24 10:06 pawelgalazka

Hello, @pawelgalazka sorry for the delayed response. Did you resolve this? I don't know off the top of my head so wondering if you managed to figure it out before investing time on it.

randombeeper avatar Jul 10 '24 21:07 randombeeper

@randombeeper I did manage to resolve this, however my solution is more of a workaround:

  1. In vite.config.ts add:
ssr: {
  noExternal: ["@docsearch/react"],
},
  1. Then use this wrapper component for @docsearch/react:
import { Suspense, lazy, useEffect, useState } from "react"
import type { DocSearchProps } from "@docsearch/react"
import "@docsearch/css"

let hydrating = true

export function useHydrated() {
  const [hydrated, setHydrated] = useState(() => !hydrating)
  useEffect(() => {
    hydrating = false
    setHydrated(true)
  }, [])
  return hydrated
}

const OriginalDocSearch = lazy(() =>
  import("@docsearch/react").then((module) => ({
    default: module.DocSearch,
  })),
)

export function DocSearch(docSearchProps: DocSearchProps) {
  const hydrated = useHydrated()

  if (!hydrated) {
    return <div className="h-9" />
  }

  return (
    <Suspense fallback={<div className="h-9" />}>
      <div className="-ml-4 flex flex-col">
        <OriginalDocSearch {...docSearchProps} />
      </div>
    </Suspense>
  )
}

which excludes @docsearch/react from being server side rendered.

Ideally I would expect to import and use original DocSearch React component as is, in my server side rendered component without any issues.

pawelgalazka avatar Jul 11 '24 08:07 pawelgalazka

Same issue here. But I can confirm the workaround provided by @pawelgalazka works! Thank you so much!

slax57 avatar Dec 06 '24 17:12 slax57

See the same issue with astro framework. When using the suggested CommonJS loading strategy, the component can be loaded but it won't react to click.

tisonkun avatar Jun 09 '25 03:06 tisonkun