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

adityar15's avatar

Toggle theme of TinyMce editor

Hi,

I am using @tinymce/tinymce-vue package with Vue 3. I am trying to toggle the dark mode for the editor on the mode switch.

Here is what I got

<template>
    <Editor
        ref="editor"
        api-key="api-key"
        :init="initOptions"
        :modelValue="modelValue"
        @update:modelValue="(val) => emit('update:modelValue', val)"
    />
</template>

<script setup>
import useDarkMode from "../composables/useDarkMode";
import Editor from "@tinymce/tinymce-vue";

import { computed, onMounted, ref, reactive } from "vue";

defineProps({
    modelValue: String,
});

const emit = defineEmits(["update:modelValue", "save"]);
const editor = ref();

const { darkMode } = useDarkMode();

const theme = computed(() => {
  
    return darkMode.value
        ? {
              skin: "oxide-dark",
              content_css: "dark",
          }
        : {
              skin: "oxide",
              content_css: "default",
          };
});


const initOptions = reactive({
    height: 750,
   /* some plugins and toolbar options */
    ...theme.value,
    save_onsavecallback: () => emit("save"),
});
</script>

the useDarkMode is a pinia store which keeps track of dark mode theme.

Everything works except the tinymce editor theme is not toggled. Does anyone know how to change the editor theme reactively for Vue? Thanks in advance :)

0 likes
2 replies
piljac1's avatar
piljac1
Best Answer
Level 28

Haven't really worked with TinyMCE before, but since the options are under the init prop, my guess is that these options are not reactive because they're initial values. After looking at the source code, I haven't seen anything suggesting they're supposed to be reactive. However, I found that they expose a rerender method on the component. So I explored with that in a Vue sandbox and it turns out explicitely calling the rerender method works, but with one downside (and possibly others I haven't seen), which might be negligeable and/or fixable, but I didn't want to spend a ton of time on it since it's just a proof of concept. The downside in question is that since the component needs to be rerendered, it loses its current state, which means that the current editor content will still remain intact (because of the two-way binding), but the undo/redo history is completely wiped. Here's an adjusted code snipped of my explorations:

<template>
  <button @click="darkMode = !darkMode">Toggle light/dark mode</button>
  <Editor
    ref="editor"
    api-key="api-key"
    :init="initOptions"
    :modelValue="modelValue"
    @update:modelValue="(val) => emit('update:modelValue', val)"
  />
</template>

<script setup>
import Editor from "@tinymce/tinymce-vue";

import { computed, onMounted, ref, reactive, watch } from "vue";

defineProps({
  modelValue: String,
});

const emit = defineEmits(["update:modelValue", "save"]);
const editor = ref();
const darkMode = ref(true);

const theme = computed(() => {
  return darkMode.value
    ? {
        skin: "oxide-dark",
        content_css: "dark",
      }
    : {
        skin: "oxide",
        content_css: "default",
      };
});

watch(darkMode, () => {
  editor.value.rerender(initOptions.value);
});

const initOptions = computed(() => {
  return {
    height: 750,
    /* some plugins and toolbar options */
    ...theme.value,
    save_onsavecallback: () => emit("save"),
  };
});
</script>

What I added/adjusted:

  1. Replaced reactive by a computed for initOptions (since it depends on theme)
  2. Added a watch on the darkMode value which will cause a the editor to rerender with the new initOptions
  3. Added a button to toggle the darkMode and changed the darkMode variable to a ref for testing purposes, but you can revert that back to what you had before
2 likes
adityar15's avatar

@piljac1 This works like a charm. Making it a computed property and calling rerender does the trick. Thank you so very much. You are amazing!

Please or to participate in this conversation.