Gatsby: Pass `PageComponent` prop to `wrapPageElement` APIs

Created on 17 Jul 2019  路  8Comments  路  Source: gatsbyjs/gatsby

I'm using gatsby-plugin-layout for sharing states that persist across routes. Can pages be components instead of elements when passed to Layout as children?

So, instead of

export default function Layout ({ children }) {
  return <State>{children}</State>
}

It can be

export default function Layout ({ PageComponent }) {
  return <State><PageComponent /></State>
}

This is similar to how Next.js does it https://nextjs.org/docs#custom-app.
Use case is passing props from Layout to page components. Since page is direct children of layout, using Context can be a bit of an overkill for some cases.
I understand that React.cloneElement can be used. Yet, I feel that passing props to components is more idiomatic.

help wanted not stale

Most helpful comment

I did some checking and there might be potential issues with https://www.gatsbyjs.org/docs/browser-apis/#replaceComponentRenderer (legacy/deprecated API) - this API allow you to replace Page Component - in v1 of gatsby it was used mostly for the same purpose as wrapPageElement to wrap page component with something - but it returns react element (not component) - which means that if you would not use children, it would discard results of that API. We don't use the API anywhere in plugins we maintain, but we don't really know if any 3rd party plugins still use that.

This is not strictly blocker - we can put Note in docs about this - just something to keep in mind.

All 8 comments

Not cleanest, but you can do it like this:

export default function Layout({ children, ...props }) {
  const PageComponent = props.pageResources.component
  return <State><PageComponent {...props} extraProp="Hi" /></State>
}

Note that you probably should pass original props (as I did in my example) - otherwise page components could miss things like query results or location (some props that we pass by default to page components)

Seems like pageResources isn't available during SSR. console.log(props.pageResources) gives undefined in CLI but in browser it works as expected.

Yeah, you are right. I think it's reasonable request to pass PageComponent as top-level arg/prop and make sure it works both in runtime and ssr.

I did some checking and there might be potential issues with https://www.gatsbyjs.org/docs/browser-apis/#replaceComponentRenderer (legacy/deprecated API) - this API allow you to replace Page Component - in v1 of gatsby it was used mostly for the same purpose as wrapPageElement to wrap page component with something - but it returns react element (not component) - which means that if you would not use children, it would discard results of that API. We don't use the API anywhere in plugins we maintain, but we don't really know if any 3rd party plugins still use that.

This is not strictly blocker - we can put Note in docs about this - just something to keep in mind.

Thank you very much for looking into this.

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.

If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!

As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contributefor more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

not stale

Yeah, you are right. I think it's reasonable request to pass PageComponent as top-level arg/prop and make sure it works both in runtime and ssr.

@pieh I'm a bit confused by this. Could you show an example please? This is my current code for wrapPageElement in gatsby-browser.js...

exports.wrapPageElement = ({ props }) => {
  const PageComponent = props.pageResources.component;
  return (
    <>
      <Layout {...props}>
        <PageComponent {...props} />
      </Layout>
    </>
  );
};

How would one do the same in gatsby-ssr.js if implementing your recommendation?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rossPatton picture rossPatton  路  3Comments

3CordGuy picture 3CordGuy  路  3Comments

jimfilippou picture jimfilippou  路  3Comments

KyleAMathews picture KyleAMathews  路  3Comments

Oppenheimer1 picture Oppenheimer1  路  3Comments