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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/48966464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 08:21:51  来源:igfitidea点击:

add raw HTML with <script> inside Gatsby React page

javascriptreactjsgatsby

提问by Giannis Dallas

I am trying to add an external embed code to my Gatsby page.

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

I currently use

我目前使用

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

which is full of syntax errors. Can you please point out a better way to include raw snippets in a react component?

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

Is there alternatively a place in Gatsby to add all additional scripts like custom scripts, Google Analytics, icon fonts, animate.js and anything else I may need?

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

Thank you for the help

感谢您的帮助

回答by AndreasT

You can inject external scripts (with no npm modules) to gatsby.js project in many ways. Prefer to use respective gatsby-plugin for "web-analytics" scripts.

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

Using require():

使用require()

  • Create a file in your project myScript.jsand paste the script content
  • Add const myExtScript = require('../pathToMyScript/myScript')
    to a statefullcomponent at the Pagesfolder inside render()and before return()if you want to execute that script only at that page(=page/component scope).

    export default class Contact extends React.Component {  
      render() {  
       const myExtScript = require('../pathToMyScript/myScript')  
        return (
          ........       
                   )}
    
  • If you want to execute script in the global scope(=in every page/ component):
    add it in html.js

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

    before closing the </body>. It is better to manipulate/monitor your global scope at this component because it has this specific purpose... to inject html to every page/route globally.

  • Another way to inject at the global scopeis with require()before the component declaration. This will work but it's not a good practice, as your components shouldn't inject anything globally.

     const myExtScript = require('../pathToMyScript/myScript')  
    
       export default class Contact extends React.Component {  
        render() {  
          return (
          ........       
                   )}
    
  • 在你的项目中创建一个文件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 (
          ........       
                   )}
    

P.S. Sorry if the answer is not edited properly. This my first answer at StackOverflow.

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

回答by Mohit Bajoria

Use React-Helmet

使用React-Helmet

First import Helmet from 'react-helmet'

第一的 import Helmet from 'react-helmet'

Inside your divyou can do like this

在你里面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>

回答by Giannis Dallas

Apparently using a multiline JS syntax did the trick, as in

显然使用多行 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>"

alternatively, you can do

或者,你可以做

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>
`

Any more comments are welcome

欢迎提出更多意见

回答by rmcsharry

One way - perhaps the preferred way - is using the SSR file.

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

From the docs:

文档

The file gatsby-ssr.js lets you alter the content of static HTML files as they are being Server-Side Rendered (SSR) by Gatsby and Node.js. To use the Gatsby SSR APIs, create a file called gatsby-ssr.js in the root of your site. Export any of the APIs you wish to use in this file.

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

A tutorial on how to do that is here: https://uxworks.online/how-to-add-a-script-in-head-or-body-tag-in-your-gatsby-website/

关于如何做到这一点的教程在这里:https: //uxworks.online/how-to-add-a-script-in-head-or-body-tag-in-your-gatsby-website/

It uses the setHeadComponentsmethod to inject into html.js:

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

setHeadComponents

It takes an array of components as its first argument which will be added to head components during building time and which will be passed to html.js.

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

回答by jonalvarezz

There is another way, which is creating a React's effects:

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

import { useEffect } from 'react'

const useGoogleAnalytics = () => {

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

    return null
}

And then you can use useGoogleAnalytics()in the page components you want to include.

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

The main advantage of this are:

这样做的主要优点是:

  • You get transpilation of the code
  • It's way easier to maintain for more complex code than inside a template literal.
  • 你得到代码的翻译
  • 维护更复杂的代码比在模板文字中更容易维护。

For simple scripts like Google Analytics I'd go for a template literal, but for custom and subject-to-change snippet I'd prefer an effect. As long as you don't abuseof those, It should not impact performance nor create overhead.

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

Does anyone see other disadvantages with this other method?

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