ShocKwav3_
ShocKwav3_

Reputation: 1760

How to import libraries using CDN links into reactjs?

I have tried:

import 'maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css';

but it produces error. How can I import a CDN link into my app.js file?

Upvotes: 53

Views: 121234

Answers (5)

Alex Cory
Alex Cory

Reputation: 11855

I did something like this so you can

  1. wait for the script to load
  2. support for SSR
  3. will not attempt to load the script multiple times

Example:

const doSomething = async () => {
  const { isServer, loaded, ...event } = await loadScript('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js', {
    async: true 
  })
}

Source

import { pEvent } from 'p-event'

export const loadScript = async (src, opts = {}) => {
  if (typeof window === 'undefined') return { isServer: true }
  if (document.readyState === 'loading') {
    await pEvent(document, 'DOMContentLoaded')
  }
  const scriptEls = Array.from(document.getElementsByTagName('script'))
  const scripts = scriptEls.map(s => s.src)
  if (scripts.includes(src)) return { loaded: true }
  const script = document.createElement('script')
  script.type = 'text/javascript'
  script.src = src
  Object.assign(script, opts)
  let head = document.getElementsByTagName('head')[0]
  head.appendChild(script)
  const event = await pEvent(script, 'load')
  return event
}

Upvotes: 0

Ozan
Ozan

Reputation: 1

I don't know if it is applicable in this situation, but I use the following method to load CDN sources in case I need them. I use some libraries only if the corresponding element appears on the page:

const lazyLoadFromCDN = (callback: Function) => {
    const mathJax = document.createElement('script');
    mathJax.setAttribute('src', 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js');   
    mathJax.addEventListener('load', () => callback());
    document.head.appendChild(mathJax);
}

Upvotes: 0

Rafael Berro
Rafael Berro

Reputation: 2601

You can include these lines within your html file:

<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>

Or, you can import a local stylesheet file that contains the import instruction. See the example below:

App.js

import './App.scss';

App.scss

@import url('https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css');

Upvotes: 32

CJY0208
CJY0208

Reputation: 195

I think we can write some function like this

const fetchJsFromCDN = (src, externals = []) => {
  new Promise((resolve, reject) => {
    const script = document.createElement('script')
    script.setAttribute('src', src)
    script.addEventListener('load', () => {
      resolve(externals.map(key => {
        const ext = window[key]
        typeof ext === 'undefined' && console.warn(`No external named '${key}' in window`)
        return ext
      }))
    })
    script.addEventListener('error', reject)
    document.body.appendChild(script)
  })
}

fetchJsFromCDN('//cdn.jsdelivr.net/npm/eruda', ['eruda']).then(([eruda]) => eruda.init())

without function like require, CDN source may inject object to window so we can get it by given name

CSS files could be easier to import with this way

Upvotes: 6

hazardous
hazardous

Reputation: 10837

You don't bundle CDN stuff inside your JS, that sort of defeats the purpose of having it on CDN :). Had this been JS, I would have asked you to use externals, but for a CSS, you can use https://github.com/jso0/html-webpack-cdn-plugin instead.

Upvotes: 15

Related Questions