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

How to get and serve HTML fragments?

Open napolux opened this issue 4 years ago • 3 comments

I was wondering how can I render an HTML fragment which is not a component...

For example: Let's say that example.com/esi-fragment is serving

<div> content </div>

So, as per ESI i can do something like this in an example.com page

<esi:include src="/esi-fragment"/>

And I should see the div rendered in my page.

In all the examples I see online I only can see react components rendered... Which is working, but not really what I want to do.... Is there something I'm getting wrong?

Thanks!

napolux avatar Nov 20 '19 14:11 napolux

Unfortunately it cannot work like that because client-side React will try to re-conciliate with the HTML that has been generated sever side. If you're not using a React component, when the client-side React will execute, you'll got a warning and the extra HTML (the content of the ESI block) will be discarded.

It's why the fragment must be a React component.

dunglas avatar Nov 20 '19 23:11 dunglas

I actually came up with this, which works, but... Will your assumption be still valid?

Unfortunately it cannot work like that because client-side React will try to re-conciliate with the HTML that has been generated sever side.

export default class Header extends React.Component<HeaderProps> {
    render() {
        const htmlFragment = {__html: this.props.dataFromMicroservice};
        return (
            <section>
                <div dangerouslySetInnerHTML={htmlFragment} />
            </section>
        );
    }

    static async getInitialProps({ res }) {

        // this is where will retrieve HTML from microservice, now just a placeholder
        const data = await fetch('https://www.example.com'); 
        const html = await data.text();

        return new Promise(resolve => {
            if (res) {
                // Set a TTL for this fragment
                res.set('Cache-Control', 's-maxage=60, max-age=30');
            }

            resolve({
                dataFromMicroservice: html
            })
        });
    }

Which wil be used like...

const HeaderESI = withESI(Header, 'id');
...
...
...
<HeaderESI />

napolux avatar Nov 21 '19 08:11 napolux

@napolux This would work as whatever is inside dangerouslySetInnerHTML won't be tracked by React.

Unfortunately it cannot work like that because client-side React will try to re-conciliate with the HTML that has been generated sever side

Doesn't apply in you sample

jaszczw avatar Apr 20 '20 04:04 jaszczw