javascriptreactjsnext.jswp-api

Rendering external HTML/React components dynamically in React


Is it possible to take HTML/JSX content from an external source and render it in dynamically in React? In our case we want to take content from the Wordpress API and render it on both the client and the server (we're using NextJS)

So, the Wordpress API returns a JSON response which includes a content property which is a string of HTML/JSX. the content would look something like this.

{
    content: "<div><Slider imageCount="5" galleryID="1"></Slider><span>This is an image gallery</span></div>"
}

So, as you can see it would be a mix of HTML and React components/JSX, represented as a string

I would use Axios to make a call to get the content (on both server and client using NextJS's getInitialProps() method), then I need to render it, but i'm new to react and I can see a couple of problems.

1) In React, JSX is compiled at build time, not run time, I can't see how to get round this (It would have been easy in Angular using $compile service for example).

2) As we don't know what components the content from Wordpress is going to use, we'd have to import every single one of them at the top of the page, the content may include a component or it may include a component, who knows?.

Right now, I'm thinking this isn't possible, which would mean we'd have to reconsider using React, but I'm really hoping somebody has an answer.

Any help would really be appreciated.


Solution

  • Interesting problem!

    You should try react-jsx-parser. I think it solves your problems. Not sure how it works with Next JS - I have no experience with Next JS.

    Check out this sandbox: Edit 24r1ypp00p


    You are right about all the components getting bundled. There is a workaround for that. :)

    Check out this sandbox: Edit 24r1ypp00p

    I've created a dynamicComponent that expects an import promise and returns a component.

    I changed the way A, B and C components are imported in index.js. This way each dynamically imported component gets a separate bundle and is only requested when needed.

    This should solve your second problem.