Contribute to this guideReport an issue

Mentions, Tags and Emoji Documentation

The optional Mentions and Emoji plugins, introduced in CKEditor 4.10, support inserting mentions, tags and emojis into the editor content. Both features were built on top of the Autocomplete plugin that provides a base for smart autocompletion functionality for custom text matches based on user input.

Every time the user types the selected, pre-configured marker into the editor, available autocomplete suggestions are displayed in the dedicated dropdown and can be inserted into the content with Enter or Tab keys. Use the sample below to try out some autocomplete suggestions:

  • Start with @ to mention a user.
  • Start with # to insert a food-related tag. Type at least 1 character e.g. #f
  • Start with : to insert a Unicode emoji character. Type at least 2 characters e.g. :fa
  • avatar
    Charles Flores @cflores 2 hours ago

    Thanks for another #yummy recipe, @dwilliams! Makes me #hungry just looking at the photos 😋. Definitely adding it to my TODO list for our next #mediterranean potluck.

  • avatar
    Mildred Wilson @mwilson 4 hours ago

    Really appreciate the #vegetarian and #vegan variations of your recipes. So thoughtful of you! 🌱

Check the documentation for the Mentions and Emoji plugins for some customization options. Read more about the Autocomplete feature if you want to implement a custom smart completion mechanism.

Related Features

Get Sample Source Code

  • Mentions, Tags and Emoji
                    <!doctype html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8">
      <meta name="robots" content="noindex, nofollow">
      <title>Mentions, Tags and Emoji</title>
      <script src="https://cdn.ckeditor.com/4.11.1/standard-all/ckeditor.js"></script>
    </head>
    
    <body>
      <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href=&quot;https://ckeditor.com/&quot;&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
      <script>
        var users = [{
              id: 1,
              avatar: 'm_1',
              fullname: 'Charles Flores',
              username: 'cflores'
            },
            {
              id: 2,
              avatar: 'm_2',
              fullname: 'Gerald Jackson',
              username: 'gjackson'
            },
            {
              id: 3,
              avatar: 'm_3',
              fullname: 'Wayne Reed',
              username: 'wreed'
            },
            {
              id: 4,
              avatar: 'm_4',
              fullname: 'Louis Garcia',
              username: 'lgarcia'
            },
            {
              id: 5,
              avatar: 'm_5',
              fullname: 'Roy Wilson',
              username: 'rwilson'
            },
            {
              id: 6,
              avatar: 'm_6',
              fullname: 'Matthew Nelson',
              username: 'mnelson'
            },
            {
              id: 7,
              avatar: 'm_7',
              fullname: 'Randy Williams',
              username: 'rwilliams'
            },
            {
              id: 8,
              avatar: 'm_8',
              fullname: 'Albert Johnson',
              username: 'ajohnson'
            },
            {
              id: 9,
              avatar: 'm_9',
              fullname: 'Steve Roberts',
              username: 'sroberts'
            },
            {
              id: 10,
              avatar: 'm_10',
              fullname: 'Kevin Evans',
              username: 'kevans'
            },
    
            {
              id: 11,
              avatar: 'w_1',
              fullname: 'Mildred Wilson',
              username: 'mwilson'
            },
            {
              id: 12,
              avatar: 'w_2',
              fullname: 'Melissa Nelson',
              username: 'mnelson'
            },
            {
              id: 13,
              avatar: 'w_3',
              fullname: 'Kathleen Allen',
              username: 'kallen'
            },
            {
              id: 14,
              avatar: 'w_4',
              fullname: 'Mary Young',
              username: 'myoung'
            },
            {
              id: 15,
              avatar: 'w_5',
              fullname: 'Ashley Rogers',
              username: 'arogers'
            },
            {
              id: 16,
              avatar: 'w_6',
              fullname: 'Debra Griffin',
              username: 'dgriffin'
            },
            {
              id: 17,
              avatar: 'w_7',
              fullname: 'Denise Williams',
              username: 'dwilliams'
            },
            {
              id: 18,
              avatar: 'w_8',
              fullname: 'Amy James',
              username: 'ajames'
            },
            {
              id: 19,
              avatar: 'w_9',
              fullname: 'Ruby Anderson',
              username: 'randerson'
            },
            {
              id: 20,
              avatar: 'w_10',
              fullname: 'Wanda Lee',
              username: 'wlee'
            }
          ],
          tags = [
            'american',
            'asian',
            'baking',
            'breakfast',
            'cake',
            'caribbean',
            'chinese',
            'chocolate',
            'cooking',
            'dairy',
            'delicious',
            'delish',
            'dessert',
            'desserts',
            'dinner',
            'eat',
            'eating',
            'eggs',
            'fish',
            'food',
            'foodgasm',
            'foodie',
            'foodporn',
            'foods',
            'french',
            'fresh',
            'fusion',
            'glutenfree',
            'greek',
            'grilling',
            'halal',
            'homemade',
            'hot',
            'hungry',
            'icecream',
            'indian',
            'italian',
            'japanese',
            'keto',
            'korean',
            'lactosefree',
            'lunch',
            'meat',
            'mediterranean',
            'mexican',
            'moroccan',
            'nom',
            'nomnom',
            'paleo',
            'poultry',
            'snack',
            'spanish',
            'sugarfree',
            'sweet',
            'sweettooth',
            'tasty',
            'thai',
            'vegan',
            'vegetarian',
            'vietnamese',
            'yum',
            'yummy'
          ];
    
        CKEDITOR.replace('editor1', {
          plugins: 'mentions,emoji,basicstyles,undo,link,wysiwygarea,toolbar',
          contentsCss: [
            'http://cdn.ckeditor.com/4.11.1/full-all/contents.css',
            'https://ckeditor.com/docs/vendors/4.11.1/ckeditor/assets/mentions/contents.css'
          ],
          height: 150,
          toolbar: [{
              name: 'document',
              items: ['Undo', 'Redo']
            },
            {
              name: 'basicstyles',
              items: ['Bold', 'Italic', 'Strike']
            },
            {
              name: 'links',
              items: ['EmojiPanel', 'Link', 'Unlink']
            }
          ],
          mentions: [{
              feed: dataFeed,
              itemTemplate: '<li data-id="{id}">' +
                '<img class="photo" src="assets/mentions/img/{avatar}.jpg" />' +
                '<strong class="username">{username}</strong>' +
                '<span class="fullname">{fullname}</span>' +
                '</li>',
              outputTemplate: '<a href="mailto:{username}@example.com">@{username}</a><span>&nbsp;</span>',
              minChars: 0
            },
            {
              feed: tags,
              marker: '#',
              itemTemplate: '<li data-id="{id}"><strong>{name}</strong></li>',
              outputTemplate: '<a href="https://example.com/social?tag={name}">{name}</a><span>&nbsp;</span>',
              minChars: 1
            }
          ]
        });
    
        function dataFeed(opts, callback) {
          var matchProperty = 'username',
            data = users.filter(function(item) {
              return item[matchProperty].indexOf(opts.query.toLowerCase()) == 0;
            });
    
          data = data.sort(function(a, b) {
            return a[matchProperty].localeCompare(b[matchProperty], undefined, {
              sensitivity: 'accent'
            });
          });
    
          callback(data);
        }
      </script>
    </body>
    
    </html>