How to import <template> with <Link import> becoming obsolete?

I have read your excellent articles on ESModules and but I cannot find anywhere how to import a web component that includes a since the link import has become obsolete. Any help would be great!
Thanks again

Hi,
This is the documentation on MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

1 Like

Thanks for your quick answer, but this new import does not allow to import html, like for example. It is limited to javascript.
How can I import HTML content (like tags)?

Hi
Can you give more info about the stack you are using please?

Hi @axel.buendia –

You mentioned web components. They are not managed with imports; they are managed through the CustomElementRegistry object. You can learn more in the Web Components section of MDN.

Hi, I am not using any stack, just good old html and js files.
I have developped several web components containing each a javascript part (the class of the component and the register part), with a html part (the tag).
With new import method () I cannot import anymore the html part containing the part. My question is how can I import the html part (the tag) into my main html file?
Thanks a lot and sorry if I was not clear :wink:

TBH I think you have a compatibility problem – this is an educated guess – but without digging into your code I can’t offer a solution. I do have one more suggestion: you should check out Pug. Good luck!

Thanks again, I can put the code:
mainhtmlfile.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Component</title>
  <link rel="import" href="template.html"/>
</head>
<body>
<div-component>essai</div-component>
</body>
</html>

The html file that contains the template tag:
template.html

<template id="divComponent">
  <style>
  .divComponentCl {
    border-top: 3px solid #c1002a !important;
    border-bottom: 3px solid #c1002a !important;
    padding: 3px 3px;
    text-align: justify;
  }
  </style>
  <div class="divComponentCl">
    <table style="border: none;"><tr><td><img alt="icone" width="70"/></td><td></td></tr></table>
  </div>
</template>

<script>
class DivMessage extends HTMLElement {
  constructor(){
    super();
  }
  connectedCallback(){
    var template;
    if(typeof document.currentScript === 'undefined' || document.currentScript == null)
      template = document.getElementById('divMessage');
    else
      template = document.currentScript.ownerDocument.getElementById('divMessage');
    if(template == null){
      window.console.error('Template [divMessage] not found in document');
      return;
    }
    ...
    var clone = template.content.cloneNode(true);
    var shadow = this.attachShadow({mode:'open'});
    shadow.appendChild(clone);
  }
}

window.customElements.define('div-message', DivMessage);
</script>

This was working just fine. But the <link type=“import” is obsolete. So I decide to use the web component API (ESModule).
The main html file becomes:
mainhtmlfile.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Component</title>
  <script type="module" src="components.js"></script>
</head>
<body>
<div-component>essai</div-component>
</body>
</html>

I cannot put any html tags into the components.js file. The web component js file, which includes the class:
component.js

class DivMessage extends HTMLElement {
  constructor(){
    super();
  }
  connectedCallback(){
    var template;
    if(typeof document.currentScript === 'undefined' || document.currentScript == null)
      template = document.getElementById('divMessage');
    else
      template = document.currentScript.ownerDocument.getElementById('divMessage');
    if(template == null){
      window.console.error('Template [divMessage] not found in document');
      return;
    }
    ...
    var clone = template.content.cloneNode(true);
    var shadow = this.attachShadow({mode:'open'});
    shadow.appendChild(clone);
  }
}

window.customElements.define('div-message', DivMessage);

So my question is, where do I put the <template> tag that used to be in the template.html?
I cannot put it into the main html file because I am a component provider, and I do not know in which html files my components will be used.
Thanks again for your help, I hope the code will clarify the situation.

I recommend using uhtml or lighterhtml, which allows you to include the contents of the <template> element in your JS code as a tagged template literal:

// component.js

import { render, html } from "https://unpkg.com/uhtml?module";
// or
import { render, html } from "https://unpkg.com/lighterhtml?module";

class DivMessage extends HTMLElement {
	constructor() {
		super();
		const shadow = this.attachShadow({ mode: "open" });
		render(shadow, html`
			<style>
				.divComponentCl {
					border-top: 3px solid #c1002a !important;
					border-bottom: 3px solid #c1002a !important;
					padding: 3px 3px;
					text-align: justify;
				}
			</style>

			<div class="divComponentCl">
				<table style="border: none;">
					<tr>
						<td><img alt="icone" width="70"/></td>
						<td></td>
					</tr>
				</table>
			</div>
		`);
	}
}

window.customElements.define("div-message", DivMessage);
1 Like

I can see you have worked hard on this. Rather than try to salvage what you have already done; use React or another js lib because this will not work this way. You could read this: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
and try to modify it. But I think you will have an easier time of it if you use a framework.

Thanks again for your answer. I will try string literals. I do not want to use framework yet :wink:
It is a shame that the consortium removed something that was useful (include of html tags)…

Thanks to everyone, here is the final version (for the record):
main.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>ComponentTest</title>
  <script type="module">
  	import {DivMessage} from './component.js';
  </script>
</head>
<body>
<div-message>message</div-message>
</body>
</html>

component.js

const divMessageInnerHTML = `
  <style>
  .divMessageCl {
    border-top: 3px solid #c1002a !important;
    border-bottom: 3px solid #c1002a !important;
    padding: 3px 3px;
    text-align: justify;
  }
  .divMessageCl td {
    padding: 0;
    margin: 0em 1em;
  }
  .divMessageCl table {
    padding: 0;
    margin: 0;
  }
  .progress {
    height: 10px;
    background-color: orange;
  }
  </style>
  <div class="divMessageCl">
    <table style="border: none;"><tr><td><img alt="icone" width="70"/></td><td></td></tr></table>
  </div>`;

// DivMessage is a component to use to highlight a text in a box with an icon
export class DivMessage extends HTMLElement {
  // cannot use this at this step because it has no content yet
  constructor(){
    super();
  }
  // this contains everything at this stage!
  connectedCallback(){
    var template = document.createElement('template');
    template.innerHTML = divMessageInnerHTML.trim();
    var clone = template.content.cloneNode(true);
    var innerContent = innerImg.parentNode.nextSibling;
    innerContent.innerHTML = this.innerHTML;
    var shadow = this.attachShadow({mode:'open'});
    shadow.appendChild(clone);
  }
}

customElements.define("div-message", DivMessage);
1 Like