Je suis un novice total de React et je suppose qu'il y a quelque chose de fondamental que je ne comprends pas très bien ici. Une page Gatsby par défaut ressemble à ceci. Existe-t-il un moyen d'utiliser un fichier .js local un peu comme ça?
import React from "react" import { Link } from "gatsby" import Layout from "../components/layout" import Image from "../components/image" import SEO from "../components/seo" const IndexPage = () => ( <Layout> <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} /> <h1>Hi people</h1> <p>Welcome to your new Gatsby site.</p> <p>Now go build something great.</p> <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}> <Image /> </div> <Link to="/page-2/">Go to page 2</Link> </Layout> )
Ce que je souhaiterais, c'est que script.js
ignore script.js
mais que le côté client l'utilise. Une page Gatsby par défaut ressemble à ceci, est-il possible de faire quelque chose comme ça là-bas?
<script src="../script/script.js"></script>
7 Réponses :
React fonctionne avec le DOM dynamique. Mais pour le rendre par navigateur, votre serveur Web doit envoyer une page d'index statique, où React sera inclus comme une autre balise de script
.
Alors, jetez un œil sur votre page index.html
, que vous pouvez trouver dans public
dossier public
. Là, vous pouvez insérer votre balise de script
dans la section d'en-tête, par exemple.
Gatsby utilise html.js dans le dossier src. Pas index.html comme la plupart des projets de réaction.
Exemple de fichier html.js:
<script dangerouslySetInnerHTML={{ __html: ` var name = 'world'; console.log('Hello ' + name); `, }} />
Pour ajouter du Javascript personnalisé en utilisant dangerouslySetInnerHTML
dans src/html.js
:
import React from "react" import PropTypes from "prop-types" export default class HTML extends React.Component { render() { return ( <html {...this.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" /> {this.props.headComponents} </head> <body {...this.props.bodyAttributes}> {this.props.preBodyComponents} <div key={`body`} id="___gatsby" dangerouslySetInnerHTML={{ __html: this.props.body }} /> {this.props.postBodyComponents} </body> </html> ) } } HTML.propTypes = { htmlAttributes: PropTypes.object, headComponents: PropTypes.array, bodyAttributes: PropTypes.object, preBodyComponents: PropTypes.array, body: PropTypes.string, postBodyComponents: PropTypes.array, }
Vous pouvez essayer d'y ajouter vos js, mais notez que vos js peuvent ne pas fonctionner comme prévu. Vous pouvez toujours regarder dans react-casque pour des applications plus dynamiques et ajouter des scripts à <head>
.
Documentation Gatsby: https://www.gatsbyjs.org/docs/custom-html/
Après plusieurs heures de frustration, je suis finalement tombé sur une discussion sur GitHub qui a résolu ce problème pour moi. Dans Gatsby, il existe une chose appelée dossier statique , pour laquelle un cas d'utilisation inclut un petit script en dehors du code fourni.
Toute autre personne dans la même situation, essayez de procéder comme suit:
Créez un dossier static
à la racine de votre projet.
Mettez votre script script.js
dans le dossier static
.
Incluez le script dans votre react dom avec react-casque .
Donc, dans le cas du code que j'ai publié dans ma question initiale, par exemple:
<Helmet> <script src={withPrefix('script.js')} type="text/javascript" /> </Helmet>
Notez les importations
import Helmet from "react-helmet" import { withPrefix, Link } from "gatsby"
et l'élément de script.
import React from "react" import Helmet from "react-helmet" import { withPrefix, Link } from "gatsby" import Layout from "../components/layout" import Image from "../components/image" import SEO from "../components/seo" const IndexPage = () => ( <Layout> <Helmet> <script src={withPrefix('script.js')} type="text/javascript" /> </Helmet> <SEO title="Home" keywords={[`gatsby`, `application`, `react`]} /> <h1>Hi people</h1> <p>Welcome to your new Gatsby site.</p> <p>Now go build something great.</p> <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}> <Image /> </div> <Link to="/page-2/">Go to page 2</Link> </Layout> )
Cela aurait économisé des heures de mon temps, j'espère que cela le fera pour quelqu'un d'autre.
Cela fonctionnait pour le mode de développement de gatsby mais n'incluait pas correctement le fichier sur la construction de gatsby. Une suggestion s'il vous plaît?
pareil ici avec moi
Merci beaucoup pour cela. Quelqu'un sait-il s'il est possible d'inclure des scripts en dehors de la balise <head>? Je préfère souvent avoir un script à la fin du corps plutôt qu'en haut pour une vitesse de chargement améliorée (ou cela n'affecte pratiquement rien?)
@Mayron Une solution si vous voulez qu'un script se charge toujours lors de la navigation est de le charger pendant le componentDidMount, par exemple voir ceci: github.com/gatsbyjs/gatsby/issues/13136 . Vous pouvez également les charger au pied du corps en utilisant gatsby-ssr mais lisez ceci aussi: gatsbyjs.org/docs/using-client-side-only-packages
@Mayron Voir également cette réponse: stackoverflow.com/questions/60066579/...
Cela a bien fonctionné. Je voulais inclure un logo d'Altmetric. J'ai essayé d'inclure le script externe dans html.js et d'utiliser gatsby-plugin-load-script mais aucun n'a fonctionné. Cela a fonctionné comme un charme. Merci!
Il existe de nombreuses façons d'ajouter des scripts dans GatsbyJS ...
Pour exécuter un script sur une page spécifique
créez votre fichier script.js
et placez-le n'importe où dans votre dossier /src
.
allez à la page dans laquelle vous voulez exécuter le script (par exemple /pages/myPage.js
), et utilisez require()
pour l'exécuter dans useEffect()
comme ceci:
<script dangerouslySetInnerHTML= {{ __html:` // your script here... `}} />
Pour l'exécuter côté client, vous pouvez vérifier l'objet window
dans votre fichier script.js
:
if(typeof window !== 'undefined' && window.document) { // Your script here... }
Si vous souhaitez exécuter un script globalement dans (chaque composant / page), vous pouvez utiliser le fichier html.js
cp .cache/default-html.js src/html.js
html.js
:useEffect(() => { // This runs the script const myScript = require('../script.js') }, []) return <div />
Cela fonctionnerait-il bien avec un js externe? C'EST À DIRE. Le public jqueryurl?
On dirait que c'est la manière React de le faire.
Si vous souhaitez utiliser un plugin Gatsby, ce qui pour moi n'est pas différent de l'utilisation d'une bibliothèque externe comme Helmet (les plugins sont des packages npm après tout), vous pouvez utiliser gatsby-plugin-load-script .
Vous pouvez fournir l'url de l'attribut src
ou un chemin local. Si vous allez stocker votre JS dans un fichier local tel que some-minified-js.min.js
, assurez-vous de stocker dans le répertoire static
à la racine de votre projet.
Une fois que vous faites cela, vous pouvez accéder via l'objet global:
useEffect(() => { const x = new global.MyImportedLibraryObject(); }, []}
Par exemple, j'essayais d'inclure une très petite bibliothèque JS via un fichier minifié, j'ai donc stocké le fichier dans /static/my-minified-library.min.js
puis:
npm i --save gatsby-plugin-load-script
gatsby-config.js
plugins: [ { resolve: "gatsby-plugin-load-script", options: { src: "/my-minified-library.min.js", }, }, ],
global.<object or func name here>
Vous pouvez le faire très facilement avec le plugin Gatsby "gatsby-plugin-load-script".
Faites simplement ceci:
static
à la racine de votre application Gatsbygatsby-config.js
{ resolve: 'gatsby-plugin-load-script', options: { src: '/test-script.js', // Change to the script filename }, },
gatsby-ssr.js
fichier gatsby-ssr.js
sur le dossier racine
et ajoutez le modèle suivant pour votre dossier de scripts
import React from 'react' export const onRenderBody = ({ setPostBodyComponents }) => { setPostBodyComponents([ <script key="https://code.jquery.com/jquery-3.2.1.slim.min.js" src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossOrigin="anonymous" defer />, <script key="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossOrigin="anonymous" defer />, <script key="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossOrigin="anonymous" defer /> ]) }
Ensuite, vous à la fin de dom vous verrez les liens vers les scripts