Inject JavaScript Or CSS At Runtime And On Demand

How to load a JavaScript library, component or a style only when you really need it #OneTrickADay-32

Image for post
Image for post
Photo by Aditya Saxena on Unsplash

Load Conditionally A Script

npm init stencil
cd my-component
npm install
import { Component, h } from '@stencil/core';

@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {

async componentDidLoad() {
const scripts = document.querySelector('[myscript-loaded]');

if (!scripts) {
// TODO: load script
}
}

render() {
return <div>Hello, World!</div>;
}
}
import { Component, h } from '@stencil/core';

@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {

async componentDidLoad() {
const scripts = document.querySelector('[myscript-loaded]');

if (!scripts) {
const script = document.createElement('script');

script.onload = async () => {
script.setAttribute('myscript-loaded', 'true');
};

script.onerror = async ($err) => {
console.error($err);
};

script.src = 'https://unpkg.com/myscript.js';
script.defer = true;

document.head.appendChild(script);
}
}

render() {
return <div>Hello, World!</div>;
}
}

Cory’s Generic Functions

function injectJS(id: string, src: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
if (!document) {
resolve();
return;
}

if (document.getElementById(id)) {
resolve('JS already loaded.');
return;
}
const script = document.createElement('script');

script.id = id;
script.async = true;
script.defer = true;
script.src = src;

script.addEventListener('load', () => resolve('JS loaded.'));

script.addEventListener('error', () => reject('Error script.'));
script.addEventListener('abort', () => reject('Aborted.'));

document.head.appendChild(script);
});
}

function injectCSS(id: string, src: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
if (!document) {
resolve();
return;
}

if (document.getElementById(id)) {
resolve('CSS already loaded.');
return;
}

const link = document.createElement('link');
link.id = id;
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', src);

link.addEventListener('load', () => resolve('CSS loaded.'));

link.addEventListener('error', () => reject('Error css.'));
link.addEventListener('abort', () => reject('CSS aborted.'));
document.head.appendChild(link);
});
}
await injectJS('firebase-ui-script', 'https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.js');await injectCSS('firebase-ui-css', 'https://cdn.firebase.com/libs/firebaseui/4.0.0/firebaseui.css');

Summary

Freelancer by day | Creator of DeckDeckGo by night | Organizer of the Ionic and IndieHackers Zürich Meetup

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store