1

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;
}
PLASMA chicken
  • 2,777
  • 2
  • 15
  • 25

2 Answers2

3

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
},
Jan Madeyski
  • 349
  • 1
  • 9
0

A subject that has been discussed an number of times.

in Vuejs.org: https://v2.vuejs.org/v2/api/#v-html

in stackoverflow.com: (one of many) Rendering html tags in Vue.js

tony19
  • 125,647
  • 18
  • 229
  • 307