1

I am trying to build a blogging platform and i need to use a text editor and i have considered CKeditor and TinyMCE but there is no video or good instruction on how to use it with NuxtJS.

If anyone can help me it will be appreciated.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • What did you tried so far? Using it with Nuxt is pretty much the same as with Vue. – kissu Mar 21 '22 at 21:19
  • @kissu I tried adding TinyMCE cdn link to my nuxtjs and tried adding the js but it did not display still. Is there any guide online for nuxtjs? – Henry Oladeji Mar 21 '22 at 21:32
  • Do not use a CDN when you can use an NPM package. Also, this one is pretty explanatory IMO: https://github.com/tinymce/tinymce-vue#about – kissu Mar 21 '22 at 23:05

2 Answers2

2

Please do not use a CDN but rather the solution that is here.

With something like this

<template>
   <div id="app">
     <img alt="Vue logo" src="./assets/logo.png">
     <editor
       api-key="no-api-key"
       :init="{
         height: 500,
         menubar: false,
         plugins: [
           'advlist autolink lists link image charmap print preview anchor',
           'searchreplace visualblocks code fullscreen',
           'insertdatetime media table paste code help wordcount'
         ],
         toolbar:
           'undo redo | formatselect | bold italic backcolor | \
           alignleft aligncenter alignright alignjustify | \
           bullist numlist outdent indent | removeformat | help'
       }"
     />
   </div>
 </template>

 <script>
 import Editor from '@tinymce/tinymce-vue'

 export default {
   name: 'app',
   components: {
     'editor': Editor
   }
 }
 </script>
kissu
  • 40,416
  • 14
  • 65
  • 133
0

Tinymce and CKeditor both have NPM packages and CDNs. This means you have two ways of using them in a Nuxt app.

Including the package via script tag (CDN)

As stated in the "Getting started" guide of those packages, you can simply import them using a script tag. In Nuxt, you can do this by adding it to your nuxt.config.js head option.

// nuxt.config.js

[...]
head: {
  scripts: [
    { src: "https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js", referrerpolicy: true }
  ]
},
[...]
// example.vue

[...]
mounted() {
  tinymce.init()
}
[...]

Using this solution you have to pay attention that tinymce is only accessed on the client-side, as it will not be available on the server-side.

Adding the package as a plugin

This is usually preferable, as it helps with bundle size analysis and allows your package manager to manage the text editors version.

You can also add the respective package as a plugin. Install the package using npm or yarn.

npm i tinymce

Afterward, simply create a .js-file in the plugins directory like so:

// plugins/tinymce.js

import tinymce from "tinymce"

export default tinymce

Register the plugin in your nuxt.config.js

// nuxt.config.js

plugins: [
  {
    src: "~/plugins/tinymce.js",
    mode: "client", // This way the plugin will only be initiated on the client side
  }
]

Now you can use the plugin within your app, accessing tinymce, just like in example.vue above.

Dynamically import the package within individual components

Another option is importing the npm package in the component directly. This may improve performance as the package is only imported when it is needed. If the package supports SSR, you can simply import it like you would any other package at the top of the script tag.

If your package does not support SSR (like most text editors), you can import it dynamically after checking whether the process is running on the client-side or by only importing it within hooks or methods that run on the client-side exclusively. (Solution by @kissu)

See this question for dynamic imports: How to make a dynamic import in Nuxt?

aside
  • 722
  • 4
  • 20
  • Using a NPM package is alway better. Also, import it locally rather than globally (plugins) to improve performance. – kissu Mar 21 '22 at 22:26
  • Not sure about importing client-only plugins locally, do you have any resources for that? Not sure if naming (`plugin.client.js`) is sufficient when importing locally. – aside Mar 21 '22 at 22:47
  • I'm sure of that. What I mean by that is basically doing `import tinymce from "tinymce"` directly into the `.vue` file (without using a Nuxt plugin). – kissu Mar 21 '22 at 23:00
  • Yes I know this works in general, but if tinymce tries to access something like the `window` or `document` object it will fail if initialized on server-side. I am not aware of a way you can achieve client-side only (like the option `mode: 'client'` in `nuxt.config`) when importing locally. Do you? – aside Mar 21 '22 at 23:40
  • `mode` is legacy anyway, you should use `target` and `ssr` now. Otherwise, yeah you can totally make a [dynamic import](https://stackoverflow.com/a/67825061/8816585) after a given condition or import a given component on the [client only](https://stackoverflow.com/a/69593428/8816585) if the package does not support SSR by itself. – kissu Mar 21 '22 at 23:46
  • Also, if you look at the [lifecycle of Nuxt](https://nuxtjs.org/docs/concepts/nuxt-lifecycle#client), you can see that `mounted()` is only for the client side, hence another approach of not having something running on the server side. – kissu Mar 21 '22 at 23:51
  • You're mixing up the `mode` property in `nuxt.config` (https://nuxtjs.org/docs/configuration-glossary/configuration-mode/) with the `mode` property in the plugin options. `mode: 'client'` is not deprecated, `ssr: false` is. (https://nuxtjs.org/docs/configuration-glossary/configuration-mode/) – aside Mar 21 '22 at 23:53
  • Oh yeah, the [plugin's mode](https://nuxtjs.org/docs/configuration-glossary/configuration-plugins#the-plugins-property) indeed. I mean, it's still globally importing it overall so it does not solve the issue indeed. But it can of course solve some use cases: package used broadly on the app + client only package. – kissu Mar 21 '22 at 23:56
  • And even though you are correct in that `mounted` only runs on the client side, importing tinymce at the top of the `script`-tag alone will already throw an error. The approach using dynamic imports looks interesting, thank you! I believe it is a trade of between performance and readability, especially if you have a couple of components using it in various different methods and hooks, but definitely, something to consider. I'll add it to the answer. – aside Mar 21 '22 at 23:57
  • It's not always running an error, it actually depends on how the package is written. Some are totally fine until you instantiate them. I've written that especially because you wrote an example with `mounted()`. Dynamic imports are indeed nice, especially because it does not load the script until you need it. So, sometimes never. Which is amazing for heavy packages that are never reached. – kissu Mar 22 '22 at 00:00
  • @aside so i did everything and i did ```mounted(){ tinymce.init({ selector: 'textarea#default' }) }``` but i keep getting this error ```tinymce.js?e562:18014 Failed to load theme: silver from url themes/silver/theme.js``` and ```tinymce.js?e562:4668 GET http://localhost:3000/_nuxt/models/dom/model.js net::ERR_ABORTED 404 (Not Found)``` – Henry Oladeji Mar 22 '22 at 15:33
  • or do i need to install it on the laravel side too? – Henry Oladeji Mar 22 '22 at 16:06
  • You don't need to install that on the Laravel side. You should answer on my comment under your question, provide us a [repro] or any kind of useful resource for help to actually have some material to help you. – kissu Mar 22 '22 at 16:55
  • So i have done everything @aside said but i keep getting several importing errors like the one i mentioned above ```tinymce.js?e562:7458 GET http://localhost:3000/_nuxt/themes/silver/theme.js net::ERR_ABORTED 404 (Not Found)``` in the .vue file i added ```selector:'textarea#default'``` and i have an id of ```default``` – Henry Oladeji Mar 22 '22 at 17:00
  • My previous comment is still valid. I'm not sure how you think this can be debugged with just this. – kissu Mar 22 '22 at 17:01
  • Like i said i did everything that was written above and i got the error i pasted. I do not know how much explanation i need to do. The Text Editor did not display instead i got that error in the console. I am not sure how much explanation i can provide – Henry Oladeji Mar 22 '22 at 19:13
  • It has worked finally !!! – Henry Oladeji Mar 22 '22 at 19:55
  • 1
    Apparently V-model does not work with it – Henry Oladeji Mar 22 '22 at 20:04