I am trying to add an external embed code to my Gatsby page.
I currently use
import React from \'react\'
import Link from \'gatsby-link\'
let test
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.
Using require()
:
myScript.js
and paste the script contentAdd const myExtScript = require('../pathToMyScript/myScript')
to a statefull component at the Pages folder 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 scope is 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 (
........
)}
P.S. Sorry if the answer is not edited properly. This my first answer at StackOverflow.
Apparently using a multiline JS syntax did the trick, as in
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
There is another way, which is creating a React's effects:
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.
The main advantage of this are:
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 abuse of those, It should not impact performance nor create overhead.
Does anyone see other disadvantages with this other method?
One way - perhaps the preferred way - is using the SSR file.
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.
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/
It uses the setHeadComponents
method to inject into 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.
Use React-Helmet
First import Helmet from 'react-helmet'
Inside your div
you can do like this
<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>