You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gatsby博客文章中使用script标签加载外部脚本

嘿,这个问题我太熟悉了——Gatsby默认的Markdown处理逻辑确实会过滤掉外部<script>标签,毕竟出于安全和渲染性能考虑嘛。不过你不想大改文章的话,有几个很实用的解决方案,刚好能适配你不同文章依赖不同版本库的需求:

方案1:自定义Remark插件(零改动文章,最推荐)

Gatsby用gatsby-transformer-remark处理Markdown,我们可以写个轻量的自定义插件,把文章里的外部脚本标签提取出来,再在页面渲染时动态加载,完全不用碰原Markdown文件。

步骤1:编写自定义Remark插件

在项目里新建src/plugins/remark-preserve-scripts/index.js,代码如下:

const visit = require('unist-util-visit');

module.exports = function attacher() {
  return function transformer(tree, file) {
    const scripts = [];

    // 遍历Markdown的AST树,找到所有带src的script标签
    visit(tree, 'html', (node) => {
      const srcMatch = node.value.match(/<script src="([^"]+)"[^>]*>/);
      if (srcMatch) {
        scripts.push(srcMatch[1]);
        // 把原script标签替换成占位符(可选,也可以直接保留原标签)
        node.value = `<div class="script-loader" data-src="${srcMatch[1]}"></div>`;
      }
    });

    // 把提取到的脚本列表附加到文件元数据里
    file.data.scripts = scripts;
  };
};

步骤2:配置Gatsby使用这个插件

在gatsby-config.js里,把自定义插件加到gatsby-transformer-remark的插件列表中:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          `${__dirname}/src/plugins/remark-preserve-scripts`,
          // 你的其他remark插件(比如prismjs、remark-images等)
        ],
      },
    },
  ],
};

步骤3:在文章模板中动态加载脚本

打开你的博客文章模板(比如src/templates/blog-post.js),修改GraphQL查询和组件逻辑,获取脚本列表并动态加载:

import React, { useEffect } from 'react';

const BlogPost = ({ data }) => {
  const post = data.markdownRemark;
  // 从文件元数据中获取脚本列表
  const scriptsToLoad = post.parent.scripts || [];

  useEffect(() => {
    scriptsToLoad.forEach(src => {
      // 检查脚本是否已加载,避免重复加载同版本
      if (!document.querySelector(`script[src="${src}"]`)) {
        const script = document.createElement('script');
        script.src = src;
        script.async = true; // 按需设置async/defer
        document.body.appendChild(script);
      }
    });

    // 可选:页面卸载时清理脚本(避免内存泄漏)
    return () => {
      scriptsToLoad.forEach(src => {
        const script = document.querySelector(`script[src="${src}"]`);
        if (script) document.body.removeChild(script);
      });
    };
  }, [scriptsToLoad]);

  return (
    <article>
      <h1>{post.frontmatter.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.html }} />
    </article>
  );
};

export const query = graphql`
  query BlogPostQuery($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
      }
      parent {
        ... on File {
          scripts
        }
      }
    }
  }
`;

export default BlogPost;

这个方案完美适配你“不同文章依赖不同版本库”的需求,而且全程不用修改任何一篇Markdown文章。

方案2:改用MDX(灵活度更高,少量改动文章)

如果你能接受把Markdown文件改成MDX格式(后缀名从.md改成.mdx),可以用组件化的方式加载脚本,更符合React生态。

步骤1:配置MDX插件

先安装依赖:

npm install gatsby-plugin-mdx @mdx-js/react

然后在gatsby-config.js里添加插件:

module.exports = {
  plugins: [
    `gatsby-plugin-mdx`,
    // 其他插件...
  ],
};

步骤2:编写脚本加载组件

新建src/components/LoadScript.js:

import React, { useEffect } from 'react';

const LoadScript = ({ src }) => {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = src;
    script.async = true;
    document.body.appendChild(script);

    return () => {
      document.body.removeChild(script);
    };
  }, [src]);

  return null;
};

export default LoadScript;

步骤3:在MDX文章中引入组件

把原Markdown里的<script src="...">替换成组件引入:

import LoadScript from '../components/LoadScript';

<LoadScript src="https://code.jquery.com/jquery-3.6.0.min.js" />
<LoadScript src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js" />

<!-- 下面是你的文章内容 -->
这篇文章需要用到jQuery和Three.js演示...

这个方案虽然需要修改文章,但改动量极小,而且能更精细地控制脚本的加载和卸载。

方案3:全局加载通用脚本(仅适合固定版本的通用库)

如果你的部分文章依赖固定版本的通用库(比如某个版本的jQuery),可以用gatsby-plugin-load-script全局加载,但这个方案解决不了“不同文章不同版本”的问题,只能作为补充:

安装插件后在gatsby-config.js配置:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-load-script`,
      options: {
        src: `https://code.jquery.com/jquery-3.6.0.min.js`,
      },
    },
  ],
};

内容的提问来源于stack exchange,提问作者chrismacp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:13:59