Skip to content
Advertisement

Render html from string vuejs

I’m struggling with a problem, I want to create a chat app, and the users to be able to tag each other, by using @. For example, user1 type in chat input ‘hi @user2’, the output should look the same, but ‘@user2’ be a link instead of simple text, I figured how to do that, but the problem is that, if user input for example html tags, it’s rendered as html.

HTML:

<span v-html="chatFormat(chat.text)"></span>

VUE:

chatFormat(text) {
  var words = text.split(" ");
  var newStr = '';
  words.forEach(function (word) {
  if (word.includes('@') >= 1) {
    if (word.charAt(0) == '@') {
      word = '{{ <a href="/user" class="font-weight-bold" style="text-decoration:none">' + word + '</a> }}';
    }
  }
  newStr = newStr + ' ' + word;
  });
  return newStr;
}

Advertisement

Answer

Well, using v-html directive renders value as HTML – it’s not parsed for variables. You could change Your code and get rid of {{}} so only link would appear in the output.

word = '<a href="/user" class="font-weight-bold" style="text-decoration:none">' + word + '</a>';

But, be aware that using v-html to display user-input is a risky thing. User input should be escaped first to get rid of potential harmful code. (You can check Sanitizing user input before adding it to the DOM in Javascript as Michal LevĂ˝ suggested)

I would also suggest using arrow functions and template literals

chatFormat(text) {
  // using let instead of var for declaring variables in the local scope
  let safeText= this.sanitizeHTML(text), // for security reasons
      words = safeText.split(" "),
      newStr = '';

  words.forEach(word => { // arrow function
    if (word.includes('@') >= 1) {
      if (word.charAt(0) == '@') {
        word = `<a href="/user" class="font-weight-bold" style="text-decoration:none">${word}</a>`; // template literal
      }
    }
    newStr = newStr + ' ' + word;
  });

  return newStr;
},

// This should be a secure sanitization method from some library
sanitizeHTML(string) {
  return string
},
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement