appbaseio / reactivesearch

Search UI components for React and Vue
https://opensource.appbase.io/reactivesearch
Apache License 2.0
4.9k stars 468 forks source link

enable pagination during SSR #441

Closed aol-nnov closed 6 years ago

aol-nnov commented 6 years ago

Issue Type: enhancement

Platform: Web

Description:

For me, the main idea behind SSR is to make web app crawlable (including dummy crawlers, which do not execute javascript).

So, for testing purposes I fired your demo packages/web/examples/ssr, disabled javascript in the browser and navigated to localhost:3000.

First page renders just fine, but pagination buttons do not function at all until I enable js back. It would be nice, if pagination buttons work without js and with URLParams enabled in ResultCard

Reactivesearch version: dev branch

Browser: all

metagrover commented 6 years ago

This is interesting.

I think if we add the href attribute on the pagination <a> buttons and add event.preventDefault() in the onClick function definition, it can work.

Do you want to give this a shot? Open to accepting PRs on this.

aol-nnov commented 6 years ago

@metagrover I've just tried to add ?SearchResult-page=2 while js is disabled and nothing happened. Seems like I need the same answer as in #440 :)

metagrover commented 6 years ago

?SearchResult-page=2 is correct. It takes the query param from the request object.

It seems I missed out on the implementation for considering pages in SSR. I will check and get back to you on this 🐱

aol-nnov commented 6 years ago

Deepak @metagrover , did you have any chance to look into this already? Any hints would be appreciated! :)

metagrover commented 6 years ago

@aol-nnov Thanks for the patience on this. I will look into it today.

metagrover commented 6 years ago

Fixed here: c6d3be2 and will be released in 2.7.0 🎉

aol-nnov commented 6 years ago

Deepk, unfortunately I still do not see any changes in 2.7.0

Here is how I perform test: the very same packages/web/examples/ssr example from dev branch with minor change:

diff --git a/packages/web/examples/ssr/pages/index.js b/packages/web/examples/ssr/pages/index.js
index f2e49a4..6d6d6df 100644
--- a/packages/web/examples/ssr/pages/index.js
+++ b/packages/web/examples/ssr/pages/index.js
@@ -78,6 +78,7 @@ const components = {
                        url: data.listing_url,
                }),
                pagination: true,
+              URLParams: true,
                react: {
                        and: ['SearchSensor', 'GuestSensor'],
                },

then npm install && npm run dev And finally I launch firefox with javascript.enabled: false in about:config

After that preparations I see exactly the same images and descriptions in ResultCard if I navigate to http://localhost:3000/?SearchResult=1 or http://localhost:3000/?SearchResult=2

Not sure if it's a reactivesearch issue, because if I curl those two urls and then diff the results, they actually differ! I'll digg more, but what do you think about it?

aol-nnov commented 6 years ago

Dug a bit more

--- a/packages/web/examples/ssr/pages/index.js
+++ b/packages/web/examples/ssr/pages/index.js
@@ -66,7 +66,9 @@ const components = {
                componentId: 'SearchResult',
                dataField: 'name',
                size: 12,
-           onData: data => ({
+         onData: data => {
+             console.debug(data);
+             return {
                        image: data.image,
                        title: data.name,
                        description: (
@@ -76,8 +78,9 @@ const components = {
                                </div>
                        ),
                        url: data.listing_url,
-           }),
+         }},
                pagination: true,
+         URLParams: true,
                react: {
                        and: ['SearchSensor', 'GuestSensor'],
                },

and it revealed that despite of ?SearchResult=1 or ?SearchResult=2 the same result set is returned. So, it does not look like firefox issue now...

aol-nnov commented 6 years ago

ouch! 4.1.0, may be? :) (since last commit to reactive core reads as 'v4.1.0')

metagrover commented 6 years ago

Hi @aol-nnov, make sure you're passing the correct search state to the initReactiveSearch function.

For instance, given the url query param ?abc=xyz (which you can get from the request object at the server end), you'll have to pass the search state here instead of null, and search state is simply an object as:

{
    abc: 'xyz',
}

Hope that helps!

aol-nnov commented 6 years ago

@metagrover , awesome, awesome, awesome!!1 thank you for that reminder and a quick response!

now it works like a charm! with nextjs it was a simple change:

diff --git a/packages/web/examples/ssr/pages/index.js b/packages/web/examples/ssr/pages/index.js
index f2e49a4..130a522 100644
--- a/packages/web/examples/ssr/pages/index.js
+++ b/packages/web/examples/ssr/pages/index.js
@@ -78,6 +78,7 @@ const components = {
                        url: data.listing_url,
                }),
                pagination: true,
+         URLParams: true,
                react: {
                        and: ['SearchSensor', 'GuestSensor'],
                },
@@ -91,7 +92,7 @@ const components = {
 };

 export default class Main extends Component {
-   static async getInitialProps() {
+ static async getInitialProps({ pathname, query }) {
                return {
                        store: await initReactivesearch(
                                [
@@ -116,7 +117,7 @@ export default class Main extends Component {
                                                source: ResultCard,
                                        },
                                ],
-                           null,
+                         query,
                                components.settings,
                        ),
                };

I'll submit a pr for example update! Also I plan to make another one for pagination as we discussed at the beginning of this issue.

aol-nnov commented 6 years ago

@metagrover I'm not sure how to correctly access to whole query string from Pagination component.

Naive approach was to pass componentId from parent component and then adding something like href={'?' + this.props.componentId + '=' + i} to the Button, but I'm afraid this approach won't always work well...

Any hints would be appreciated!

metagrover commented 6 years ago

I think it's best if we apply these hrefs to the pagination component at the library end. Can you open a separate issue for this?

aol-nnov commented 6 years ago

sure thing! where should I post it? reactivecore or somewhere else?

metagrover commented 6 years ago

This repo (reactivesearch) would be the ideal place.

At core, we handle the query formation, watcher and state related logic.