Next.js Discord

Discord Forum

How to mark parts of the string for emphasis in JSON, and render them accordingly?

Answered
Satin Angora posted this in #help-forum
Open in Discord
Satin AngoraOP
I store the strings that I use in the components in JSON files, created for different languages. However, I want to mark some of the words in strings i use for my headings for emphasis, and render them with <em>.

How should I go about this?
Answered by Rafael Almeida
you need to parse the string, separating each part of the highlighted text into different array items so you can iterate through all of them rendering different elements for each text part. there are libraries that already do all the hard work: https://www.npmjs.com/package/react-highlight-words
View full answer

5 Replies

you need to parse the string, separating each part of the highlighted text into different array items so you can iterate through all of them rendering different elements for each text part. there are libraries that already do all the hard work: https://www.npmjs.com/package/react-highlight-words
Answer
Satin AngoraOP
Thank you, I will check the library to see how they solved the issue. I will try a few things.
Satin AngoraOP
For further reference, I made a utility method to solve this problem. First, I architectured my dictionary JSON like;
{
  "page": {
    "header": "...",
    "header-marks": ["...", "..."],
    ...
  }
}
where I add strings that needs to be marked in an array, in left-to-right fashion, following the string label.
And I pass the string which needs to be marked to this utility:
export enum MarkType {
  Emphasis,
  Strong
}

const parseMarkedString = (str: string, marks: string[], type: MarkType) => {
  const separatedContents: string[] = [str]

  marks.forEach((markedContent) => {
    const pattern = "(" + markedContent + ")"
    
    const lastEl = separatedContents.pop()
    const splitRes = lastEl!
      .split(new RegExp(pattern, "g"))
      .filter(str => str.length != 0) 

    separatedContents.push(...splitRes)
  })

  return <>{
    separatedContents.map((part: string) => {
      if (marks.includes(part)) {
        return markString(part, type)
      } else {
        return part
      }
    })
  }</>
}

const markString = (str: string, type: MarkType) => {
  switch (type) {
    case MarkType.Emphasis: return <em>{str}</em>
    case MarkType.Strong: return <strong>{str}</strong>
  }
}
Which returns the content with Fragments to add into element's content