UXP WebView support for loading local html content

UXP WebView only supports loading from a web URL and currently does not support loading local html content.
Is there any possibility that local html content loading will be implemented in the next UXP updates?

1 Like

This is English speaking forum :thinking:

Could you further describe your use case? This isn’t the first request for local content.

2 Likes

Hi @Erin_Finnegan, thanks for replying!
In my use case, webView loading local html content would avoid overloading the index.htm file by having an overly large UXP Plugin with dozens of buttons, among them loading svg codes that call a dozen or more complex modal windows consuming a large amount of lines of code only in an html file and that undergoes constant changes and having to maintain it. It would be fantastic to be able to count on this functionality because I will be able to separate all the code from the index.htm file into several files.html, making it easier to edit or maintain them.
Being able to load a modal window with the .htm file created just for its interface would be a dream.

Thanks! I’ll add @pkrishna here to note this…

2 Likes

Am trying to understand the use case here a bit more in detail.
I understand that maintaining a single large htm file can be cumbersome but I think it is possible to split it into multiple files even now without the support of local html. The src attribute can take any web url. If the index.htm is split into different html files, with each file having a unique url (like any other web application), you should be able to load a modal with that specific html, no?

Apologies in advance if I have misunderstood the problem statement.

1 Like

Hi @pkrishna , thank you for analyzing my case, you understood perfectly.
I was excited to learn that maybe uploading .html file separately is possible.
I tried to follow your suggestion with the tribute Src but I wasn’t successful.
I saw on the internet that this src attribute refers to loading images or url inside an iframe which is not supported by uxp.
I tried this:
project:
Captura de tela 2023-01-11 134100
index.htm

<sp-action-button class="botoes" id="btn" > <a href="'modal.html"></a> Open modal</sp-action-button>  
<dialog  id="modal" src="modal.html">
//Here loaded the elements of the modal.html file
</dialog>

modal.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Modal</title>
</head>
<body>
    <h1>Hello world! Here is the modal page</h1>
</body>
</html>

js

document.getElementById('btn').addEventListener('click', async () => {
  await core.executeAsModal(async () => {
    document.querySelector("#modal").show({ title: "Acesso a conteúdo web!", resize: "both", size: { width: 260, height: 60 } })
  })
})

I tried that but I couldn’t load the modal.html page inside the modal window.
Any help is valid. thanks

dialog doesn’t support src. I believe you would need an iframe in the dialog probably

I’ve done this by simply by getting my local html file content and stringifying it using fetch(URL).text(); and then rendering it in the required html element with .innerHTML

That’s if I’m understanding what you want to achieve correctly - i.e. split your html into separate files. I’m not taking into account any requirement to use WebView.

1 Like

@Karmalakas
Does uxp support iframes? Have you already used it?, did it work for you?? WebView would be iframes for uxp but without access to local content, at least that’s what I understand.

Hi @Timothy_Bennett your approach seems to be quite interesting, could you show me a good example, it might be with my code above. Thanks.
The base of my dialog windows has dozens of elements, as I show in this example below
Capturar

I load all my plugin HTML this way except for a basic layout that houses the loaded content.

const path = <path to an html file>;

const content = await fetch(path).text();

const container = document.querySelector("#<id of element in main html file in which to insert content>");

container.innerHTML = content;
2 Likes

Excellent! Should I save the formatting of the auxiliary .html file normally?
type:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Modal</title>
</head>
<body>
    <h1>Hello world! Here is the modal page</h1>
</body>
</html>

Your main HTML file already has the html, head, and body tags covered, you’ll just be inserting HTML into an existing element, so your file only needs to be an HTML snippet - In your case, your modal dialog’s content.
I hard code a basic dialog with no content into my main HTML file - here’s a very simple example of what my main HTML file might look like for a single page plugin with a modal:

<!DOCTYPE html>
<head>
    <!-- Meta stuff !-->
</head>
<body>
    <!-- Main content loaded here !-->
    <div id="main-content">
    </>

    <!-- Dialog content loaded here !-->
    <div id="dialog">
    </>
</body>
</html>
1 Like

@Timothy_Bennett thank you for everything! I’ll try it out and come back to let you know if it worked.

Hi @Timothy_Bennett , I followed your method, but it didn’t work for me.

const path = "modal.html";
const content = await fetch(path).text();
const dlg = document.querySelector("#dlg");
dlg.innerHTML = content;
console.log(content)

I found something that helped me in this video:

The result was positive in this way

document.getElementById('btn').addEventListener('click', async () => {
  await core.executeAsModal(async () => {      
    openModal()
   })
})

function openModal() {
    const path = "modal.html";
    const dlg = document.querySelector("#dlg");
    fetch(path).then(function(respnse) {
        return respnse.text();
    }).then(function(content) {
        dlg.show({
            title: "Dialog",
            resize: "both",
            size: {
                width: 260,
                height: 100
            }
        })
        dlg.innerHTML = content;
    })
}

Here is the plugin working:
UXP-EXT-HTML_PS.ccx (6.2 KB)
You were genius, thanks for pointing me in the right direction.
This feature is awesome and will certainly help me a lot.

1 Like

The reason it didn’t work is because await needs to be wrapped in an async function:

async function exampleFunc() {
    const waiting = await fetch()
}

That said, the way you’ve done it is perfectly valid and whether you use aysnc/await or .then().catch() is entirely personal preference. I like async/await as I find it more readable.

I’ll also point out that showing a Dialog doesn’t require you to use executeAsModal, although there are valid reasons why you might want to so I’m not going to say you’re wrong!

1 Like

The main objective of this topic is to find a solution to make my codes as clean and readable as possible, the alternative I found perfectly meets my needs, however your method is much cleaner and more readable, that’s what I’m looking for. The problem is that I haven’t been successful with my attempts.
Look:

async function openModal() {
    try {
        const path = "modal.html";
        const content = await fetch(path).text();
        const dlg = document.querySelector("#dlg");
        dlg.show({ title: "Dialog", resize: "both", size: {  width: 260, height: 100 } })
        dlg.innerHTML = content;
    } catch (err) {
        console.log(err)
    }
}

Received error:
Captura de tela 2023-01-12 140353

And I just tried with <webview> and no matter how I try to load local HTML, it just ends in loaderror event with message Operation canceled. Apparently not supported after all :frowning:

Apologies @PS-fxrios, my solution of using ‘src’ was meant for webviews. I didnt understand that you were trying to load the modal content with different html.

Webview doesnt support loading local htmls as of now, unless you are loading it using localhost. We might add this support in the future though.

2 Likes