0

I have gone through many answer but still unable to do it

This Works Perfectly fine when js is included in public folder but this doesn't work when route changes

<script src="%PUBLIC_URL%/JS/jQuery-2.1.4.min.js"></script>
<script src="%PUBLIC_URL%/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script src="%PUBLIC_URL%/JS/app.min.js"></script>

I included this code in my header file to add extrenal js file and works properly but each time the page changes script gets added. I am missing something in loadScript function.

export default class Header extends Component {
    componentDidMount() {
        var loadScript = function (src) {
            var tag = document.createElement('script');
            tag.type = "text/javascript";
            tag.async = false;
            tag.src = src;
            var body = document.getElementsByTagName('body')[0];
            body.appendChild(tag);
        }
        loadScript("/JS/jQuery-2.1.4.min.js");
        loadScript("/BOOTSTRAP-JS/bootstrap.min.js");
        loadScript("/JS/app.min.js");
    }

    render() {
        return (
            <header className="main-header">
                <a href="#" className="logo">
                    <span className="logo-mini"><img src={ImageSmall} /></span>
                    <span className="logo-lg">
                        <img src={RelconImage} style={{ width: '170px', height: 60 }} />
                    </span>
                </a>
                <nav className="navbar navbar-static-top" role="navigation">
                    <img src={menuIcon} className="sidebar-toggle" data-toggle="offcanvas" role="button" style={{ width: '55px' }} />
                    <label style={{ color: 'white', paddingTop: '18px' }} />
                    <div className="navbar-custom-menu">
                        <ul className="nav navbar-nav">
                            <li className="dropdown user user-menu">
                                <a href="#" className="dropdown-toggle" data-toggle="dropdown"> <img src={userIcon} className="user-image" alt="User Image" />
                                    <span className="hidden-xs" />
                                </a>
                                <ul className="dropdown-menu">
                                    <li className="user-header"><img src={userIcon} className="img-circle" alt="User Image" />
                                        <p>Relcon</p></li>
                                    <li className="user-footer">
                                        <div className="pull-right">
                                            <a className="btn btn-info">SIGN OUT</a>
                                        </div>
                                    </li>
                                </ul>
                            </li>
                            <li><a href="#" data-toggle="control-sidebar"><img src={VendorLogo} style={{ width: '200px', height: '50px', marginTop: '-10px' }} /></a></li>
                        </ul>
                    </div>
                </nav>
            </header>
        );
    }
}

to stop appending I used the following code but this does not work when menu changes

componentDidMount() {
    var loadScript = function (src, file_id) {
        var scriptexist = document.getElementById(file_id);
        if (!scriptexist) {
            var tag = document.createElement('script');
            tag.type = "text/javascript";
            tag.async = false;
            tag.src = src;
            tag.id = file_id;
            var body = document.getElementsByTagName('body')[0];
            body.appendChild(tag);
        }
    }
    loadScript("/JS/jQuery-2.1.4.min.js", 'jqjs');
    loadScript("/BOOTSTRAP-JS/bootstrap.min.js", 'bootsjs');
    loadScript("/JS/app.min.js", 'appjs');
}

this is how it gets append to body every time page changes

<script type="text/javascript" src="/JS/jQuery-2.1.4.min.js"></script>
<script type="text/javascript" src="/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script type="text/javascript" src="/JS/app.min.js"></script>
<script type="text/javascript" src="/JS/jQuery-2.1.4.min.js"></script>
<script type="text/javascript" src="/BOOTSTRAP-JS/bootstrap.min.js"></script>
<script type="text/javascript" src="/JS/app.min.js"></script>
These are my other sub-page and ComponentWillMountFunction is in Header page.

class dashboard extends Component {
    render() {
        return (
            <div>
                <Header />
                <Sidebar />
                <div className="content-wrapper">
                    <section className="content-header" />
                    <section className="content">
                        {/* Page Content Here */}
                    </section>
                </div>
                <Footer />
            </div>
        );
    }
}
export { dashboard }

class transactions extends React.Component {
    render() {
        return (
            <div>
                <Header />
                <Sidebar />
                <div className="content-wrapper">
                    <section className="content-header" />
                    <section className="content">
                      This are transactions
                    </section>
                </div>
                <Footer />
            </div>
        );
    }
}
export { transactions }

this is my App file

import React from 'react';
import { history } from '../helpers';
import { login } from '../login';
import { dashboard } from '../dashboard';
import { transactions, inventorys } from '../reports';
import { Router, Route, Switch, Redirect } from 'react-router-dom';
class App extends React.Component {
  render() {
    return (
      <Router history={history}>
        <Switch>
          <Route exact path="/" component={login} />
          <Route path="/dashboard" component={dashboard} />
          <Route path="/transaction" component={transactions} />
          <Route path="/inventory" component={inventorys} />
          <Redirect from="*" to="/" />
        </Switch>
      </Router>
    );
  }
}

export { App };
Rahul Baraiya
  • 73
  • 1
  • 10
  • Tell me, what exactly is the question? Compare what the `PUBLIC_URL` is and your relative path, and you will see that your relative path points to the wrong place. – bhoodream Feb 25 '20 at 06:14

1 Answers1

0

The scripts are going to run in the browser. So you have to use absolute paths. And the paths must be served in your server.

Normally, for express, there is a middleware for you to choose which locations static files should be served. https://expressjs.com/en/starter/static-files.html

Check your code, maybe there is

app.use(express.static('public'))

Now for your case, if you want to serve scripts file from src/component/ui. You may modify the code like this:

app.use(express.static('src/component/ui'))

And now your scripts will be like this:

<script src="/JS/jQuery-2.1.4.min.js" type="text/babel"></script>
<script src="/BOOTSTRAP-JS/bootstrap.min.js" type="text/babel"></script>
<script src="/JS/app.min.js" type="text/babel"></script>
Tan Dat
  • 2,888
  • 1
  • 17
  • 39
  • Any other alternative without using express in react? – Rahul Baraiya Feb 25 '20 at 06:24
  • Are you using Create React App or what? – Tan Dat Feb 25 '20 at 06:26
  • I am new to react and yes i am using create react app – Rahul Baraiya Feb 25 '20 at 06:31
  • So in the docs of CreateReactApp, says `Only files inside public can be used from public/index.html.` – Tan Dat Feb 25 '20 at 06:36
  • But I found some useful information to change public url by setting PUBLIC_URL in your .env file https://create-react-app.dev/docs/advanced-configuration/#! – Tan Dat Feb 25 '20 at 06:38
  • can you help me out I have edited my answer@Tan Dat – Rahul Baraiya Feb 26 '20 at 12:19
  • @RahulBaraiya, before `loadScript`, you can check if the script exists in your page. Something like this: https://stackoverflow.com/questions/5629684/how-can-i-check-if-an-element-exists-in-the-visible-dom. Easiest way is to add the id in your `script` tags, and then check by Id. – Tan Dat Feb 26 '20 at 12:41
  • The scripts exist in the page. But whenever the route changes it again get added. So if I have three routes and If I navigate to all three pages, my page will contain nine script tag. The code is working fine but I want to add only once and not every time at new route.My Heade Page is included in all other sub pages @Tan Dat – Rahul Baraiya Feb 27 '20 at 05:38
  • Why don't you just put them in the public folder? :D and then add the script in index.html – Tan Dat Feb 27 '20 at 06:10
  • I did that and it works fine for first page but when route changes it does not work. I have edited my code again.See its working fine, but now, I only want to find out if script is already present than no need to add it again and this is were I am stuck now.It is obvious that If I am adding my extrenal js file in Header page than this file will get append wherever the Header component is used. – Rahul Baraiya Feb 27 '20 at 06:24
  • Hi @Tan Dat I have edited my code can you help me out with this.Thanks – Rahul Baraiya Feb 27 '20 at 07:44
  • maybe you can try to put `loadScript` part into `componentDidMount` of `App` component – Tan Dat Feb 27 '20 at 08:25