盖茨比:如何在 head 标签内注入原始 html
Gatsby: How to inject raw html inside head tag
在一个Gatsby.js项目中,有没有办法在每个页面的<head></head>
标签中注入原始html?我收到一串 html 用于跟踪(内联和外部脚本标签、link 标签和元标签),我只需要将其转储到 head 标签中。
编辑:这是我将收到的 html 的示例(由于我工作环境的限制,我无法编辑 html 字符串):
<script src="//sometracking.com/script.js" async></script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','TAGID');</script>
<!-- End Google Tag Manager -->
<link rel="stylesheet" type="text/css" href="https://somefont.com/stylesheet.css" />
<link href="~/another/stylesheet.css" type="text/css" rel="stylesheet" />
<link href="~/more/styles.css" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" src="~/vendor/javascript.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="format-detection" content="telephone=no">
<meta name="apple-itunes-app" content="app-id=123456789">
<meta name="google-play-app" content="app-id=com.blah.blah">
<link rel="apple-touch-icon" sizes="180x180" href="~/icon.png" />
..
我试过使用 react-helmet(需要 a: 属性传递给 meta
prop 或 b: script/meta/link 标签作为子 JSX)
我试过在 gatsby-ssr.js 中使用 onPreRenderHTML API。 (类似的问题,它需要 jsx 而不是字符串)
// THIS RENDERS THE HTML AS TEXT IN THE BODY TAG
const headScripts = `<script type="text/javascript">alert("tracking stuff");</script>`;
exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => {
replaceHeadComponents([...getHeadComponents(), headScripts]);
};
像 gatsby-plugin-google-tagmanager 这样的插件不是一个选项,因为跟踪 html 作为一个大字符串出现
任何见解将不胜感激!
我通过创建自定义 html.js 文件解决了这个问题(Gatsby 文档 here) and using html-react-parser。
首先我将 .cache/default-html.js
复制到 src/html.js
以修改 Gatsby 使用的根 html 文档。然后我用html-react-parser
包把给我的trackinghtml放到head里
我对 html.js
文件的修改由下面的 ADDED
评论指出
import React from "react";
import PropTypes from "prop-types";
import parse from "html-react-parser"; // ADDED
import getTrackingHtml = from './myCustomUtils'; // ADDED
export default function HTML(props) {
const trackingHtml = getTrackingHtml(); // ADDED
return (
<html {...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"
/>
{props.headComponents}
{parse(trackingHtml)} {/* ADDED */}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={"body"}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
);
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
};
(注意:“您在 html.js 组件中呈现的任何内容都不会像其他组件一样在客户端中“生效””-Gatsby 文档)
在一个Gatsby.js项目中,有没有办法在每个页面的<head></head>
标签中注入原始html?我收到一串 html 用于跟踪(内联和外部脚本标签、link 标签和元标签),我只需要将其转储到 head 标签中。
编辑:这是我将收到的 html 的示例(由于我工作环境的限制,我无法编辑 html 字符串):
<script src="//sometracking.com/script.js" async></script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','TAGID');</script>
<!-- End Google Tag Manager -->
<link rel="stylesheet" type="text/css" href="https://somefont.com/stylesheet.css" />
<link href="~/another/stylesheet.css" type="text/css" rel="stylesheet" />
<link href="~/more/styles.css" type="text/css" rel="stylesheet" />
<script language="javascript" type="text/javascript" src="~/vendor/javascript.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="format-detection" content="telephone=no">
<meta name="apple-itunes-app" content="app-id=123456789">
<meta name="google-play-app" content="app-id=com.blah.blah">
<link rel="apple-touch-icon" sizes="180x180" href="~/icon.png" />
..
我试过使用 react-helmet(需要 a: 属性传递给
meta
prop 或 b: script/meta/link 标签作为子 JSX)我试过在 gatsby-ssr.js 中使用 onPreRenderHTML API。 (类似的问题,它需要 jsx 而不是字符串)
// THIS RENDERS THE HTML AS TEXT IN THE BODY TAG const headScripts = `<script type="text/javascript">alert("tracking stuff");</script>`; exports.onPreRenderHTML = ({ getHeadComponents, replaceHeadComponents }) => { replaceHeadComponents([...getHeadComponents(), headScripts]); };
像 gatsby-plugin-google-tagmanager 这样的插件不是一个选项,因为跟踪 html 作为一个大字符串出现
任何见解将不胜感激!
我通过创建自定义 html.js 文件解决了这个问题(Gatsby 文档 here) and using html-react-parser。
首先我将 .cache/default-html.js
复制到 src/html.js
以修改 Gatsby 使用的根 html 文档。然后我用html-react-parser
包把给我的trackinghtml放到head里
我对 html.js
文件的修改由下面的 ADDED
评论指出
import React from "react";
import PropTypes from "prop-types";
import parse from "html-react-parser"; // ADDED
import getTrackingHtml = from './myCustomUtils'; // ADDED
export default function HTML(props) {
const trackingHtml = getTrackingHtml(); // ADDED
return (
<html {...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"
/>
{props.headComponents}
{parse(trackingHtml)} {/* ADDED */}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={"body"}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
);
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
};
(注意:“您在 html.js 组件中呈现的任何内容都不会像其他组件一样在客户端中“生效””-Gatsby 文档)