在 Gatsby React 页面中添加带有 <script> 的原始 HTML

IT技术 javascript reactjs gatsby
2021-04-09 07:00:55

我正在尝试向我的 Gatsby 页面添加外部嵌入代码。

我目前使用

import React from 'react'
import Link from 'gatsby-link'


let test ="<script type='text/javascript'>
(function(d, s) {
    var useSSL = 'https:' == document.location.protocol;
    var js, where = d.getElementsByTagName(s)[0],
    js = d.createElement(s);
    js.src = (useSSL ? 'https:' : 'http:') +  '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd='+parseInt(Math.random()*10000, 10);
    try { where.parentNode.insertBefore(js, where); } catch (e) { if (typeof console !== 'undefined' && console.log && e.stack) { console.log(e.stack); } }
}(document, 'script'));
</script>"

const ContactPage = () => (

    <div>
        <h1>ContactPage</h1>
        <div
            dangerouslySetInnerHTML={{ __html: test }}
          />
    </div>

)

export default ContactPage

里面充满了语法错误。您能否指出一种在 React 组件中包含原始代码段的更好方法?

Gatsby 中是否有其他地方可以添加所有其他脚本,例如自定义脚本、Google Analytics、图标字体、animate.js 以及我可能需要的任何其他脚本?

感谢您的帮助

5个回答

您可以通过多种方式将外部脚本(没有 npm module)注入 gatsby.js 项目。更喜欢将各自的 gatsby-plugin 用于“web-analytics”脚本。

使用require()

  • 在你的项目中创建一个文件myScript.js并粘贴脚本内容
  • 如果您只想在该页面(=页面/组件范围)执行该脚本,请添加const myExtScript = require('../pathToMyScript/myScript')
    到其内部和之前Pages文件夹中有状态组件render()return()

    export default class Contact extends React.Component {  
      render() {  
       const myExtScript = require('../pathToMyScript/myScript')  
        return (
          ........       
                   )}
    
  • 如果要在全局范围内(=在每个页面/组件中)执行脚本
    将其添加到html.js

    <script dangerouslySetInnerHTML= {{ __html: ` 
        putYourSciptHereInBackticks `}} />`  
    

    在关闭</body>. 最好在这个组件上操作/监控你的全局范围,因为它有这个特定的目的......全局地将 html 注入每个页面/路由。

  • 全局范围内注入的另一种方法require()在组件声明之前使用。这会起作用,但这不是一个好习惯,因为您的组件不应全局注入任何内容。

     const myExtScript = require('../pathToMyScript/myScript')  
    
       export default class Contact extends React.Component {  
        render() {  
          return (
          ........       
                   )}
    

PS对不起,如果答案没有正确编辑。这是我在 StackOverflow 上的第一个回答。

你会展示一些关于这些例子的 GitHub 存储库吗?
2021-06-17 07:00:55
使用在线脚本而不是本地文件的脚本是什么?例如: <script src=" blah-blah/js/blah.js " />
2021-06-19 07:00:55

使用React-Helmet

第一的 import Helmet from 'react-helmet'

在你里面div你可以这样做

<Helmet>
<script type='text/javascript'>
(function(d, s) {
    var useSSL = 'https:' == document.location.protocol;
    var js, where = d.getElementsByTagName(s)[0],
    js = d.createElement(s);
    js.src = (useSSL ? 'https:' : 'http:') +  '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd='+parseInt(Math.random()*10000, 10);
    try { where.parentNode.insertBefore(js, where); } catch (e) { if (typeof console !== 'undefined' && console.log && e.stack) { console.log(e.stack); } }
}(document, 'script'));
</script>
</Helmet>

我们是否必须在整个项目的所有文件中使用它?整个项目中包含的单个是否有任何聪明的工作?
2021-06-01 07:00:55
这并不是问题的真正解决方案,但我发现的一种解决方法是使用 Google 标签管理器注入自定义脚本。这并不适用于所有场景,但如果您要注入跟踪脚本之类的东西,它会工作得很好,并且有助于避免使用非托管脚本乱扔代码。我只是用它在 Gatsby 页面上注入 MailChimp 弹出代码,效果很好。
2021-06-07 07:00:55
@Logemann 我最近没有尝试过,但是您可以使用 GTM 将任何脚本注入页面。当我陷入困境时,我什至用它来替换内容。support.google.com/tagmanager/answer/6107167?hl=en
2021-06-07 07:00:55
谢谢,但这会产生与我的初始代码相同的语法错误。无法转译
2021-06-13 07:00:55
@AaronNewton GTM 不适用于 mailchimp 脚本,对吗?据我所知没有。
2021-06-17 07:00:55

显然使用多行 JS 语法可以解决问题,如

let test = "<script type='text/javascript'>\
(function(d, s) {\
    var useSSL = 'https:' == document.location.protocol;\
    var js, where = d.getElementsByTagName(s)[0],\
    js = d.createElement(s);\
    js.src = (useSSL ? 'https:' : 'http:') +  '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd='+parseInt(Math.random()*10000, 10);\
    try { where.parentNode.insertBefore(js, where); } catch (e) { if (typeof console !== 'undefined' && console.log && e.stack) { console.log(e.stack); } }\
}(document, 'script'));\
</script><div id='pph-hireme'></div>"

或者,你可以做

let test2 = `
<script type='text/javascript'>
(function(d, s) {
    var useSSL = 'https:' == document.location.protocol;
    var js, where = d.getElementsByTagName(s)[0],
    js = d.createElement(s);
    js.src = (useSSL ? 'https:' : 'http:') +  '//www.peopleperhour.com/hire/1002307300/1213788.js?width=300&height=135&orientation=vertical&theme=light&rnd='+parseInt(Math.random()*10000, 10);\
    try { where.parentNode.insertBefore(js, where); } catch (e) { if (typeof console !== 'undefined' && console.log && e.stack) { console.log(e.stack); } }\
}(document, 'script'));
</script><div id='pph-hireme'></div>
`

欢迎提出更多意见

一种方法——也许是首选方法——是使用 SSR 文件。

文档

文件 gatsby-ssr.js 允许您更改静态 HTML 文件的内容,因为它们由 Gatsby 和 Node.js 进行服务器端呈现 (SSR)。要使用 Gatsby SSR API,请在站点的根目录中创建一个名为 gatsby-ssr.js 的文件。导出您希望在此文件中使用的任何 API。

关于如何做到这一点的教程在这里

它使用setHeadComponents注入到 html.js方法:

setHeadComponents

它接受一个组件数组作为它的第一个参数,这些参数将在构建时添加到头部组件中,并将传递给 html.js。

还有另一种方法,即创建 React 的效果:

import { useEffect } from 'react'

const useGoogleAnalytics = () => {

    useEffect(() => {
        // GA Snippet
    }, [])

    return null
}

然后您可以useGoogleAnalytics()在要包含的页面组件中使用

这样做的主要优点是:

  • 你得到代码的翻译
  • 维护更复杂的代码比在模板文字中更容易维护。

对于像 Google Analytics 这样的简单脚本,我会选择模板文字,但对于自定义和可更改的片段,我更喜欢效果。只要您不滥用它们,它就不会影响性能或产生开销。

有没有人看到这种其他方法的其他缺点?