〈load-file〉Web Component, add external content to the DOM
Tags: webcomponents, javascript, svg, showdev
Published: 2021-05-28 13:25:15

---
title:〈load-file〉Web Component, add external content to the DOM
published: true
description: Add external content (HTML, SVG, Markdown) to the DOM 
tags: webcomponents,javascript,svg,showdev
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bub6qy1tttnepd9qc0ut.png
---

Whilst we are waiting for [HTML Modules](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md) to arrive in all Browsers ([Chrome Platform Status](https://chromestatus.com/feature/4854408103854080))


# The〈load-file〉Web Component

### ✔️ Fetches **any** external text file: ie. ``.txt`` , ``.svg`` , ``.html``

#### ✔️ Injects the content into the DOM

* in shadowDOM

  * respects _lightDOM_ content for _shadowDOM_ ``<slot>`` elements
  * with optional _**scoped**_ CSS styling! ✨✨✨
  * can _move_ lightDOM content to _shadowDOM_

* *Or* replaces the ``<load-file>`` element *itself* with the ``replaceWith`` attribute

#### ✔️ is **not** a replacement for 'HTML Imports'; ``<script>`` will **not** execute

#### ✔️ is done in **7** lines of code:  

{% jsfiddle https://jsfiddle.net/WebComponents/bfe0r4j9 js,result,html,css %}

<hr>

# There are multiple ways to put an _external_ SVG file on the page

source: https://vecta.io/blog/best-way-to-embed-svg

* ### 👉 as src : 
``<img src="file.svg">``

   * SVG content can **not** be styled with CSS  

* ### 👉 as Object : 
``<object type = "image/svg+xml" data="file.svg"></object>``

   * CORS restrictions apply

* ### 👉 as CSS background-image 
``background-image: url(file.svg)``

   * (2019) [Inline SVG in CSS background with custom properties](https://adactio.com/journal/15075)
   * (2015) [CSS-Tricks: Using SVG background-image](https://css-tricks.com/lodge/svg/06-using-svg-svg-background-image/)  

* # 👉 🎉 **use the ``<load-file>`` Web Component** 🎉

    * it provides _scoped_ CSS styling

    * Load the SVG

   ```html
   <load-file replaceWith src="//load-file.github.io/heart.svg"></load-file>

   <load-file src="//load-file.github.io/heart.svg">
    <style shadowRoot>
      path:nth-child(2n+2) {
        fill: GREEN; /* shadowDOM style does NOT style global DOM */
      }
    </style>
   </load-file>
   ```
   * display as bare SVG, by using the ``replaceWith`` attribute
       * (global) CSS styles **all** SVGs (see red heart puzzle pieces)
   * OR, display contained in shadowDOM
       * now (local) CSS styles **one** SVG (see green heart puzzle pieces)


{% jsfiddle https://jsfiddle.net/WebComponents/bfe0r4j9 result,html,js,css %}

<hr>

# Loading the &lt;load-file> Web Component
Load the element from the Repo

```html
<script src="https://load-file.github.io/element.js"></script>
```

It doesn't matter **when** the Custom Element is loaded/defined. 

Any existing ``<load-file>`` elements in the document will *automagically* **upgrade** when the Custom Element is defined later.

**or** define the *entire* element in the &lt;head> of your HTML document with a &lt;script> tag:

```html
<script>
customElements.define("load-file",class extends HTMLElement{async connectedCallback(){
this.shadowRoot||this.attachShadow({mode:"open"});this.shadowRoot.innerHTML=await(
await fetch(this.getAttribute("src"))).text();this.shadowRoot.append(...this.children);
this.hasAttribute("replaceWith")&&this.replaceWith(...this.shadowRoot.children)}})
</script>
```

<hr>

# Using the &lt;load-file> Web Component

Specify the full path in the ``src`` attribute

add the ``replaceWith`` attribute so the src content **replaces** the ``<load-file>`` Element **itself** in the document

```html
<load-file  replaceWith  src="https://load-file.github.io/heart.svg"></load-file>
```
!! Note the CAPITAL in ``replaceWith`` (creates a better GZip compressed file)

<br>

Without ``replaceWith`` the source content will be injected in shadowDOM:

```html
<load-file src="https://load-file.github.io/heart.svg"></load-file>
```

**All** elements with attribute ``shadowRoot`` are **moved** to shadowDOM:

```html
<load-file src="https://load-file.github.io/heart.svg">
    <style shadowRoot>
      path:nth-child(2n+2) {
        fill: GREEN; /* shadowDOM style will NOT style global DOM */
      }
    </style>
</load-file>
```

{% jsfiddle https://jsfiddle.net/WebComponents/bfe0r4j9 result,html,js,css %}


<hr>


<br>
<hr>
<br>

{% jsfiddle https://jsfiddle.net/WebComponents/62f1eLay result,html,js %}