Last active
January 22, 2025 02:08
-
-
Save MrJackdaw/d111b5bcdfc8b71afba8ba6c55b3168f to your computer and use it in GitHub Desktop.
Reusable class for loading external script files (e.g. from CDN)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example usage of Inject-Script.js | |
// Example 1: Load a script from an external URL. (preferred method) | |
// You can call this in a React/Vue/whatever component lifecycle, or wherever. | |
// makes sense. Window globals (e.g. `window.YT`) will be available after calling this. | |
await injectScriptBySrc("https://www.youtube.com/iframe_api", "yt"); | |
// now you can use `window.YT` methods and properties in your code. | |
// Example 2: Load the raw text content of a script into a page | |
// You can also call this wherever it makes sense, though it is probably a | |
// terrible idea to trigger code this way, and you *should* likely be ashamed. | |
const myShamefulJS = ` | |
const something = 1; | |
console.log( something ); | |
` | |
injectScriptContents(myShamefulJS); | |
// logs "1" to console after the above line executes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @file Inject-Script | |
* @description DYNAMICALLY INJECT EXTERNAL SCRIPT DEPENDENCIES INTO YOUR WEB APP | |
* | |
* NOTE: Track page-session scripts (i.e. scripts that should be reloaded with the page). | |
* You can track as few or as many script dependencies as needed: YouTube is provided as an | |
* example below. | |
*/ | |
// (example for tracking YT script dependency) | |
let YouTubeLoaded = false; | |
// (example if loading Google Charts script into your app) | |
// let GoogleCharts = false; | |
/** | |
* Inject a `<script />` tag with the supplied contents into the page's | |
* html. This will execute `contents` immediately. You should ideally prefer | |
* `injectScriptBySrc( ... )` over this method. If it MUST be used, modify | |
* this file to track any required scripts that have to be loaded in this way. | |
* @param {string} contents Script tag contents | |
*/ | |
export function injectScriptContents(contents) { | |
const scrpt = document.createElement('script'); | |
scrpt.innerHTML = contents; | |
const lastElem = document.head.lastChild; | |
document.head.insertBefore(scrpt, lastElem); | |
// Update module state to track that this script has been loaded. e.g.: | |
// | |
// YouTubeLoaded = (key === "yt"); | |
// GoogleChartsLoaded = (key === "gc"); // etc | |
} | |
/** | |
* Inject a `<script />` tag by `src` attribute into the page's | |
* html. This will execute `contents` immediately. | |
* @param {string} src External URL for Script source | |
* @param {string|undefined} key An internal identifier that helps track whether | |
* this script has been loaded in your app (so you don't load it multiple times) | |
*/ | |
export async function injectScriptBySrc(src, key) { | |
// IMPORTANT: Check if script has been loaded; exit if true. For example: | |
// if (key === "yt" && YouTubeLoaded) return; | |
// Load script from source and inject into page | |
const scrpt = document.createElement('script'); | |
scrpt.src = src; | |
scrpt.id = `${key}-script`; | |
const lastElem = document.head.lastChild; | |
document.head.insertBefore(scrpt, lastElem); | |
// Update module state to track that this script has been loaded. e.g.: | |
// | |
// YouTubeLoaded = (key === "yt"); | |
// GoogleChartsLoaded = (key === "gc"); // etc | |
} | |
/** | |
* Identify and remove <script /> tag by its id from the page | |
* @param. {string} key Internal identifier for script, so that the module can | |
* track its loaded/unloaded status | |
*/ | |
export function unmountScript(key: string) { | |
const id = `${key}-script`; | |
const script = document.getElementById(id); | |
if (script) script.remove(); | |
// Update module state to track that this script has been unloaded. e.g.: | |
// | |
// switch (key) { | |
// case "gc": return void (GoogleChartsLoaded = false); | |
// case "yt": return void (YouTubeLoaded = false); | |
// default: break; | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Public Service Announcement
The gist and example above have been completely changed to reflect my latest approach to this problem.
While I still haven't used
react-hot-loader
, all comments prior to 2025 are aimed at a previous gist. See revisions for previous versions.