Open mrsafalpiya opened 1 year ago
First, I've got to compliment the thoroughness of your post. It perfectly replicated the issue. What was perhaps most interesting was that I was able to use /foo
within the app via the link, but not within a browser at localhost:34115/foo
even when navigating (if the app didn't navigate there first).
This is a result of the wails runtime not being injected into the generated localhost:34115/foo/index.html
as it is in the localhost:34115/index.html
.
If you inspect the /
endpoint you will see the following two scripts injected into the head of the document.
These two scripts are injected by the wails app in order to link to the golang backend. But, when you navigate to /foo
within a browser, Wails doesn't re-inject these scripts into the new page unless it is loaded within the running Wails app.
/
The first solution is a breakable one, adding even a bare-bones +layout.svelte
like:
allows navigation within the browser from /
to /foo
to carry the injection as a user routes through the site since the layout is replacing the routes/+page.svelte
with routes/foo/+page.svelte
without changing the header.
If a user navigates to localhost:34115/foo
without having started at localhost:34115
the layout will not be loaded, so the required scripts aren't injected.
Adding these scripts to the head in these endpoints within the /foo/+page.svelte
allows a browser to navigate directly to an endpoint while retaining the capability to communicate with the backend.
This fails to negate a +layout.svelte
that carries these injections when a user moves from the root to /foo
resulting in doubled inclusion as seen below.
I have confirmed that this problem of double injection remains within the Wails app using solution # 2 with Svelte-kit even without the +layout.svelte
to carry the injection. Currently, Wails is not intended as a served web-app for an external browser to navigate. While this doesn't appear to cause any conflicts, repeated injection can easily consume more resources than necessary as a user continues to navigate.
Great observation!
Based on your second solution I have came up with this solution which is to be placed on every route's +page.svelte
or +layout.svelte
file:
>> NOTE: The following code has few problems. Please refer to the updated code two comments down. <<
import { browser } from "$app/environment";
if (browser && !window.hasOwnProperty("wailsbindings")) {
// Inject missing /wails/ipc.js and /wails/runtime.js
let wails_ipc = document.createElement("script");
wails_ipc.setAttribute("src", "/wails/ipc.js");
let wails_runtime = document.createElement("script");
wails_runtime.setAttribute("src", "/wails/runtime.js");
document.head.appendChild(wails_ipc);
document.head.appendChild(wails_runtime);
}
This avoids repeated injection of the scripts.
Looks like this solves this issue!
Thanks for this! I'll double check this solution in wails and browser this weekend and update the repo accordingly. Both Svelte & JS are new to me but I had considered that there may be a way to check and avoid the repeat.
I've shared this issue with the Wails discord due to the targets of v3; such as multi-window applications and local network web-apps. Which are certainly situations where both the user may choose to start at a location other than root and where it doesn't even necessarily make sense to launch from the root.
It may be more beneficial to contain this snippet in the associated +page.js
on the route (or add it to the $lib
by default) or equivalent in Vue, Angular, etc. This method should at least reduce it to an import and a call. While there's always the option of adding a PR to make a wails (or other) command to generate a new route with the solution, I think working this out might help Wails move towards a more robust and simple development environment. Of course, for simplicity sake, it would be ideal for all frameworks to not need to replicate it or create a variety of custom solutions that are unique to each.
Great observation!
Based on your second solution I have came up with this solution which is to be placed on every route's
+page.svelte
or+layout.svelte
file:import { browser } from "$app/environment"; if (browser && !window.hasOwnProperty("wailsbindings")) { // Inject missing /wails/ipc.js and /wails/runtime.js let wails_ipc = document.createElement("script"); wails_ipc.setAttribute("src", "/wails/ipc.js"); let wails_runtime = document.createElement("script"); wails_runtime.setAttribute("src", "/wails/runtime.js"); document.head.appendChild(wails_ipc); document.head.appendChild(wails_runtime); }
This avoids repeated injection of the scripts.
Looks like this solves this issue!
Looks like a better approach is to have the script injection code on the head tag itself:
<svelte:head>
<script>
if (!window.hasOwnProperty("wailsbindings")) {
let wails_ipc = document.createElement("script");
wails_ipc.setAttribute("src", "/wails/ipc.js");
let wails_runtime = document.createElement("script");
wails_runtime.setAttribute("src", "/wails/runtime.js");
document.head.appendChild(wails_ipc);
document.head.appendChild(wails_runtime);
}
</script>
</svelte:head>
Consider the above code:
+layout.svelte
:
<script lang="ts">
import { browser } from "$app/environment";
if (browser && !window.hasOwnProperty("wailsbindings")) {
let wails_ipc = document.createElement("script");
wails_ipc.setAttribute("src", "/wails/ipc.js");
let wails_runtime = document.createElement("script");
wails_runtime.setAttribute("src", "/wails/runtime.js");
document.head.appendChild(wails_ipc);
document.head.appendChild(wails_runtime);
}
</script>
<slot />
+page.svelte
:
<script>
import { Greet } from "$lib/wailsjs/go/main/App.js";
import { onMount } from "svelte";
onMount(() => {
console.log(Greet("foo"));
})
</script>
The result would be:
Looks like the ipc connection gets established after the onMount()
hook.
layout.svelte
:
<svelte:head>
<script>
if (!window.hasOwnProperty("wailsbindings")) {
let wails_ipc = document.createElement("script");
wails_ipc.setAttribute("src", "/wails/ipc.js");
let wails_runtime = document.createElement("script");
wails_runtime.setAttribute("src", "/wails/runtime.js");
document.head.appendChild(wails_ipc);
document.head.appendChild(wails_runtime);
}
</script>
</svelte:head>
<slot />
The result will be:
It's been 6 months. Are you still using the svelte:head
solution above to avoid IPC issues?
Situationally, yes. One of my projects needs it in the +layout and the other doesn't. I've gone back and forth on including it.
On Sun, Jul 30, 2023, 4:27 PM Isaac Andrade @.***> wrote:
It's been 6 months. Are you still using the svelte:head solution above to avoid routing issues?
— Reply to this email directly, view it on GitHub https://github.com/plihelix/wails-template-sveltekit/issues/5#issuecomment-1657280687, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARUJFUP7LQFVA7EDKWE4SFLXS3NVVANCNFSM6AAAAAAUINWE5M . You are receiving this because you commented.Message ID: @.***>
Description
Calling golang functions in subpages such as
localhost:34115/foo
produces following error:But if we are to goto
/foo
from the homepage (/
) using an anchor tag as<a href="/foo">Goto foo</a>
the function call works as expected but as soon as we refresh the page, it breaks again.To Reproduce
Now browse
http://localhost:34115/foo
, enter a name and click onGreet
:Using anchor tag from homepage
Browse the home page, scroll to bottom and click on
Goto /foo
Scroll to bottom, enter a name and click on
Greet
:This works as expected. But if we refresh the page and again enter a name and click on
Greet
:Expected behaviour
System Details
Additional message
I have tried this only on linux.