Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

anpel's avatar
Level 1

How can I use TinyMCE with Laravel Mix?

I'm on 5.4 but I don't know much about webpack.

I am trying to use TinyMCE on a textarea but it never loads and in the console I keep getting the message: "TypeError: Theme is not a constructor".

I have installed it using npm install tinymce --save and it appears in the node_modules directory as expected.

My webpack.mix.js file:

mix.js('resources/assets/js/app.js', 'public/js')
      .sass('resources/assets/sass/app.scss', 'public/css')
      .browserSync({proxy: "mydomain.dev"});    

And my app.js file:

// I have not edited this file
require('./bootstrap');

// Use tinymce from node modules
require('tinymce');

tinymce.init({
    selector: '#description',
    height: 500,
    menubar: false,
    plugins:[],
    toolbar: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
    content_css: '//www.tinymce.com/css/codepen.min.css'
});

Can you please point me in the right direction?

0 likes
5 replies
willvincent's avatar

This isn't really an issue with laravel mix as it is intended to handle the "80% use case" scenario... This falls outside that 80% because tinyMCE apparently isn't quite compatible with webpack -- at least, not without some extra webpack config to make things work properly.

See: http://stackoverflow.com/questions/41009736/tinymce-uncaught-typeerror-theme-is-not-a-constructor

Not tested, but you ought to be able to add that necessary extra webpack config with mix.webpackConfig() as documented here: https://github.com/JeffreyWay/laravel-mix/blob/master/docs/quick-webpack-configuration.md

anpel's avatar
Level 1

@willvincent thank you for your time.

Sadly, after changing my files to:

mix.webpackConfig({
  module: {
    loaders: [
      {
        test: require.resolve('tinymce/tinymce'),
        loaders: [
          'imports?this=>window',
          'exports?window.tinymce'
        ]
      },
      {
        test: /tinymce\/(themes|plugins)\//,
        loaders: [
          'imports?this=>window'
        ]
      }    
    ]
  }
});

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .browserSync({proxy: "mydomain.dev"});

And:

require('./bootstrap');

// Core - these two are required :-)
import tinymce from 'tinymce/tinymce'
import 'tinymce/themes/modern/theme'

// Plugins
import 'tinymce/plugins/paste/plugin'
import 'tinymce/plugins/link/plugin'
import 'tinymce/plugins/autoresize/plugin'

// Initialize
tinymce.init({
  selector: '#description',
  skin: false,
  plugins: ['paste', 'link', 'autoresize']
});

the console message disappears, but TinyMCE still fails to load (shows whole textarea blank, no outines).

Is there another way I could set up TinyMCE to work or will I have to switch editor? If it's the latter, do you have any in mind that would work out of the box in this case?

willvincent's avatar

The issue you're likely running into now is that your tinymce init method is probably firing too early. If that's being executed before the #description element exists in the dom, for example, it's just not going to work properly.

I don't actively use tinymce, so can't really offer any more help, unfortunately.

greenroom's avatar
tinymce.init({
  selector: '#description',
  skin: false,
  plugins: ['paste', 'link', 'autoresize']
});

I would think that Tinymce is not showing because you have declared skin : false

Try removing it and use mix.copy to copy the skin folder to public folder

mix.copy('node_modules/tinymce/skins', 'public/skins');

also remember to git ignore it.

Hope it's help =D

1 like
Qanah's avatar
  1. npm i tinymce

  2. edit webpack.mix.js and add this line mix.copy('node_modules/tinymce/skins', 'public/js/skins');

  3. edit /resources/assets/js/app.js and add this code

require('tinymce');
require('tinymce/themes/modern');
require('tinymce/plugins/paste');
require('tinymce/plugins/advlist');
require('tinymce/plugins/autolink');
require('tinymce/plugins/lists');
require('tinymce/plugins/link');
require('tinymce/plugins/image');
require('tinymce/plugins/charmap');
require('tinymce/plugins/print');
require('tinymce/plugins/preview');
require('tinymce/plugins/anchor');
require('tinymce/plugins/textcolor');
require('tinymce/plugins/searchreplace');
require('tinymce/plugins/visualblocks');
require('tinymce/plugins/code');
require('tinymce/plugins/fullscreen');
require('tinymce/plugins/insertdatetime');
require('tinymce/plugins/media');
require('tinymce/plugins/table');
require('tinymce/plugins/contextmenu');
require('tinymce/plugins/code');
require('tinymce/plugins/help');
require('tinymce/plugins/wordcount');

$( document ).ready(function() {
    tinymce.init({
        selector: ".tiny",
        height: 300,
        menubar: false,
        plugins: [
            'advlist autolink lists link image charmap print preview anchor textcolor',
            'searchreplace visualblocks code fullscreen',
            'insertdatetime media table contextmenu paste code help wordcount'
        ],
        toolbar: 'insert | undo redo |  formatselect | bold italic backcolor  | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat | help',
        content_css: [
            '//fonts.googleapis.com/css?family=Lato:300,300i,400,400i',
            '//www.tinymce.com/css/codepen.min.css'
        ]
    });
});
  1. add tiny class to textarea<textarea class="tiny"></textarea>
5 likes

Please or to participate in this conversation.