Open secondmanveran opened 1 year ago
Are you using SSR? Errors on the server side are often harder to track down, because the console output is worse than in the browser. You could try to turn it off and check if you get an error in the browser console on page load.
I am. I'll try disabling it and see if that resolves it.
@neluba
Yep that seems to resolve the issue. No errors at all in the console when running without SSR.
What would be my next step in debugging why I'm not getting a response body with SSR turned on?
Wow, so check this out.
I opened Rompetomp\InertiaBundle\Ssr\HttpGateway::class
And under the dispatch
method I added a dump to see what's going on:
try {
$response = $this->httpClient->request(
'POST',
$this->interia->getSsrUrl(),
[
'headers' => [
'Content-Type: application/json',
'Accept: application/json',
],
'body' => json_encode($page),
]
);
// to see the array of the response
dd($response->toArray());
} catch (Exception $e) {
return null;
}
And with this dump in place... all the pages load and render correctly.
What the heck???
Could this be something to do with using the Inertia > 1.0 version? No need to actually return a Response
object?
@secondmanveran Does your node server output any errors? Inertia v1 shouldn't be the problem, because I'm using it as well.
You should also see the dump output if you put the dd() at this location, except if you turned off SSR.
You could also try to use ts-node-dev in development, if you don't already use it, and see if it gives you more output. The output is often not very helpful, but better than nothing. It looks like this
Inertia SSR server started.
[Vue warn]: Property "foo" was accessed during render but is not defined on instance.
TypeError: Cannot read properties of undefined (reading 'length')
at ssrRender (/.../public/build-ssr/ssr.js:151323:16)
The problem could also be in your ssr entrypoint, if you can't reproduce the problem without SSR.
Here is my version without all the extra vue plugins
createServer((page) =>
createInertiaApp({
page,
render: renderToString,
resolve: (name) => {
const pageInternal = require(`@/pages/${name}`).default;
pageInternal.layout = pageInternal.layout || DefaultLayout;
return pageInternal;
},
setup({ el, app, props, plugin }) {
const vueApp = createSSRApp({ render: () => h(app, props) })
.use(plugin);
return vueApp;
},
})
);
@neluba
I've had a bit of progress but still getting weird results all around.
Now I'm getting weird rendering with no css on any initial page load.
Then when I click an Inertia link, it will load up the requested component and render everything perfectly.
Any initial page:
Then when I navigate via links:
I put all my dependencies in a plugin file that looks like so:
import { Head, Link } from '@inertiajs/vue3'
import { Routing } from 'fos'
import mitt from 'mitt'
import axios from 'axios'
import dayjs from 'dayjs'
import routes from './routes.json'
Routing.setRoutingData(routes)
export const zuma = {
install(app) {
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'
axios.defaults.withCredentials = true
const router = (name, params, absolute = true) =>
Routing.generate(name, params, absolute)
app.mixin({
methods: {
route: router
}
})
const is_null = obj => {
return !obj && typeof obj === 'object'
}
const isObject = obj => {
return obj === Object(obj)
}
app.provide('route', router)
app.provide('emitter', mitt())
app.provide('dayjs', dayjs)
app.provide('axios', axios)
app.provide('isObject', isObject)
app.provide('is_null', is_null)
app.component('Head', Head)
app.component('Link', Link)
}
}
That way I can ensure both app and ssr contain the same dependencies.
My ssr server looks like so:
import { createInertiaApp } from '@inertiajs/vue3'
import createServer from '@inertiajs/vue3/server'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'
import { resolvePageComponent } from './resolvePageComponent.js'
import { zuma } from './plugin.js'
import '../css/app.css'
const pages = import.meta.glob('../pages/**/*.{vue,md}', { eager: true })
createServer(
page =>
createInertiaApp({
page,
render: renderToString,
resolve: async name => {
return await resolvePageComponent(`../pages/${name}.vue`, pages)
},
setup({ App, props, plugin }) {
return createSSRApp({
render: () => h(App, props)
})
.use(plugin)
.use(zuma)
}
}),
import.meta.env.VITE_SSR_PORT
)
The resolvePageComponent
is the same as what comes from the Laravel Inertia helper.
I am using client side hydration in my app.
All this works fine in my Laravel apps, I would have thought Symfony would be farther ahead of this, but I think the fact that Encore is so widely promoted is stopping the team from moving forward on the Vite trend.
@secondmanveran Are you using Vite? I never used it and symfony and would wish that the symfony team would officially support it. Styles are also my biggest pain point with SSR, because I can't get the SSR server to output the css chunks from single file components. And it also tries to load it's own generated main.css file, instead of of a shared one with the client code.
A workaround to at least load the css entrypoint in SSR are these few lines in the SSR webpack encore config.
Encore.setOutputPath("public/build-ssr/")
.setPublicPath(process.env.DEV_ENV === "DEV_SERVER" ? "https://localhost:9038/build" : "/build")
.setManifestKeyPrefix("build/")
This will generate asset links with /build instead of /build-ssr.
The environment variable check helps with the encore dev server. Port 9038 is the port in my project, encore usually uses 9000. I start my ssr watcher with this script in the package json, to prepend the env var:
{
"scripts": {
"watch:ssr": "encore dev --watch -c ./webpack.ssr.config.js",
"dev-server:ssr": "DEV_ENV=DEV_SERVER encore dev --watch -c ./webpack.ssr.config.js",
"build:ssr": "NODE_ENV=production encore production --progress -c ./webpack.ssr.config.js"
}
}
The result is ok, but not great, because it only helps a little. I need the ssr part for SEO reasons in production for my main project and hide most of the ui, until the client rendered the ui with additional css chunks loaded through the webpack runtime.
It does work well with tailwind though in another project of mine, because I only have a single css file anyway.
@neluba
Yes I tried to use Encore just so I could keep in line with the current "Symfony way" and it wouldn't compile Inertia > 1, so I went back to Vite, which is what I normally use. I can't stand webpack, it's just so bloated and time consuming. ES modules are the way.
I don't ever use SFC css normally so let me try getting rid of this default Symfony start page and we'll see where we are then.
Yeah I give up. I'll just stick with Laravel.
When using the
Link
component pages navigate correctly but when you input a page via the address bar I get the following exception:It looks like it's dying at:
Any ideas what's up, or any additional info you need?