stereobooster / react-snap

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

How to prerender dynamic (blog post/product page/etc) pages created from cms? #369

Open ShayanJavadi opened 5 years ago

ShayanJavadi commented 5 years ago

Let's say I'm getting the data for 10 products from a cms (contentstack) in my case and I can pass these to a product page as query strings.

Is there any way to prerender these dynamic pages?

sorry if this is a dumb question just trying to wrap my head around this whole prerender/ssr thing

Fluorz commented 5 years ago

I think SSR is better for dynamic pages/content

stereobooster commented 4 years ago

You can try to create an "index" page with list of all pages generated by CMS, then react-snap will crawl those. This use case is less optimal for react-snap. You can take a look at react-static, which can handle this case better

ifier commented 4 years ago

You can try to create an "index" page with list of all pages generated by CMS, then react-snap will crawl those. This use case is less optimal for react-snap. You can take a look at react-static, which can handle this case better

Hi. Can you please give us small part of code? Trying to choose technology for SEO as well and it seems like that SSR is better, but not for the server (if it is high loaded).

For example: 1) Homepage - I have a request to the API and getting a list of products (componentDidMount) 2) Rendering them with links - /products/:id (from local state or Redux)

Will react-snap crawl such dynamic pages?

PS: Thank for your work. Awesome plugin.

brohlson commented 4 years ago

@ShayanJavadi @ifier You'll need to do your fetching at build-time, render out the <Route /> components from your fetch & pass the page data to the routed component in order for the SEO value & fully static rendering to be effective. Really similar to how Gatsby & React static do things.

Like this:

export default function BlogSitemap() {
  const { data } = useAsync({ promiseFn: myApiCall });
  function getBlogRoutes() {
    return data.map((page, index) => (
      <Link key={index} to={`blog/${page.slug}`}>
        <Route key={index} path={`/blog/${page.slug}`}>
           <Blog {...page} />
        </Route>
      </Link>
    ));
  }
  return (
    <Wrapper>
        <Router>{getBlogLinks()}</Router>
    </Wrapper>
  );
}

Full example: https://github.com/brohlson/parcel-react-ssr/blob/master/src/App.js

marcuszierke commented 4 years ago

@ShayanJavadi @ifier You'll need to do your fetching at build-time, render out the <Route /> components from your fetch & pass the page data to the routed component in order for the SEO value & fully static rendering to be effective. Really similar to how Gatsby & React static do things.

Like this:

export default function BlogSitemap() {
  const { data } = useAsync({ promiseFn: myApiCall });
  function getBlogRoutes() {
    return data.map((page, index) => (
      <Link key={index} to={`blog/${page.slug}`}>
        <Route key={index} path={`/blog/${page.slug}`}>
           <Blog {...page} />
        </Route>
      </Link>
    ));
  }
  return (
    <Wrapper>
        <Router>{getBlogLinks()}</Router>
    </Wrapper>
  );
}

Full example: https://github.com/brohlson/parcel-react-ssr/blob/master/src/App.js

I have a project setup exactly like that and once I build (push to Heroku) it fetches all the slugs automatically due to an API call. But how can I make sure that this call only happens during build? Atm the API call is also been made once I visit the Blog page on the website although the content is served from a static file on the sever. I put it in a context and only deliver the context to the routes where the API fetched data is needed but if I build the sites static anyways - there is no need for that anymore, is there?

omkarajagunde commented 3 years ago

@ShayanJavadi @ifier You'll need to do your fetching at build-time, render out the <Route /> components from your fetch & pass the page data to the routed component in order for the SEO value & fully static rendering to be effective. Really similar to how Gatsby & React static do things. Like this:

export default function BlogSitemap() {
  const { data } = useAsync({ promiseFn: myApiCall });
  function getBlogRoutes() {
    return data.map((page, index) => (
      <Link key={index} to={`blog/${page.slug}`}>
        <Route key={index} path={`/blog/${page.slug}`}>
           <Blog {...page} />
        </Route>
      </Link>
    ));
  }
  return (
    <Wrapper>
        <Router>{getBlogLinks()}</Router>
    </Wrapper>
  );
}

Full example: https://github.com/brohlson/parcel-react-ssr/blob/master/src/App.js

I have a project setup exactly like that and once I build (push to Heroku) it fetches all the slugs automatically due to an API call. But how can I make sure that this call only happens during build? Atm the API call is also been made once I visit the Blog page on the website although the content is served from a static file on the sever. I put it in a context and only deliver the context to the routes where the API fetched data is needed but if I build the sites static anyways - there is no need for that anymore, is there?

You can detect the platform maybe https://github.com/facebook/react-devtools/blob/faa4b630a8c055d5ab4ff51536f1e92604d5c09c/backend/installGlobalHook.js#L23