sveltejs / kit

web development, streamlined
https://kit.svelte.dev
MIT License
18.45k stars 1.89k forks source link

Installing SvelteKit in WordPress: Page keeps reloading infinitely #10500

Open dayton-outar opened 1 year ago

dayton-outar commented 1 year ago

Describe the bug

Page keeps reloading in WordPress admin page after the all the build files have been referenced properly. It reloads in an infinite loop.

The +layout.js is set as,

export const prerender = true;
export const ssr = false;

The svelte.config.js file is condifgured as,

import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/kit/vite';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    kit: {
        // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
        // If your environment is not supported or you settled on a specific environment, switch out the adapter.
        // See https://kit.svelte.dev/docs/adapters for more information about adapters.
        adapter: adapter(),
        paths: {
            base: '/wp-content/plugins/astro-forms/assets'
        }
    },
    preprocess: vitePreprocess()
};

export default config;

The vite.config.js is set as,

import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
    plugins: [sveltekit()]
});

When the build is run it produces several files in an _app folder and a version.json file. The files are copied into the WordPress plugins assets folder and are referenced using the admin_head action hook to do the following,

public static function astroFormsModulePreloadLinks()
    {
        $version = '1.2';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/entry/start.7b810d09.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/chunks/scheduler.ec1e1a00.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/chunks/singletons.0451d5e2.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/chunks/index.0b861ccf.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/entry/app.749411f8.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/chunks/preload-helper.a4192956.js?v=' . $version . '">';
        echo '<link rel="modulepreload" href="' . AF_PLUGIN_URL . 'assets/_app/immutable/chunks/index.a313f8a5.js?v=' . $version . '">';
    }

The script within the body of the page is modified as follows,

{
                    const thisBase = new URL("<?php echo AF_PLUGIN_URL . 'assets/' ?>", location).pathname.slice(0, -1);
                    console.log( thisBase );
                    __sveltekit_h36q48 = {
                        assets: thisBase,
                        base: new URL(thisBase, location).pathname.slice(0, -1),
                        env: {}
                    };

                    const element = document.currentScript.parentElement;

                    Promise.all([
                        import( thisBase + "/_app/immutable/entry/start.7b810d09.js"),
                        import( thisBase + "/_app/immutable/entry/app.749411f8.js")
                    ]).then(([kit, app]) => {
                        kit.start(app, element);
                    });
                }

When the page is loaded, it keeps reloading.

Reproduction

Load the page when all the scripts have been properly referenced in the WordPress plugin

Logs

No response

System Info

Using,
- @sveltejs/kit v 1.20.4
- @sveltejs/adapter-static v 2.0.3

Building with,
 - vite v 4.4.2

Severity

blocking all usage of SvelteKit

Additional Information

No response

khromov commented 1 year ago

👋 Hi, I was just working with this today and I managed to fix the infinite reloading issue, I'll summarize below:

The problem is that if you configure the base path SvelteKit will get sad if you try to load the app outside that base and redirect you in a loop. By configuring base the URLs to the JS are correct but when you try to embed the content of the built index.html page at / (ie the WordPress site root) it goes into a redirect loop because it expects to load from /wp-content/plugins/sveltekit-wordpress-plugin/sveltekit/build/

At the entrypoint in start.js SvelteKit runs client.goto(location.href, { replaceState: true }); which triggers location.href = url.href; causing the loop. That's why I asked if it was possible to skip the router. :sweat_smile: I tried data-sveltekit-reload on the div surrounding the app like <div data-sveltekit-reload>%sveltekit.body%</div> but it didn't help.

I did get it to work by not setting base and instead manually rewriting the paths in the init object, like this:

Promise.all([
    import("/wp-content/plugins/sveltekit-wordpress-plugin/sveltekit/build/_app/immutable/entry/start.5d2b6790.js"),
    import("/wp-content/plugins/sveltekit-wordpress-plugin/sveltekit/build/_app/immutable/entry/app.cbd67c23.js")
]).then(([kit, app]) => {
    kit.start(app, element);
});

You can do this with a regex replace in PHP for example.

It does work, but the routing is funny, eg if you have a /foo route then when you init the app on wordpress-site.com/foo then the Svelte /foo route will load, which is probably not what you want when you're embedding the app. My naive approach would be that you could feed the path to the SvelteKit app when initializing it, as that's easily done from PHP.

I also changed app.html to be just:

%sveltekit.head%
<div data-sveltekit-reload>%sveltekit.body%</div>

... so that you wouldn't have multiple body tags and such.

Codargorn commented 10 months ago

I encountered exactly the same problem today. Is there another, perhaps less messy solution?