How do i replace some text template with a custom JSX Component in ReactJS?

3k Views Asked by At

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).

1

There are 1 best solutions below

1
On BEST ANSWER

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>