stereobooster / react-snap

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

Generate json-files from ajax requests #221

Open goras opened 6 years ago

goras commented 6 years ago

Hi!

I've just started using react-snap together with create-react-app, loadable-components and redux. Everything works great so far. React-snap generates prerendered html for every route that can be used for the initial requests, loadable-components generates js-bundles for all the subsequent navigation/requests and data is fetched in the form of json from a rest-api.

Would it be possible for react-snap to also generate separate json-files along with the prerendered html and make all subsequent requests fetch those instead of burden the rest-api?

Thanks in advance!

stereobooster commented 6 years ago

Huh. I see what you want to do here. This is similar to what Gatsby doing, it "prerenders" not just html, but also data. Yes this is possible, but I will not have time to do it.

How it can be implemented:

  1. reactSnap already intercept every request by browser, so we can track every json request
const ct = response.headers()["content-type"] || "";
if (ct.includes("json" )) {}
  1. use url to build local path of json file, check if it already exists, if it is not then write it to the disc
  2. we will need to support proxy from create-react-app, so that requests to /api/something will be mapped to real api calls at build time, same time they will be calls to static files in production.
  3. profit
goras commented 6 years ago

Thank you for the thorough response!

It all sounds about right, but I do think that creating a PR for this might be a bit over my head. More specifically it's the implementation of no. 3 that is a bit unclear to me.

However, if nobody else shows any interest in creating a PR and you think it's a feature that would benefit react-snap, I might give it a shot ;)

stereobooster commented 6 years ago

It seems like https://github.com/chimurai/http-proxy-middleware should solve most of the problems

stereobooster commented 6 years ago

Other thing which I haven't thought about is how to serialise request params e.g. /api/call?params=123. To do this we will need code which will be shared between client and ReactSnap.

Stanko commented 5 years ago

Hi @stereobooster, Sorry for commenting on the old issue, but I'm willing to help with this one. I have few ideas, and one is to add two callbacks.

The first one would be onJsonFetch, and it would be called in the same place where you cache json on window:

if (cacheAjaxRequests && ct.includes("json")) {
  if (typeof options.onJsonFetch === "function") {
    options.onJsonFetch(route, json);
  }
}

And the second one is onSnapSaveState:

if (
  window.snapSaveState &&
  (state = window.snapSaveState()) &&
  Object.keys(state).length !== 0
) {
  if (typeof onSnapSaveState === "function") {
    onSnapSaveState(route, state);
  }
}

Exposing public interface like this would allow users to cache JSON responses or redux state on the disk. Having a callback is a little bit more flexible, and then we can add gatsby-like recipe.

Let me know what do you think, cheers!