ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.41k stars 777 forks source link

feat: support GatsbyJS replaceRenderer by hydrating a React element #3202

Closed BrunnerLivio closed 2 years ago

BrunnerLivio commented 2 years ago

Prerequisites

Describe the Feature Request

GatsbyJS added a replaceRenderer lifecycle hook which would be a perfect fit for Stencil! Unfortunately, GatsbyJS only passes a React element to the function. This means the current hydrate.* functions can not be used.

Describe the Use Case

Better support for StencilJS in GatsbyJS. The current solution (gatsby-plugin-stencil) unfortunately does not work nicely with GatsbyJS incremental build features because it does not follow Gatsbys best practices.

An integration with replaceRenderer would fix that!

Describe Preferred Solution

Expose a function like renderToString which can take a React Element as a parameter.

Describe Alternatives

No response

Related Code

No response

Additional Information

No response

BrunnerLivio commented 2 years ago

It seems like this is the way to go:

const ReactDOMServer = require('react-dom/server')
const hydrate = require('<STENCIL_LIBRARY>/hydrate')

export async function replaceRenderer({ bodyComponent, replaceBodyHTMLString }) {

    const { html, diagnostics = [] } = await hydrate.renderToString(ReactDOMServer.renderToString(bodyComponent), {
        removeHtmlComments: true,
        removeScripts: true,
    })

    diagnostics.forEach((diagnostic) =>
        console.error(
            `error pre-rendering file: ${JSON.stringify(
                diagnostic,
                null,
                "  "
            )}`
        )
    );

    if (html) {
        replaceBodyHTMLString(html)
    }
}

Haven't been able to get it fully working, but I am getting closer