stereobooster / react-snap

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

Only Helmet in index.js file can be crawled by SEO facebook #413

Open minhnguyenit14 opened 4 years ago

minhnguyenit14 commented 4 years ago

Bug Report

create-react-app react-snap v1.23.0

PROBLEM

I have a product introduction web page and i want share the website also its product on facebook. Firstly, i use react-helmet in index file in src folder that create common meta tags for the whole website. Next, in productDetail component, I also use react-helmet to change(replace) the meta tags depends on product that returned from restful API server (title, image, description,... ) Note: my product detail url depends on product name (from api), not static. ex: .../product/sony-tivi_34 -> [sony-tivi] is the name that got from api and [34] is the id of product.

But, facebook cannot crawl the meta from productDetail page, just only and always is the meta from home page, ofcourse the meta changed when i inspect the web page. I cant understand why :?

Try

I thought, maybe, problem is the meta tags must follow by the data from api (async), so i try set static meta for test but it still cant appear on facebook crawler (test on facebook develop debug sharing). I also try to comment the setting meta tags in index, only set meta tag in product detail page, facebook crawl nothing.

Config for react-snap things

package.json Capture

scripts/sw-precache-config image

src/index Capture

src/container/productDetail Capture

Build logs

Capture Capture

Demo http://anguyen.azurewebsites.net

Other problem My scss is broken when first loading or f5 also

bfricka commented 4 years ago

In my experience, Helmet only works w/ React Snap when it's defined at runtime (not within a component). If this is indeed the case, and there are no workarounds, your use case will not work because you won't have access to state when predefining Helmet blocks. To be clear about what I'm describing, here's a simple example that should work:

const HeadContent = (props: {title: string, description: string}) => (
  <Helmet>
    <title>{props.title}</title>
    <meta name="description" content={props.description}/>
  </Helmet>
);

const SOME_PAGE_HEAD = <HeadContent description="Some page description" title="Some Page Title"/>;

const SomePage = () => (
  <>
    {SOME_PAGE_HEAD}
    <SomePageContent/>
  </>
)

As you can see SOME_PAGE_HEAD is defined statically and so can't receive props or state from SomePage. This is obviously unfortunate, since it doesn't allow dynamic head content, unless you're switching on pre-rendered head fragments.