4

I'm working on an app for a client who wants to display Zendesk Support article data with richer content than the API/tool supports. The API, powered by a basic WYSIWYG editor on Zendesk, is able to serve up an HTML blob with <p> and <img> and <a> tags. But it's unable to, say, easily embed a video, show an image gallery, or link to another location in the app without necessitating a hard refresh.

So we decided to build out a small amount of DSL syntax whereby the client could type something that would be parsed on our app and turned into the richer content. For example:

[[ video src="youtube.com/whatever" ]]

might, on our app, be parsed out, and replaced with an iframe embedding that video directly in the article.

I've got the above example working just fine, using all sorts of fun/problematic RegExp magic.

I'm aware that parsing HTML with RegExp is a major anti-pattern, and I'm getting around it by not really parsing HTML per se -- I'm just looking for [[...]]).

Basically, I parse each code out, determine what to replace it with, pass back that component, and then call ReactDOMServer.renderToString(replacementEl) to insert the resulting HTML into the article HTML string, which is then rendered to the page using dangerouslySetInnerHtml.

This is working great, despite all the obvious messiness issues. (I know, but the client wants a very feature-rich solution, and wants to use the Zendesk API).

Here's the problem: This solution only works when rendering HTML. It doesn't work when I try to render, for example, a <Link> (from React Router) or a home-made <Gallery /> component.

So I'm trying to figure out if there's a good way to do this. One that ideally doesn't involve going full RegExp on the HTML blob (which is obviously a mess).

I'm guessing that the solution will involve removing the codes, converting the code-free HTML string into actual React components (as opposed to just spitting the string into another element), and then, based on some sort of ledger of where the short codes go in this new React component, inserting the contents into the page.

But I'd appreciate some suggestions if anyone has encountered a similar problem. I want to do this in a way that isn't totally crazy and brittle, though it's obviously an inherently messy problem.

EDIT: To clarify, when I say it doesn't work, what I mean is that the JavaScript associated with the React components doesn't run. If I replace a code with a <Link to="whatever" />, for example, ReactDOMServer.renderToString successfully turns that component into its final HTML (an <a> tag), but nothing happens on click of that tag, because the JavaScript that's actually changing browserHistory on a regular click just isn't run.

So maybe the more pointed question is:

Is there a way to insert React Components into an HTML string in such a way that they retain their JavaScript functionality and don't just become HTML?

Community
  • 1
  • 1
Sasha
  • 6,224
  • 10
  • 55
  • 102
  • Is there a way to add your own javascript to the page? If so, might be able to heavily abuse the paragraph tag and render all your react components as paragraphs. It's kind of a depressing solution semantically but might work. – user2027202827 Apr 22 '17 at 04:55
  • I'm not sure I understand what you mean. Add my own JavaScript to the Zendesk HTML? That's technically possible, but not something my client, who will be creating the content can/will do. Not sure how that would fix it, though, unfortunately. I'll explain more about the problem above to clarify – Sasha Apr 24 '17 at 18:04
  • Yes, I ask because as you found out, renderToString only produces the html of your component. It's like a snapshot of its state. If you can add javascript though, you could add the react library (or others: x-tags and polymer were very appealing to me when I was trying to solve a similar problem). Obviously you would need the ability to add javascript to the page though (not from just within the editor itself). If you can pass that hurdle though, you could render full components (react, x-tags, ...) and not need to call to the server to do it. – user2027202827 Apr 26 '17 at 03:55
  • This probably wont help you're situation now, but if you ever have a little more control over your editor, I've found that the framework provided by DraftJS is a pretty amazing improvement over what's available with most web based editors. – user2027202827 Apr 26 '17 at 04:04

0 Answers0