react-snap icon indicating copy to clipboard operation
react-snap copied to clipboard

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

Open ShayanJavadi opened this issue 5 years ago • 6 comments

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

ShayanJavadi avatar May 03 '19 14:05 ShayanJavadi

I think SSR is better for dynamic pages/content

Fluorz avatar Jul 05 '19 12:07 Fluorz

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

stereobooster avatar Jul 14 '19 08:07 stereobooster

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.

ifier avatar Sep 03 '19 09:09 ifier

@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

brohlson avatar Oct 22 '19 00:10 brohlson

@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?

marcuszierke avatar Feb 01 '20 19:02 marcuszierke

@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

omkarajagunde avatar Apr 03 '21 12:04 omkarajagunde