algolia / instantsearch

⚑️ Libraries for building performant and instant search experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.

Home Page:https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filter is not working via URL when its on same page: Next.js App Routing

naseef0 opened this issue Β· comments

πŸ› Current behavior

Filtering doesn't work via URL when staying on the same page. I've added quick filters that contain filtered URLs. Clicking any of the filtered URLs doesn't apply the filter. However, if I refresh the page, I get the filtered results. i have used InfiniteHits component

eg:

<div
    style={{
      display: "flex",
      justifyContent: "center",
      marginBottom: "20px",
      marginTop: "20px",
    }}
  >
    <Link
      style={{ marginRight: "10px" }}
      href="/?instant_search%5BrefinementList%5D%5BhierarchicalCategories.lvl0%5D%5B0%5D=Appliances&&id=1"
    >
      <button>Appliances</button>
    </Link>
    <Link
      style={{ marginRight: "10px" }}
      href="/?instant_search%5BrefinementList%5D%5BhierarchicalCategories.lvl0%5D%5B0%5D=Audio&instant_search%5BrefinementList%5D%5Bbrand%5D%5B0%5D=Bose%C2%AE&instant_search%5BrefinementList%5D%5Bbrand%5D%5B1%5D=JBL&instant_search%5BrefinementList%5D%5Brating%5D%5B0%5D=2"
    >
      <button>Audio</button>
    </Link>
    <Link
      style={{ marginRight: "10px" }}
      href="/?instant_search%5BrefinementList%5D%5BhierarchicalCategories.lvl0%5D%5B0%5D=Household%20Essentials&instant_search%5BrefinementList%5D%5BhierarchicalCategories.lvl0%5D%5B1%5D=Cameras%20%26%20Camcorders&instant_search%5BrefinementList%5D%5Bbrand%5D%5B0%5D=Nikon&instant_search%5BrefinementList%5D%5Bcategories%5D%5B0%5D=Short-Range%20Zoom%20Lenses"
    >
      <button>Cameras & Camcorders & Household Essentials</button>
    </Link>
  </div>
  <InstantSearchNext
    searchClient={client}
    indexName="instant_search"
    routing
  >
    <Configure hitsPerPage={1114} />
  
    <div className="Container">
      <div>
        <DynamicWidgets fallbackComponent={FallbackComponent} />
      </div>
      <div>
        {/* <SearchBox /> */}
        <InfiniteHits hitComponent={Hit} cache={sessionStorageCache} />
      </div>
    </div>
</InstantSearchNext>

πŸ” Steps to reproduce

  1. Go to browser.
  2. Click any of Quick filter shown above
  3. Nothing happens
  4. Refresh the page, you'll get result

Live reproduction

https://codesandbox.io/p/devbox/friendly-boyd-y42v3c?file=%2Fapp%2FSearch.tsx%3A58%2C1-72%2C31

πŸ’­ Expected behavior

If i click any of Quick filters i should get filtered results without refreshing the page

Package version

"algoliasearch": "4.22.1", "instantsearch.css": "8.1.0", "next": "13.5.1", "react": "18.2.0", "react-dom": "18.2.0", "react-instantsearch": "7.6.0", "react-instantsearch-nextjs": "0.1.13"

Operating system

Ubuntu 22.04.4 LTS

Browser

Firefox 123.0 (64-bit)

Code of Conduct

  • I agree to follow this project's Code of Conduct

Anyone any update on this?

I am also facing the same issue. Is there any fix for this?

Hey @naseef0,

Thanks for the feedback !

Unfortunately the app router for Next.js does not have events like the router for pages had.

There are some other changes that we need to do for routing, I'll take that in mind as well. I suppose we'll have to react to external changes with useParams.

In the meantime you could either call refine from useMenu instead of relying on Link, or maybe key the <InstantSearchNext> component with the URL. Or you can check the routing's prop arguments in which you may customize behavior.

@aymeric-giraudet Thanks, I'll try some workaround for this.

@aymeric-giraudet As of now, I have completely removed Algolia components and have instead utilised the algoliasearch client. Additionally, I have implemented a custom context to manage results and filters. Also i have used package nuqs for routing

Hi @naseef0,

The feature is in PR #6107 and should be in the next minor.

This workaround would have worked though :

export default function Search() {
  const searchParams = useSearchParams();
  const onUpdateRef = useRef<() => void>();
  useEffect(() => {
    if (onUpdateRef.current) {
      onUpdateRef.current();
    }
  }, [searchParams]);

  return (
    <InstantSearchNext
      searchClient={client}
      indexName="instant_search"
      routing={{
        router: {
          start(onUpdate) {
            onUpdateRef.current = onUpdate;
          },
        },
      }}
    >
    {/* Widgets */}
    </InstantSearchNext>
  );
}

Hi @naseef0,

The feature is in PR #6107 and should be in the next minor.

This workaround would have worked though :

export default function Search() {
  const searchParams = useSearchParams();
  const onUpdateRef = useRef<() => void>();
  useEffect(() => {
    if (onUpdateRef.current) {
      onUpdateRef.current();
    }
  }, [searchParams]);

  return (
    <InstantSearchNext
      searchClient={client}
      indexName="instant_search"
      routing={{
        router: {
          start(onUpdate) {
            onUpdateRef.current = onUpdate;
          },
        },
      }}
    >
    {/* Widgets */}
    </InstantSearchNext>
  );
}

Thanks @aymeric-giraudet, This works fine in codesandbox. Will wait for the next release.

Although this was good for this use case when the URL need to be updated, but this is causing issues with Intercepting routes, where the Intercepted route is a URL opening a modal. Could there be a flag where we can optionally use this fix for the URLs?