-
-
Notifications
You must be signed in to change notification settings - Fork 457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
createInertiaApp not using "id" option for Vue root element #1358
Comments
This just happened to me too.
app.blade.php <!DOCTYPE html>
<html lang="en" data-bs-theme="dark" class="w-100 h-100">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
<title>Document</title>
@vite(['resources/js/app.js'])
@inertiaHead
</head>
<body id="my-app" class="w-100 h-100">
</body>
</html> app.js ...
const inertiaData = {
id: 'my-app',
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', {eager: true})
let page = pages[`./Pages/${name}.vue`]
page.default.layout = page.default.layout || AppLayout
return page
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
};
createInertiaApp(inertiaData); For the "createInertiaApp" portion: export default async function createInertiaApp({ id = 'app', resolve, setup, title, page, render }) {
const isServer = typeof window === 'undefined'
const el = isServer ? null : document.getElementById(id)
const initialPage = page || JSON.parse(el.dataset.page) // Line 7, where the error occurs
...
} It gets compiled to this JS: let m = typeof window > "u", ... // Is this a valid "undefined" check? This isn't returning true or false, but stays undefined. By this being set to undefined the JSON parse seems to just not go through. I can provide more details, and this would be awesome to be fixed. |
update your blade.php : @inertia('my-app') |
I'm experiencing the same issue in React. Is there any solution to this or is it just a bug. |
Yeah, the docs are incomplete on this. What's described in the docs only changes the client-side, server-side the rendered div also has to be changed for it to even work. For Laravel you'd have to use the approach @zxdstyle mentioned ( |
Then, a solution would be updating the docs indicating the proper way of initializing inertia using the |
Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion. In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward. Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it. Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️ |
Add |
Yup, exactly, this works! @inertia('my-custom-id') And I agree, this should get added to the server-side setup page: https://inertiajs.com/server-side-setup Going to open this issue as a reminder to do that 👍 |
Version:
nodejs
version: 18.12.1@inertiajs/vue3
version: 3.2.45@inertiajs/inertia
version: 0.11.1@inertiajs/inertia-vue3
version: 0.6.0ruby
version: 3.1.2rails
version: 7.0.4Describe the problem:
Per the documentation page "Client-side setup", a custom element ID can be specified for the root of the application:
Something, somewhere is dropping the ball when attempting to use this capability. If an element with the ID exists named
my-vue-root
, it is not used when passed as theid
option/argument tocreateInertiaApp
.I have tested this in a clean install, with the versions described above, using the simplest-possible example: a single component/page application with a stripped-down layout template, and bare minimum setup for Inertia/Vue. Different amounts of fiddling and banging has led to one of two main outcomes:
<div>
element is created within the intended root element with and id ofapp
, ignoring the intended purpose.Uncaught (in promise) SyntaxError: "undefined" is not valid JSON
increateInertiaApp.js:7:36
, because this root element does not have the valuedata-page
, or if I adddata-page=""
to the element, it fails for other reasons.Reading the source of
createInertiaApp.js
I see that one can pass apage
argument tocreateInertiaApp()
. It is not documented in that file, but it seems one can use this by passingpage
as an object with propertiescomponent
,props
andurl
. This can "force" an initial page load to boot up with a particular component. However, the component does not load any data from the server (regardless of theurl
property in thepage
object), and worse, doing so causes a page refresh to leave the current route and re-render this initial page/component.It "works" in that the specified
component
will mount within the element withid="my-app"
instead of make a nested<div id="app">
. So success on that, but then breaks routing on reloads. For example, if thepage
property in the argument is{ component: "Home", url: "/" }
, then one navigates to aFoo.vue
page at/foo
, and then reloads, the page does not return to/foo
. Instead it is reset to showHome
and the route is reset to/
. There is a logic to that, but it is clearly not a desirable tradeoff just to force the proper use of a DOM element byid
.Steps to reproduce:
First, the simplest possible combination:
app/views/layouts/application.html.erb
:app/frontend/entrypoints/application.js
:app/frontend/Pages/Home.vue
:Even though
<div id="my-vue-root">
clearly exists, this produces the JavaScript error:Stepping through in the debugger, the
createInertiaApp
function is receiving theid
property from the argument, but is trying to catch some data parameterpage
that does not exist yet, because the app is not yet created. Obviously the app and itspage
data cannot be created yet, as this is the create function itself!(From packages/vue3/src/createInertiaApp.js):
In an even stranger case, and I apologize for not isolating this better, I have managed to get a halfway failure, where this
SyntaxError: "undefined" is not valid JSON
error occurs, but the DOM itself appears to have created the<div id="app">
nested within my specified<div id="my-vue-root">
element, before attempting to use that element and failing anyway. The DOM in such an occasion looks like this:Again, I can "force" the root to attach to
<div id="my-vue-root">
if I instead initialize with apage
property in the object argument:However, again, doing this causes any and all reloads of the application, at any route (e.g. after navigating elsewhere) to reset and load
Home
at the route/
. I feel like I understand why, but it makes me feel like thispage
option must truly be not intended for use in this way.I am left wondering, based on the documentation, whether this is a bug, or if I am radically misunderstanding something about this
id
option forcreateInertiaApp
?Why this matters
I ask this because, in a more complex, real-world use, I wish to point Inertia at different root elements by
id
, in different situations. If this is not how theid
option is intended to be used, I kindly request some documentation explaining what steps are required to properly use thisid
option forcreateInertiaApp
.The text was updated successfully, but these errors were encountered: