En un proyecto Gatsby.js, ¿hay alguna forma de inyectar html sin procesar dentro de la etiqueta <head></head> de cada página? Recibo una cadena de html para el seguimiento (etiquetas de secuencias de comandos en línea y externas, etiquetas de enlace y metaetiquetas) que solo necesito volcar en la etiqueta principal.
Editar: aquí hay un ejemplo de cómo se ve el html que recibiré (debido a las restricciones del entorno en el que estoy trabajando, no puedo editar la cadena 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" /> .. Intenté usar react-helmet (requiere a: propiedades pasadas al meta o b: las etiquetas script/meta/link para ser JSX como niños)
Intenté usar la API onPreRenderHTML dentro de gatsby-ssr.js. (problema similar donde espera jsx en lugar de una cadena)
// 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]); };Los complementos como gatsby-plugin-google-tagmanager no son una opción, ya que el html de seguimiento aparece como una cadena grande
¡Cualquier idea sería muy apreciada!
Resolví esto creando un archivo html.js personalizado (documentación de Gatsby aquí ) y usando html-react-parser .
Primero copié .cache/default-html.js a src/html.js para modificar el documento html raíz que usa Gatsby. Luego usé el paquete html-react-parser para colocar el html de seguimiento que me dieron en la cabeza.
Mis modificaciones al archivo html.js se indican mediante los comentarios ADDED a continuación
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, };(Nota: "Cualquier cosa que renderice en el componente html.js no se hará "en vivo" en el cliente como otros componentes" -Documentación de Gatsby)