Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

"Error: [ssr]: no widgets were added " - A breaking change in v6.8.0, not properly documented. #2978

Closed
ItsWendell opened this issue Oct 17, 2020 · 22 comments

Comments

@ItsWendell
Copy link

ItsWendell commented Oct 17, 2020

Describe the bug 🐛

After updating to version v6.8.0 my code stopped working for SRR on NextJS. After digging in the PR's of this repository, I noticed that it is highly likely caused by pull request #2973, which was released a few days ago under v6.8.0.

I think this should have been marked as a breaking change. It changes the way SSR works using the WidgetsCollector which isn't properly documented in the documentation.

See SSR docs here.

The documentation shows that the <App /> component now receives a prop for widgetsCollector but this prop is never actually passed down by the server. Also, the related examples and type definitions were not properly updated, like the NextJS example.

To Reproduce 🔍

Steps to reproduce the behavior:

  1. Run the NextJS example and open in your browser.
  2. It will popup the following error: Error: [ssr]: no widgets were added, you likely did not pass the `widgetsCollector` down to the InstantSearch component.

Expected behavior 💭

I expected this to be either backward compatible or released as a breaking change like the industry-standard semver suggests.

Environment:

  • OS: Linux
  • Browser: Chrome
  • Version: 36

Additional context

** For people running into the same problem **
I needed install and / or revert back and freeze the version of the packages react-instantsearch, react-instantsearch-dom and react-instantsearch-core to v6.7.0 in order to fix this problem. I specifically had to install react-instantsearch-core separately too and freeze at v6.7.0 because of react-instantsearch is set to resolve all "^6.7.0" (all 6.. versions), which means it will install the 'broken' version too, v6.8.0 and above. Installing and freezing the core package worked for me.

@ItsWendell ItsWendell changed the title [ssr]: no widgets were added - Breaking change in v6.8.0 Error: [ssr]: no widgets were added | A breaking change in v6.8.0, not properly documented. Oct 17, 2020
@ItsWendell ItsWendell changed the title Error: [ssr]: no widgets were added | A breaking change in v6.8.0, not properly documented. Error: [ssr]: no widgets were added | A breaking change in v6.8.0, not properly documented. Oct 17, 2020
@ItsWendell ItsWendell changed the title Error: [ssr]: no widgets were added | A breaking change in v6.8.0, not properly documented. "Error: [ssr]: no widgets were added " - A breaking change in v6.8.0, not properly documented. Oct 17, 2020
@Haroenv
Copy link
Contributor

Haroenv commented Oct 18, 2020

Thanks for opening an issue, when I tried the example locally (and via the tests) it works without issue, as long as you spread the props in App towards InstantSearch. The goal is to replace the prop onSearchParameters with the prop widgetsCollector forwarded. I will look into this in detail and try to find the issue

You're right that this probably should have been a breaking change / major version

@Haroenv
Copy link
Contributor

Haroenv commented Oct 18, 2020

If you have a repo where it's not working as expected, that will help to see what's going wrong.

@Haroenv
Copy link
Contributor

Haroenv commented Oct 19, 2020

I think you might not spread the props as in the example, this works as expected for me: https://codesandbox.io/s/github/algolia/react-instantsearch/tree/master/examples/next?file=/components/app.js:1507-1525

EDIT the example on the repo wasn't updated yet, but it works when you update the dependency too https://codesandbox.io/s/gracious-mayer-6rrzy?file=/components/app.js

@ItsWendell
Copy link
Author

ItsWendell commented Oct 21, 2020

@Haroenv thanks for taking the time to debug this. I converted the above code sandbox to how I've set it up in my next.js project (with getServerSideProps instead of getInitialProps).

Here is my sandbox:

I just do not understand where widgetsCollector is coming from, if you follow it up the tree, it never gets assigned or passed down. If I comment it out from the <InstantSearch ...> component, you get the error mentioned in this issue.

Yet if you console.log the value of this.props.widgetsCollector, you get undefined. I simply do not understand where widgetsCollector is coming from, and why it works.

I'm confused, also the types in the @types package are missing so it's harder for me to pass down all the props into InstantSearch.

Does this help and could you explain what is going on?

--

I managed to fix the issue by extending the types of react-instantsearch-core like this:

(react-instantsearch-core.d.ts)

export declare module "react-instantsearch-core" {
  interface InstantSearchProps {
    widgetsCollector: any;
  }
}

And then actually passing the widgetsCollector from my search page props to the <InstantSearch> component, I'm still very confused on to why this works and where widgetsCollector is coming from, hope someone can explain!

@DB-Alex
Copy link

DB-Alex commented Oct 21, 2020

I have the same problem

@Haroenv
Copy link
Contributor

Haroenv commented Oct 21, 2020

you seemed to have forgotten the actual sandbox, could you send it please? The typings are indeed not yet updated, since those are community maintained. I can review a PR to definitelyTyped though!

@ItsWendell
Copy link
Author

Haroenv added a commit to algolia/DefinitelyTyped that referenced this issue Oct 21, 2020
@Haroenv
Copy link
Contributor

Haroenv commented Oct 21, 2020

Thanks @ItsWendell, but what doesn't work about this? Just like onSearchParameters before, it's being set when you call findResultsState for determining which widgets render, so it's only used on the server; the logs you see are on the frontend :)

I've made a PR to definitelytyped for adding it to the typescript definitions

@DB-Alex
Copy link

DB-Alex commented Oct 27, 2020

An update of the next example would help a lot, really have no clue on how to fix this.

@ItsWendell
Copy link
Author

ItsWendell commented Oct 27, 2020

@alexvandervegt I can seem like a bit of magic, but here's how I think it works.

In NextJS, since you pass down a NextJS Page during SSR to findResultsState, that will pass down the prop widgetsCollector to that page. Your <InstantSearch> component needs this prop during SSR to properly find widgets I guess.

It looks empty indeed in the client side since findResultsState only passes down this prop, simply adding the property widgetsCollector to the page and passing that down to my <InstantSearch> component fixed it for me.

Here's an small example:

// ...

export const SearchPage = ({
  searchState,
  resultsState,
  onSearchParameters,
  searchClient,
  widgetsCollector,  // Deconstruct or pass down all ...props
}) => {
  return (
    <InstantSearch
      searchState={searchState}
      resultsState={resultsState}
      indexName="companies"
      searchClient={searchClient || client}
      onSearchParameters={onSearchParameters}
      widgetsCollector={widgetsCollector}
    >
        <RestOfYourComponents />
    </InstantSearch>
  );
};

export const getServerSideProps = async ({ req, res }) => {
  const searchState = urlToSearchState(req.url || "");
  const resultsState = (await findResultsState(SearchPage, { // findResultsState adds widgetsCollector to the SearchPage
    searchClient: client,
    searchState: searchState,
    indexName: "your_search_index",
  }));

  return {
    searchState: JSON.parse(JSON.stringify(searchState)),
    resultsState: JSON.parse(JSON.stringify(resultsState)),
  };
};

@DB-Alex
Copy link

DB-Alex commented Oct 27, 2020

Thanks, I have it working now!

@DB-Alex
Copy link

DB-Alex commented Oct 27, 2020

However SSR side is working but how can we fetch the widgetsCollector client side?

@Haroenv
Copy link
Contributor

Haroenv commented Oct 27, 2020

widgetsCollector is only used on the initial render server side, just like how onSearchParameters was :)

@DB-Alex
Copy link

DB-Alex commented Oct 28, 2020

I also have the bug client side, see attached.

When i refresh the page the SSR renderer kicks in and everything is working.
Screenshot 2020-10-28 at 12 50 01

@Haroenv
Copy link
Contributor

Haroenv commented Oct 29, 2020

could you show this bug in a sandbox perhaps @alexvandervegt? This doesn't seem to happen with the demo: https://codesandbox.io/s/github/algolia/react-instantsearch/tree/master/examples/next?file=/pages/index.js

@DB-Alex
Copy link

DB-Alex commented Oct 29, 2020

I got it working already, was a mistake on my side.

@Haroenv
Copy link
Contributor

Haroenv commented Oct 29, 2020

Were you calling findResultsState on the client too maybe?

@DB-Alex
Copy link

DB-Alex commented Oct 30, 2020

yep...

sheetalkamat pushed a commit to DefinitelyTyped/DefinitelyTyped that referenced this issue Nov 23, 2020
* [react-instantsearch]: add support for latest ssr api

see algolia/react-instantsearch#2978

* correct test & add index type

* prevent wrong lint

* add createInfiniteHitsSessionStorageCache

* missing semicolon
owenlow pushed a commit to owenlow/DefinitelyTyped that referenced this issue Dec 8, 2020
…d#48995)

* [react-instantsearch]: add support for latest ssr api

see algolia/react-instantsearch#2978

* correct test & add index type

* prevent wrong lint

* add createInfiniteHitsSessionStorageCache

* missing semicolon
@miggu
Copy link

miggu commented Jun 1, 2021

I need help with regards to this issue , recently in the process of upgrading to 6 from 5. I have a react app whose every route depends on Algolia to render UI (was working fine), I have found that in SSR, when hitting a Redirect ( basically to add a trailing slash to a url route) , and this not containing any widgets , this is actually causing the SSR to error for the redirects routes . I went to Algolia's source code /node_modules/react-instantsearch-dom/dist/cjs/core/createInstantSearchServer.js (inside the findResultsState function) where it checks to see if there is any widgets , it seems to crash when the array of widgets is empty (which is the case of a redirect not containing them) . Experimentally removing this warning check in Algolias code seems to fix the issue completely. I can even create routes that don't contain Algolia components which is something it's not possible to do with the current setup.

@francoischalifour
Copy link
Member

@miggu What's the structure of your app? Do you wrap it entirely in the InstantSearch component, even though some pages have no widgets?

@miggu
Copy link

miggu commented Jun 3, 2021

Thank you for your answer @francoischalifour , yes we have found a workaround for this by adding a search instance that is in the header this way we will always have at least a widget , this way the is a least a widgets and now the SSR is not crashing, now my question is more ... was that error message necessary as removing this if condition it in the react-instantsearch-dom package simply does not verify for an empty widgets array and the app does not crash. Essentially what causes it to crash is simply that error message.

@dhayab dhayab removed the dhaya label Dec 22, 2022
@dhayab
Copy link
Member

dhayab commented Dec 22, 2022

Hi! We're doing a round of cleanup before migrating this repository to the new InstantSearch monorepo. This issue seems not to have generated much activity lately, so we're going to close it, feel free to reopen if needed.

@dhayab dhayab closed this as completed Dec 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants