stereobooster / react-snap

👻 Zero-configuration framework-agnostic static prerendering for SPAs
MIT License
5.04k stars 391 forks source link

Snapping page that sends request at startup #453

Closed prokotg closed 4 years ago

prokotg commented 4 years ago

Hi there!

We have been using react-snap in our project to generate static sites so that they can be served by server on Android which is mostly working really good. We had one issue we could not have wrap our heads around and we sort of developed a workaround although not very satisfying to this moment.

We have a react page that sends requests, periodically, to an unavailable (at build time) server, starting right away as user enters the website. In other words, we have setInterval(foo, 300) somewhere in Component construction. The problem is, react-snap timeouts when we set this interval and the workaround is to :

setTimeout(setInterval(foo,300), 5000)

so that react-snap does not have to deal with any external requests.

How to do it properly, so that I can set up an interval from the start?

Cheers!

Daniel15 commented 4 years ago

react-snap uses a user-agent of ReactSnap so you can use that to gate your code. Something like:

if (navigator.userAgent !== 'ReactSnap') {
  setInterval(foo, 300);
}

For my app I created a prerendering.ts module to encapsulate this check:

export const isPrerendering = navigator.userAgent === 'ReactSnap';

Which then lets me do:

import {isPrerendering} from './prerendering';
...
if (!isPrerendering) {
  // Send some request
}

As a side note, for periodically sending requests I'd recommend using setTimeout instead of setInterval, and set the next timeout in the response handler of the request. The reason is that if the request takes longer than the interval (300ms here), you'll have multiple requests overlapping at the same time, whereas with setTimeout you'll only ever have one active request.

prokotg commented 4 years ago

@Daniel15 Hi, this is a little bit late from my side but that works. Thank you :) And thank you for the side note, sometimes it's easy to skip small, obvious things :)