1

This is all about having translation text strings and implementing them in JSX.

Lets say I have two strings. One for english and another for spanish like this:

English

const phrase = `this is just a string with some [replace]weird[/replace] link inside`

Spanish

const phrase = `esto es solo un string con un [replace]raro[/replace] enlace dentro`

When I am in English mode the string will of course come as the first example.

I am trying to replace the [replace]word inside[/replace] with a component like this.

<p dangerouslySetInnerHTML={{
    __html: phrase.replace(/\[replace\](.*)\[\/replace\]/, <Link to={linkurl} >test</Link>)
}}>

The output is: this is just a string with some [object Object] link inside

This one works fine, using just plain html tags

<p dangerouslySetInnerHTML={{
    __html: phrase.replace(/\[replace\](.*)\[\/replace\]/, "<b>$1</b")
  }}>
</p>

the output is: this is just a string with some weird link inside

I've also tried the following:

<p dangerouslySetInnerHTML={{
    __html: phrase.replace(/\[replace\](.*)\[\/replace\]/, "<Link to=\""+linkurl+"\">$1</Link>")
  }}>
</p>

the output is: this is just a string with some weird link inside

but the word 'weird' should be a link element, and it's not...

By the way the component is just a component from gatsby, it allows you to navigate with routing (currently using reach router).

5
  • The problem is JSX code <Link to={linkurl} >test</Link> will get converted to React.CreateElement(...) and it's in the end indeed the object, which you can see as the result. Check: stackoverflow.com/questions/19266197/reactjs-convert-to-html or maybe google for react to html Commented Nov 11, 2018 at 19:20
  • the question is, why do you need to add a JSX object in the variable? It would be easier to try to add the component and just replace either the url, or the text, or whatever. Is there a specific use case that you have so we can suggest an alternative? Commented Nov 11, 2018 at 19:32
  • @c-chavez I can agree with the argument, on the other hand sometimes you really need to replace JSX with static markup. Here is more info to the topic: medium.com/@arkadiusz.machalica/… Commented Nov 11, 2018 at 19:35
  • @c-chavez these strings come from a db, translated by other ppl (i just used a random phrase here as example). Sometimes you need a hyperlink in between the words of a phrase or pharagraph that varies depending on the language, so we just use simple template format and then replace it with the proper html code. But we are talking with React+Gatsby here. Commented Nov 11, 2018 at 21:44
  • I managed to "make it work", at least make it render the anchor from the gatsby <Link> component by using `ReactDOMServer.renderToString(<Link to="/">anchor</Link>) but Reach Router from Gatsbyjs is not picking up the Link with JS, so everytime i click the link it reloads the entire page instead of navigating with js... it can render the <a> anchor element w/o problems. Commented Nov 11, 2018 at 21:45

1 Answer 1

1

This is pretty easy to do if you treat your text templates as Markdown:

  1. Replace keywords with Markdown link syntax ([linked phrase](https://www.example.com/))
  2. Run the markdown through markdown-to-jsx to convert it to JSX
  3. Use the overrides option to use a custom component with a tags (e.g. a wrapper that extracts the href and provides it as the to prop on Gatsby's Link).

If you want a leaner pipeline, you could piece something together with dangerouslySetInnerHTML but it won't be as flexible or easily sanitized.

Example code:

import * as React from "react"
import Link from "gatsby"
import Markdown from "markdown-to-jsx"

const MagicText = ({ children, linkUrl }) => (
  <Markdown
    options={{
      overrides: {
        replace: Link,
      },
    }}
  >
    {children
      .replace("[replace]", `<replace to=${linkUrl}>`)
      .replace("[/replace]", "</replace>")}
  </Markdown>
)

And in use:

<MagicText linkUrl="https://www.example.com/">{phrase}</MagicText>
Sign up to request clarification or add additional context in comments.

1 Comment

I'm glad you understood my problem! This solution looks neat. I will try that in a few hours and see if it works like charm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.