Skip to content
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

Category filter is not applied by InstantSearchNext when the url is opened via next/link #6359

Open
1 task done
pkutsenko opened this issue Sep 11, 2024 · 0 comments
Open
1 task done
Labels
triage Issues to be categorized by the team

Comments

@pkutsenko
Copy link

🐛 Current behavior

We are using InstantSearchNext to make SSR for Algolia search.
The category is parsed from the url and passed to the uiState

export const InstantSearchProvider = ({ indexName, ...props }: Props) => {
  return (
    <InstantSearchNext
      routing={{
        router: {
          cleanUrlOnDispose: false,
          createURL({ qsModule, routeState, location }) {
            // @ts-ignore
            const queryParameters = routeState[indexName];

            const queryString = qsModule.stringify(queryParameters, {
              addQueryPrefix: true,
              arrayFormat: 'brackets',
            });

            return `${location.origin}${location.pathname}${queryString}`;
          },
          parseURL({ location, qsModule }) {
            const category = location.pathname.replace(/^\//, '').replace(/\/$/, '');

            const params = qsModule.parse(location.search.slice(1));
            const data = {
              [indexName]: params,
            };

            if (!data[indexName].menu) {
              // @ts-ignore
              data[indexName].menu = {};
            }

            if (category.includes('/')) {
              // @ts-ignore
              data[indexName].menu['category.url'] = category;
            } else {
              // @ts-ignore
              data[indexName].menu['category.parent.url'] = category;
            }

            return data;
          },
        },
        stateMapping: {
          stateToRoute(uiState) {
            const indexUiState = uiState[indexName] || {};

            if (indexUiState.configure?.['clickAnalytics']) {
              // @ts-ignore
              delete indexUiState.configure['clickAnalytics'];
            }
            if (indexUiState.menu?.['category.url']) {
              delete indexUiState.menu['category.url'];
            }
            if (indexUiState.menu?.['category.parent.url']) {
              delete indexUiState.menu['category.parent.url'];
            }

            return uiState;
          },
          routeToState(routeState: any) {
            return routeState;
          },
        },
      }}
      indexName={indexName}
      {...props}
    />
  );
};

We have a component that has useMenu hook. It's visible when the page is opened via <a href="/categoryId">Category</a>

export const CategoryUrlFacet = ({ isSubCategory }: Props) => {
  const attribute = isSubCategory ? 'category.url' : 'category.parent.url';

  useMenu({ attribute: attribute, limit: 1 });

  return null;
};

But when the page is opened via next/link <Link href="/categoryId">Category</Link> so that transition is seamless we got warning that menu widget is absent and the category parameter is ignored so we retrieve all the products.

The issue is reproduced when useDynamicWidgets is used together with useMenu is another component

export const FiltersColumn = ({
  excludedAttributes = [],
  isPlp = false,
  isSubCategory = false,
  className,
}: Props) => {
  const preAppliedAttributes = isSubCategory ? ['category.url'] : ['category.parent.url'];
  const trackFilterClick = useTrackClickFilter();
  const { attributesToRender } = useDynamicWidgets({
    facets: isPlp ? preAppliedAttributes : ['*'],
    maxValuesPerFacet: 100,
  });
  const isCategoryPage = isPlp && !isSubCategory;
  const filteredAttributes = attributesToRender.filter(
    (attribute) => !excludedAttributes.includes(attribute),
  );

  return (
    <div className={className}>
      <div>Filters</div>
      <div>
        {isCategoryPage && <SubcategoryLinks />}
        {filteredAttributes.map((attribute, index) => {
          return (
            <Filter
              attribute={attribute}
              key={attribute}
            />
          );
        })}
      </div>
    </div>
  );
};

export const SubcategoryLinks = ({ onClick }: Props) => {
  const { items } = useMenu({
    attribute: 'category.nameUrl',
    limit: 100,
    transformItems,
  });

  return (
        <ul>
          {items.map((item, index) => (
            <li key={item.label + index} >
              <Link
                href={`/${item.value}`}
              >
                <span>
                  {item.label}
                </span>
                <span>&nbsp;({item.count})</span>
              </Link>
            </li>
          ))}
        </ul>
  );
};

image image

image

🔍 Steps to reproduce

  1. Open the category page (page is showing the correct number of products)
  2. Open any product
  3. Go to the category page using next/link
  4. Result: Category filter wasn't applied. Search result consist of all the products (This issue is not consistent. It's reproduced time after time)

Live reproduction

https://codesandbox/no-sandbox

💭 Expected behavior

CSR page to return the same result as SSR. All filters that have been set up by routing prop of the InstantSearchNext component are applied.

Package version

algoliasearch 4.24.0, react-instantsearch 7.13.0, react-instantsearch-nextjs 0.3.10

Operating system

macOS 14.5

Browser

Chrome Version 128.0.6613.120

Code of Conduct

  • I agree to follow this project's Code of Conduct
@pkutsenko pkutsenko added the triage Issues to be categorized by the team label Sep 11, 2024
@pkutsenko pkutsenko changed the title useMenu hook is not visible by InstantSearchNext when the url is opened via next/link Category filter is not applied by InstantSearchNext when the url is opened via next/link Sep 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage Issues to be categorized by the team
Projects
None yet
Development

No branches or pull requests

1 participant