pasamsin's avatar

Laravel + inertia SSR + vite + tinymce self hosted error.

Hi,

I want to add TinyMCE as self-hosted, but I'm getting the following error. Where am I going wrong?

terminal error;

 php artisan inertia:start-ssr
Starting SSR server on port 13714...
Inertia SSR server started.
ReferenceError: window is not defined
    at mediaMatch (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:957:57)
    at DeviceType (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:615:35)
    at Object.detect [as detect] (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:948:26)
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:958:53
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:605:17
    at detect (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:959:28)
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:962:24
    at Object.<anonymous> (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:31756:3)
    at Module._compile (node:internal/modules/cjs/loader:1378:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1437:10)
node:internal/process/promises:289
            triggerUncaughtException(err, true /* fromPromise */);
            ^

ReferenceError: window is not defined
    at mediaMatch (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:957:57)
    at DeviceType (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:615:35)
    at Object.detect [as detect] (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:948:26)
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:958:53
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:605:17
    at detect (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:959:28)
    at /Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:962:24
    at Object.<anonymous> (/Applications/XAMPP/xamppfiles/htdocs/W/INERTIA/node_modules/tinymce/tinymce.js:31756:3)
    at Module._compile (node:internal/modules/cjs/loader:1378:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1437:10)

Node.js v21.6.2

Editor.vue

<template>
    <editor
        api-key="no-api-key"
        v-model="model" model-events="" @selectionChange="changes"
        :init="init"
    />
</template>

<script>
import { defineComponent } from 'vue'

//TinyMCE
import tinymce from 'tinymce';
import 'tinymce/icons/default/icons'
import 'tinymce/themes/silver/theme'
import 'tinymce/models/dom/model'
import 'tinymce/skins/ui/oxide/skin.css'
//import {contentUiCss} from 'tinymce/skins/ui/oxide/content.css';

//TinyMCE plugins
//https://www.tiny.cloud/docs/tinymce/6/plugins/
import 'tinymce/plugins/lists/plugin'
import 'tinymce/plugins/link/plugin'
import 'tinymce/plugins/image/plugin'
import 'tinymce/plugins/table/plugin'
import 'tinymce/plugins/code/plugin'
import 'tinymce/plugins/wordcount/plugin'

import 'tinymce/langs/tr'

import Editor from '@tinymce/tinymce-vue'

export default defineComponent({
    props: ['modelValue'],

    components: {'editor':Editor},

    emits: ['update:modelValue'],
    data() {
        return {
            model: this.modelValue,
            init: {
                entities : "Ü = Ü ü = ü Ç = Ç ç = ç Ö = Ö ö = ö Ş = Ş ş = ş Ğ = Ğ ğ = ğ İ = İ ı = ı",
                valid_elements: "*[*]",
                skin: false,
                plugins: 'lists link image table code wordcount',
                content_css: false,
                //content_style: contentUiCss.toString(),
                language: 'tr',
                promotion: false,
                convert_urls: false,
            }
        }
    },
    methods: {
        changes(event,editor){
            this.$emit('update:modelValue', editor.getContent())
        }

    }
})
</script>

0 likes
7 replies
gych's avatar

Its because window doesn't work with ssr, it only works on client side

pasamsin's avatar

So, can't I use any rich text editor with SSR? I think TinyMCE doesn't support SSR, right?

gych's avatar

@pasamsin

The only editor that I know of that supports ssr is Draft.js but I haven't used it myself.

You can try to add tinymce after the page has been mounted or exclude the page from ssr so it only gets rendered on the client side. I've seen both methods used as a solution for this. The first a bit harder to implement than the second.

pasamsin's avatar

How can I exclude one or more pages or pages in a directory from SSR?

gych's avatar
gych
Best Answer
Level 29

@pasamsin You can exclude the routes with a HttpGateway

Here is an example

Create a file called InertiaHttpGateway.php in for example app/Inertia with this content

namespace App\Inertia;

use Illuminate\Support\Str;
use Inertia\Ssr\HttpGateway;
use \Inertia\Ssr\Response;

class InertiaHttpGateway extends HttpGateway
{
    /**
     * Dispatch the Inertia page to the Server Side Rendering engine.
     *
     * @param array $page
     * @return Response|null
     */
    public function dispatch(array $page): ?Response
    {
        if (isset($page['url']) && Str::is('/singleroute', $page['url'])) return null;
        if (isset($page['url']) && Str::is('/admin*', $page['url'])) return null;

        return parent::dispatch($page);
    }
}

In the example above you can see that I added two example routes

  • /singleroute will exclude the specified url path from ssr
  • /admin* will exclude all url path's that start with /admin

Once this file is created add the created HttpGateway to the AppServiceProvider

use App\Inertia\InertiaHttpGateway;
use Inertia\Ssr\HttpGateway;

class AppServiceProvider extends ServiceProvider
{

    public $bindings = [
        HttpGateway::class => InertiaHttpGateway::class,
    ];

	// rest of existing code in AppService Provider
}
1 like
pasamsin's avatar

After you mentioned the exclusion issue to me, I did some research and found the following lines, and it worked. Also, thank you for sharing.

    @php
       if(Request::is('panel/*')){
           $__inertiaSsrDispatched = true;
           $__inertiaSsrResponse = null;
       }
    @endphp
gych's avatar

@pasamsin No problem ! I'm glad I could help, don't forget to close your post by selecting the best answer :)

Please or to participate in this conversation.