reactjslazy-loadingserver-side-renderingreact-lazy-load

Lazy-loading React components under SSR


I have a ReactJS app built with react-lazy-load-image-component in order to improve performance.

My code wraps components that take time to initialize with something like:

<h2 className={styles.sectionTitle}>Categories</h2>
<Row>
  {categories &&
    categories.map((category, index) => {
      if (category.image) {
        return (
          <Col
            xs={6}
            md={4}
            key={index}
            className={[
              'col-xs-4 col-md-4 col-lg-4 col-xl-3',
              styles.thumbnail
            ].join(' ')}
          >
            <LazyLoadComponent>
              <CategoryButton {...category} />
            </LazyLoadComponent>
          </Col>
        );
      }
      return null;
    })}
</Row>

It is working fine. However, this there is the lazy-load, SSR prints my markup as:

<h2>Categories</h2>
<div class="row"></div>

I want the server to print everything, so crawlers would have an easy time indexing my pages. The library that I am using supports the visibleByDefault property, which is probably the way to go.

I am just wondering how to pass it from my loader doing:

<Capture report={m => modules.push(m)}>
  <Provider store={store}>
    <StaticRouter location={req.url} context={context}>
      <Frontload isServer={true}>
        <App />
      </Frontload>
    </StaticRouter>
  </Provider>
</Capture>

all the way to each <LazyLoadComponent>?

Suggestions?


Solution

  • I ended-up doing:

    import React from 'react';
    
    import { LazyLoadComponent } from 'react-lazy-load-image-component';
    import useSSR from 'use-ssr';
    
    const LazyLoad = ({ children }) => {
      var { isServer } = useSSR();
      return (
        <LazyLoadComponent visibleByDefault={isServer}>
          {children}
        </LazyLoadComponent>
      );
    };
    
    export default LazyLoad;