Skip to content
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

Customize the BasePath #46

Open
EilifAkerjordet opened this issue Nov 6, 2024 · 7 comments
Open

Customize the BasePath #46

EilifAkerjordet opened this issue Nov 6, 2024 · 7 comments

Comments

@EilifAkerjordet
Copy link

EilifAkerjordet commented Nov 6, 2024

Hi, love the library, it has helped me a lot!

I have used it to hack together some Blazor WordPress-plugins. Locally it runs fine. I am running into issues however when running it on the WordPress server, as scripts are requested through {currentUrl}/_content/xxx instead of {domain}/wp-content/plugins/my-app/_content/xxx

Before hooking on this library this was easily solved by implementing a custom Blazor.start:

Blazor.start({
    loadBootResource: (type, name, defaultUri, integrity) => {
        const basePluginPath = '/wp-content/plugins/myplugin/js/_framework/';
        return basePluginPath + name;
    },
});

Is there a way to achieve the same here?

@jsakamoto
Copy link
Owner

Hi @EilifAkerjordet,
Thank you for reporting. I'm trying to investigate the issue you reported in these two days, but unfortunately, I'm stuck reproducing the problem you ran into.

scripts are requested through {currentUrl}/_content/xxx instead of {domain}/wp-content/plugins/my-app/_content/xxx

Could you tell me the exact names of the script files that failed to load? Providing a screenshot or text of the "network" tab of the browser's dev tools window would be better.

Moreover, if you could provide me with a project that reproduces the problem on my side, it might be possible to resolve it faster. Honestly, the most important thing is that I don't understand precisely what you are doing.

Thank you for your cooperation.

@EilifAkerjordet
Copy link
Author

EilifAkerjordet commented Nov 8, 2024

@jsakamoto, thanks for looking into this! I appreciate it a lot. :-)

Locally/as a normal Blazor WASM app everything works perfectly. It's only when running it on the WP server that I run into issues with the BasePath.

Here is a repo with steps to reproduce. Note that it includes a docker-compose to run the app as a plugin in WordPress.
https://github.com/EilifAkerjordet/blazor-wp-plugin-error-reproduction

Here the network tab:

Screenshot 2024-11-08 at 09 29 04

@EilifAkerjordet
Copy link
Author

EilifAkerjordet commented Nov 8, 2024

I am very new to .NET. But just looking through the repo a bit and noticing this file:

Could it be enough just to allow customizing the <BasePath>_content/BlazorWasmPreRendering.Build</BasePath> ?

@EilifAkerjordet
Copy link
Author

EilifAkerjordet commented Nov 20, 2024

@jsakamoto,

Directly editing the blazor.boot.json did do the trick. Granted its not an ideal solution, it still works:

    "libraryInitializers": {
      "/wp-content/plugins/my-plugin/_content/BlazorWasmPreRendering.Build/BlazorWasmPreRendering.Build.lib.module.js": "sha256-Z094C6tvTOKvix221ZuSPsaaNvGOp0XKqThmB4vfuOA="
    },
    "modulesAfterConfigLoaded": {
      "/wp-content/plugins/my-plugin/_content/BlazorWasmPreRendering.Build/BlazorWasmPreRendering.Build.lib.module.js": "sha256-Z094C6tvTOKvix221ZuSPsaaNvGOp0XKqThmB4vfuOA="
    }

@jsakamoto
Copy link
Owner

Hi @EilifAkerjordet,
I'm investigating this issue. So far, the root cause seems to be Blazor's JavaScript initializer, which is confused in unusual environments for the usual Bazor app, such as WordPress plugins.

I'll keep trying to find a better way and legal solution.

In the meantime, I believe your workaround, such as directly editing the blazor.boot.json, is the best.

@jsakamoto
Copy link
Owner

Hi @EilifAkerjordet,
Could you try using the implementation below for "initialize-blazor.js"? Based on my investigation, the following implementation looks to work fine.

// initialize-blazor.js
(() => {

    const basePluginPath = '/wp-content/plugins/akapluss-benefit-search-entrance/';

    let restoreOriginalBaseElement = null;

    const ensureBaseElementWithPluginPath = () => {
        return (() => {
            // Just in case, check if the base element is already present in the head element.
            const existsBase = document.querySelector('head base') !== null;
            if (existsBase) return () => { };

            // When the base element is absent, we must add it to the head element 
            // to ensure that relative URLs are resolved correctly when loading resources.
            const base = document.createElement('base');
            base.href = basePluginPath;
            document.head.appendChild(base);
            return () => { document.head.removeChild(base); }
        })();
    }

    Blazor.start({
        loadBootResource: (type, name, defaultUri, integrity) => {

            // Revert the changes made to the head element made during previous resource loading.
            restoreOriginalBaseElement?.();
            restoreOriginalBaseElement = null;

            // Before loading the 'blazor.boot.json' file, we ensure that the base element 
            // with the correct base plugin path is in the head element. 
            // This is necessary to ensure that relative URLs are resolved correctly 
            // when loading JavaScript initializers.
            if (name === "blazor.boot.json") {
                restoreOriginalBaseElement = ensureBaseElementWithPluginPath();
            }

            return `${basePluginPath}_framework/${name}`;
        },
    });

})();

The root cause of your reported issue is that the base URL is not explicitly specified in the HTML pages that WordPress produces. Blazor's importing JavaScript initializer process strongly depends on the `document.baseURI" to resolve the path of JavaScript initializer script files, so it crashes with an unstabilized base URL.

So, as you can see above, I couldn't resolve the issue without a hack that sets up the <base> element on the fly to resolve the issue you reported.

I hope this answer resolves the problem on your side, too.

@EilifAkerjordet
Copy link
Author

EilifAkerjordet commented Nov 24, 2024

@jsakamoto,

First of all, thank you for spending time on this.

This in conjunction with directly modifying the libraryInitializers and modulesAfterConfigLoaded in blazor.boot.json to the full and absolute path does work. For my use case that is good enough. Making Blazor components into WordPress widgets is a bit hacky to begin with, it was never gonna work seamlessly out of the box.

EDIT:
It works even without directly modifying libraryInitializers and modulesAfterConfigLoaded in blazor.boot.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants