Lit-html: How to load scripts in rendered html

Created on 23 Dec 2018  路  7Comments  路  Source: Polymer/lit-html

I'm trying to load external html inside my lit-element, I'm using lit-html to render the template with couple 'script' and 'link' tags, but no GET request are triggered.
I found out that if you set the innerHTML, scripts won't be executed but script-inside-shadow-dom-not-working solution will work.
I'a looking for better and robust solution for dynamic and unknown HTML so I can load it in run time.

render() {
    return html`
      <h3>I'm a Web Component</h3>
      <script type="text/javascript" src="some-index.html"></script>
    `
  }
Medium

Most helpful comment

If you load your HTML via fetch, you can render it with the unsafeHTML and until directives:

import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
import {until} from 'lit-html/directives/until.js';

const someHTML = fetch('some-index.html').then((response) => unsafeHTML(response.text()));

render() {
    return html`
      <h3>I'm a Web Component</h3>
      ${until(someHTML)}
    `;
  }

This _should_ work, but combining directives can be tricky. Let me know if there's an issue.

All 7 comments

You are trying to load html in a script tag, that won't work. There is no browser-native way to load HTML on the web. There was HTML Imports, but it's now deprecated: https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports

There is a proposal for HTML modules but it's not there yet: https://github.com/w3c/webcomponents/issues/645

For loading javascript dynamically, there is a new browser standard called dynamic imports. It's only implemented in chrome, but others will follow soon. All modern build tools use it for code splitting, so if you're using a build step it will be fine. See: https://developers.google.com/web/updates/2017/11/dynamic-import

Thanks.
I could use build tools like webpack and probably my problems will be solved, the problem is that I have to load on run time and I don't really know the content of the html (but I can trust it).
As I don't have good solution, I trying to use jQuery load (yeh, I know) or manually find and parse any script that I'll find on the retrieved html.

If you load your HTML via fetch, you can render it with the unsafeHTML and until directives:

import {unsafeHTML} from 'lit-html/directives/unsafe-html.js';
import {until} from 'lit-html/directives/until.js';

const someHTML = fetch('some-index.html').then((response) => unsafeHTML(response.text()));

render() {
    return html`
      <h3>I'm a Web Component</h3>
      ${until(someHTML)}
    `;
  }

This _should_ work, but combining directives can be tricky. Let me know if there's an issue.

Great answer! Thanks

@justinfagnani Yes, but that still does not execute script tags inside the HTML inserted with unsafeHTML (probably because under the hood it uses innerHTML), which is what my cool-o system for composing apps needs to do.

@rtm: Correct, script tags need to be handled specially to be able to run them. You'll have to create a directive to document.createElement('script') and set the inner text on that node, then insert the node into the DOM.

See https://stackblitz.com/edit/lit-html-script-tag for a working example.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pmkroeker picture pmkroeker  路  5Comments

dakom picture dakom  路  4Comments

dflorey picture dflorey  路  4Comments

justinfagnani picture justinfagnani  路  3Comments

AndyOGo picture AndyOGo  路  3Comments