Astro中使用rehype-inline-svg遇路径错误及Excalidraw SVG字体内嵌方案
解决Astro博客中内联SVG(含Excalidraw字体)的问题
问题根源
rehype-inline-svg默认从项目根目录查找文件,但你用引用的SVG实际存在于Astro的public目录下(Astro会把public目录的资源映射到网站根路径),插件找不到正确的文件位置,所以抛出ENOENT错误。
解决方案1:配置rehype-inline-svg的正确路径
修改Astro配置,给插件传入baseDir参数,指定SVG文件的实际存放目录(即项目根下的public文件夹):
import { defineConfig } from 'astro/config'; import inlineSVG from '@jsdevtools/rehype-inline-svg'; export default defineConfig({ markdown: { rehypePlugins: [ [inlineSVG, { baseDir: './public', // 指向public目录,匹配你的SVG实际路径 removeSVGTagAttrs: false, // 保留SVG原有属性,避免影响字体和样式 }] ], }, });
配置后,插件就能正确找到public/assets/images/image-1.svg,并自动将Markdown中的图片引用替换为内联SVG。
解决方案2:自定义Astro组件实现内联(更灵活)
如果插件方案仍有问题,可以自定义组件手动处理SVG内联,同时更好控制字体渲染:
- 在
src/components/SvgInline.astro创建组件:
--- import fs from 'fs'; import path from 'path'; export interface Props { src: string; // 传入相对public的路径,比如'/assets/images/image-1.svg' } const { src } = Astro.props; // 拼接出本地文件路径,去掉src开头的斜杠 const filePath = path.join(process.cwd(), 'public', src.slice(1)); const svgContent = fs.readFileSync(filePath, 'utf8'); --- <!-- 直接输出SVG内容实现内联 --> <div set:html={svgContent}></div>
- 在Markdown文章中引用组件(Astro默认已启用Markdown组件支持):
--- title: 我的文章 --- <SvgInline src="/assets/images/image-1.svg" />
Excalidraw SVG字体显示注意事项
- 导出Excalidraw SVG时,选择嵌入字体选项,这样内联后字体无需额外加载就能显示
- 如果是引用外部字体,在项目全局样式中通过
@font-face声明对应字体,确保SVG能调用到
内容的提问来源于stack exchange,提问作者tvandinther
相关产品推荐
相关产品推荐

