How to include local javascript on a Gatsby page?

后端 未结 7 551
深忆病人
深忆病人 2020-11-30 07:48

I\'m a total React newbie and I guess there is something fundamental I don\'t quite understand here. A default Gatsby page looks like this. Is there a way to use a local .js

相关标签:
7条回答
  • 2020-11-30 08:23

    There are many ways to add scripts in GatsbyJS...

    To execute a script on a specific page

    • create your script.js file and place it anywhere inside your /src folder.

    • go to the page you want to excute the script in (e.g. /pages/myPage.js ), and use require() to execute it inside useEffect() like this:

       useEffect(() => {
         // This runs the script
         const myScript = require('../script.js')
       }, [])
      
       return <div />
      
    • To run it on client-side, you could check the window object inside your script.js file:

       if(typeof window !== 'undefined' && window.document) {
          // Your script here...
       }
      

    If you want to execute a script globally in (every component/page) you could use html.js file.

    • first, you'll have to extract the file (in case you didn't) by running:

    cp .cache/default-html.js src/html.js

    • inside your html.js file:
    <script dangerouslySetInnerHTML= {{ __html:`
      // your script here...
    `}} />
    
    0 讨论(0)
  • 2020-11-30 08:28

    After several hours of frustration I finally stumbled upon discussion on GitHub that solved this for me. In Gatsby, there is a thing called static folder, for which one use case is including a small script outside of the bundled code.

    Anyone else in the same situation, try proceeding as follows:

    1. Create a folder static to the root of your project.

    2. Put your script script.js in the folder static.

    3. Include the script in your react dom with react-helmet.

    So in the case of the code I posted in my original question, for instance:

    import React from "react"
    import Helmet from "react-helmet"
    import { withPrefix, Link } from "gatsby"
    
    import Layout from "../components/layout"
    import Image from "../components/image"
    import SEO from "../components/seo"
    
    const IndexPage = () => (
      <Layout>
        <Helmet>
            <script src={withPrefix('script.js')} type="text/javascript" />
        </Helmet>
        <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
        <h1>Hi people</h1>
        <p>Welcome to your new Gatsby site.</p>
        <p>Now go build something great.</p>
        <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
          <Image />
        </div>
        <Link to="/page-2/">Go to page 2</Link>
      </Layout>
    )
    

    Notice the imports

    import Helmet from "react-helmet"
    import { withPrefix, Link } from "gatsby"
    

    and the script element.

    <Helmet>
        <script src={withPrefix('script.js')} type="text/javascript" />
    </Helmet>
    

    This would have saved hours of my time, hopefully this does it for someone else.

    0 讨论(0)
  • 2020-11-30 08:29

    React works with dynamic DOM. But for rendering it by browser, your web server should send a static index page, where React will be included as another script tag.

    So, take a look on your index.html page, which you can find in public folder. There you could insert your script tag in the header section, for example.

    0 讨论(0)
  • 2020-11-30 08:33

    You can do this very easily with the Gatsby plugin "gatsby-plugin-load-script."

    Simply do this:

    1. Create a folder named static at the root of your gatsby app
    2. Place your script in it
    3. Add the following configuration in gatsby-config.js
        {
          resolve: 'gatsby-plugin-load-script',
          options: {
            src: '/test-script.js', // Change to the script filename
          },
        },
    
    0 讨论(0)
  • 2020-11-30 08:37

    Just create gatsby-ssr.js file on root folder

    and add the following pattern for your scripts folder

    import React from 'react'
    
    export const onRenderBody = ({ setPostBodyComponents }) => {
      setPostBodyComponents([
        <script
          key="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
          integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
          crossOrigin="anonymous"
          defer
        />,
        <script
          key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
          src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
          integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
          crossOrigin="anonymous"
          defer
        />,
        <script
          key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
          src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
          integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
          crossOrigin="anonymous"
          defer
        />
      ])
    }
    

    Then, you at the end of dom you'll see the links to scripts

    0 讨论(0)
  • 2020-11-30 08:38

    Gatsby uses html.js in the src folder. Not index.html like most react projects.

    Example html.js file:

    import React from "react"
    import PropTypes from "prop-types"
    
    export default class HTML extends React.Component {
      render() {
        return (
          <html {...this.props.htmlAttributes}>
            <head>
              <meta charSet="utf-8" />
              <meta httpEquiv="x-ua-compatible" content="ie=edge" />
              <meta
                name="viewport"
                content="width=device-width, initial-scale=1, shrink-to-fit=no"
              />
              {this.props.headComponents}
            </head>
            <body {...this.props.bodyAttributes}>
              {this.props.preBodyComponents}
              <div
                key={`body`}
                id="___gatsby"
                dangerouslySetInnerHTML={{ __html: this.props.body }}
              />
              {this.props.postBodyComponents}
            </body>
          </html>
        )
      }
    }
    
    HTML.propTypes = {
      htmlAttributes: PropTypes.object,
      headComponents: PropTypes.array,
      bodyAttributes: PropTypes.object,
      preBodyComponents: PropTypes.array,
      body: PropTypes.string,
      postBodyComponents: PropTypes.array,
    }
    

    For adding custom Javascript using dangerouslySetInnerHTML inside src/html.js:

    <script
      dangerouslySetInnerHTML={{
        __html: `
                var name = 'world';
                console.log('Hello ' + name);
            `,
      }}
    />
    

    You can try adding your js there but, note that your js may not work as expected. You can always look into react-helmet for more dynamic apps and adding scripts to <head>.

    Gatsby Documentation: https://www.gatsbyjs.org/docs/custom-html/

    0 讨论(0)
提交回复
热议问题