Blank screen when rendering Vue compoments with Inertia in production
Hi
I'm using Laravel and Inertia with Vue to build a multi page web application. I use Coolify with nixpacks to deploy my application on a server.
When making a request, the server always returns a response, without any server side error. On the client side, the page correctly renders for a millisecond, before going blank. When I take a look at the HTML, the vue component has been unmounted. When this happens, the following exception is thrown in Vue's runtime-core.esm-bundler.js:
-
TypeError: Cannot read properties of null (reading 'ce')The error throws when mounting the app component inresources/js/app.ts. The property 'ce' cannot be read becausecurrentRenderingInstanceis null.
The error happens in runtime-core.esm-bundler.js:
function renderSlot(slots, name, props = {}, fallback, noSlotted) {
if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) {
if (name !== "default") props.name = name;
return openBlock(), createBlock(
Fragment,
null,
[createVNode("slot", props, fallback && fallback())],
64
);
}
...
The page I'm trying to render is quite simple too:
<script setup lang="ts">
import {Head} from "@inertiajs/vue3";
import Column from "@/components/utils/Column.vue";
</script>
<template>
<div>
<Head title="Log in" />
<Column>
hi!
</Column>
</div>
</template>
where Column.vue:
<script setup lang="ts">
import {cn} from "@/lib/utils";
import {type Component, type HTMLAttributes} from "vue";
import type {AsTag} from "radix-vue";
const props = withDefaults(
defineProps<{
class?: HTMLAttributes['class'],
as?: AsTag | Component
}>(),
{
as: "div"
}
);
</script>
<template>
<component :is="as" :class="cn('flex flex-col justify-center items-start w-full', props.class)">
<slot />
</component>
</template>
According to similar issues, the problem could be due to multiple versions of Vue running at the same time, but I have not been able to confirm that hypothesis. I have tried resolving and deduping vue in vite.config.js, but with no success. I'm unable to reproduce this issue in my local environment, even when I set NODE_ENV and APP_ENV to production. The issue only happens on my production server.
Does anyone have any insight on this issue? Or perhaps an idea on how to debug this?
package.json
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"typecheck": "vue-tsc",
"build": "vite build",
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.3",
"@vitejs/plugin-vue": "^5.0.0",
"autoprefixer": "^10.4.12",
"laravel-vite-plugin": "^1.0",
"postcss": "^8.4.31",
"tailwindcss": "^3.2.1",
"typescript": "^5.5.3",
"vite": "^5.0",
"vue": "^3.5.13",
"vue-tsc": "^2.0.24"
},
"dependencies": {
"@iconify/vue": "^4.1.2",
"@inertiajs/vue3": "^1.0.0",
"axios": "^1.7.4",
"@dzangolab/vue-country-flag-icon": "^0.3.0",
"@inertia-vue-form/zod": "^0.1.1",
"@tanstack/vue-table": "^8.20.5",
"@vee-validate/zod": "^4.13.2",
"@vitejs/plugin-vue-jsx": "^4.0.1",
"@vueuse/core": "^11.1.0",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"date-fns": "^4.1.0",
"lucide-vue-next": "^0.446.0",
"radix-vue": "^1.9.6",
"tailwind-merge": "^2.5.2",
"tailwindcss-animate": "^1.0.7",
"vaul-vue": "^0.2.0",
"vee-validate": "^4.13.2",
"vue-json-viewer": "^3.0.4",
"zod": "^3.23.8"
}
}
vite.config.js
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import {fileURLToPath, URL} from "url";
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.ts', 'resources/css/app.css'],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
vueJsx({})
],
resolve: {
alias: [
{find: '~', replacement: fileURLToPath(new URL('./resources/js', import.meta.url))},
{find: '@', replacement: fileURLToPath(new URL('./resources/js', import.meta.url))},
{find: '@pages', replacement: fileURLToPath(new URL('./resources/js/pages', import.meta.url))},
{find: '@layouts', replacement: fileURLToPath(new URL('./resources/js/layouts', import.meta.url))},
{find: '@components', replacement: fileURLToPath(new URL('./resources/js/components', import.meta.url))},
// I have tried resolving vue here, but with no success
]
},
build: {
sourcemap: true,
},
});
resources/js/app.ts
import './bootstrap';
import '../css/app.css';
import {createApp, DefineComponent, h} from 'vue';
import {createInertiaApp} from '@inertiajs/vue3';
import {resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers';
import {ZiggyVue} from '../../vendor/tightenco/ziggy';
import.meta.glob('../images/**');
const appName = import.meta.env.VITE_APP_NAME || 'ImagineY';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./pages/${name}.vue`, import.meta.glob<DefineComponent>('./pages/**/*.vue')),
setup({el, App, props, plugin}) {
createApp({
render: () => h(App, props),
})
.use(ZiggyVue)
.use(plugin)
.mount(el);
},
progress: {
color: '#4B5563'
},
}).catch(error => console.error(error));
resources/views/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1">
<title inertia>{{ config('app.name', 'ImagineY') }}</title>
<!-- Scripts -->
@routes
@vite(['resources/js/app.ts'])
@inertiaHead
</head>
<body class="font-sans antialiased @if (session('dark-mode')) dark @endif">
@inertia
</body>
</html>
Please or to participate in this conversation.