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

使用MDSvex在Svelte 4中渲染Git仓库Markdown代码块异常

问题:Svelte 4 + mdsvex 代码块渲染异常

在Svelte 4博客应用中,使用mdsvex渲染从Git仓库拉取的Markdown文章时,大部分内容显示正常,但```格式的代码块出现异常,被包裹在{@html }`文本中,无法还原Obsidian编写的原始代码块样式。

相关代码文件

package.json

{
  "name": "planet-oxy",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "dev": "vite dev --port 8008",
    "launch": "vite dev --port 8008 --open",
    "build": "vite build",
    "preview": "vite preview",
    "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
    "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
    "lint": "eslint .",
    "init:houdini": "npx houdini@latest init",
    "generate:houdini": "npx houdini generate",
    "pull:houdini": "npx houdini pull-schema"
  },
  "devDependencies": {
    "@sveltejs/adapter-auto": "^3.3.1",
    "@sveltejs/adapter-netlify": "^4.3.1",
    "@sveltejs/kit": "^2.5.27",
    "@sveltejs/vite-plugin-svelte": "^4.0.0",
    "@types/eslint": "^8.56.7",
    "autoprefixer": "^10.4.19",
    "eslint": "^9.0.0",
    "eslint-plugin-svelte": "^2.45.1",
    "globals": "^15.0.0",
    "houdini": "^1.5.4",
    "houdini-svelte": "^2.1.8",
    "mdsvex": "^0.12.6",
    "prettier": "^3.6.2",
    "prettier-plugin-svelte": "^3.4.0",
    "prettier-plugin-tailwindcss": "^0.6.14",
    "svelte": "^5.0.0",
    "svelte-check": "^4.0.0",
    "tailwindcss": "^4.0.6",
    "tslib": "^2.4.1",
    "typescript": "^5.5.0",
    "typescript-eslint": "^8.0.0-alpha.20",
    "vite": "^5.4.4"
  },
  "type": "module",
  "dependencies": {
    "@sanity/client": "^6.22.4",
    "@tailwindcss/vite": "^4.0.6"
  }
}

svelte.config.js

import { mdsvex } from 'mdsvex';
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const msdsvexOpt = {
    extensions: ['.md']
}

/** @type {import('@sveltejs/kit').Config} */
const config = {
    extensions: ['.svelte', '.svx','.md'],
    preprocess: [vitePreprocess(), mdsvex(msdsvexOpt)],
    kit: {
        adapter: adapter({
            edge: false,
            split: false
        }),
        alias: { $houdini: ".houdini/" }
    },
};

export default config;

+page.ts

import { PUBLIC_BLOG_URL } from '$env/static/public';
import type { TPostMeta } from '$lib/types/post/TPost.type.js';
import { error } from '@sveltejs/kit';
import { compile } from 'mdsvex';

export async function load({ params }) {
    try {
        const url = `${PUBLIC_BLOG_URL}/refs/heads/master/${params.article}.md`

        const res = await fetch(url);
        const post = await res.text();

        const response = await compile(post, {
            extensions: ['.md'],
            filename: `${params.article}.md`
        })

        if (!response) {
            throw new Error(`Could not fetch ${params.article}`);
        }

        const content = response.code
        const meta = (response.data as any).fm;

        return {
            metadata: meta satisfies TPostMeta,
            content,
            map: response.map
        }
    } catch (e) {
        error(404, `Could not find ${params.article}`)
    }
}

+page.svelte

<section class="container m-auto px-48">
  {#if data.content && data.metadata}
    <article>
      <hgroup
        class="flex flex-col relative bottom-7 md:bottom-12 lg:bottom-8 gap-y-1"
      >
        <h1
          class="bg-dh-black w-fit font-hanuman font-extrabold text-dh-orange text-[1.5em] md:text-6xl text-wrap lg:text-nowrap p-4 pb-0"
        >
          {data.metadata.title}
        </h1>
        <p>{new Date(data.metadata.date).toISOString().split("T")[0]}</p>

        <div
          class="tags flex letter--spacing--md font-quirkyrobot text-dh-orange text-[.9em] !gap-x-3"
        >
          {#each data.metadata.tags as tag}
            <span class="surface-4">&num;{tag}</span>
          {/each}
        </div>
      </hgroup>

      <div class="prose flex flex-col gap-y-6">
        {@html data.content}
      </div>
    </article>
  {/if}
</section>

源Markdown内容

## Usage  

To add a task: 

```bash 
python tasktracker.py add "Write blog post"

To view tasks:

python tasktracker.py list 
## 渲染异常截图
![渲染异常的代码块](https://i.sstatic.net/ykaMBSA0.png)

---

# 解决方案
### 1. 核心问题分析
当前使用`compile`方法生成的是**Svelte组件代码**,而非纯HTML,直接用`{@html}`渲染会把Svelte的语法(如`{@html ...}`)当成文本输出,导致代码块显示异常。

### 2. 修改代码:改用`render`生成纯HTML
将`+page.ts`中的`compile`替换为`mdsvex`的`render`方法,直接生成可渲染的HTML内容:

```ts
// +page.ts
import { PUBLIC_BLOG_URL } from '$env/static/public';
import type { TPostMeta } from '$lib/types/post/TPost.type.js';
import { error } from '@sveltejs/kit';
// 替换compile为render
import { render } from 'mdsvex';

export async function load({ params }) {
    try {
        const url = `${PUBLIC_BLOG_URL}/refs/heads/master/${params.article}.md`;
        const res = await fetch(url);
        const post = await res.text();

        // 使用render生成纯HTML和元数据
        const { html, data } = await render(post, {
            extensions: ['.md'],
            filename: `${params.article}.md`
        });

        if (!html) {
            throw new Error(`Could not render ${params.article}`);
        }

        const meta = data.fm;

        return {
            metadata: meta satisfies TPostMeta,
            content: html
        };
    } catch (e) {
        error(404, `Could not find ${params.article}`);
    }
}

3. (可选)添加代码高亮

如果需要代码高亮效果,安装prismjs并引入样式:

  1. 安装依赖:
npm install prismjs
  1. 在根布局+layout.svelte中引入样式:
<script>
    import 'prismjs/themes/prism-tomorrow.css';
</script>

4. 验证效果

重新运行项目,代码块会被渲染为标准的<pre><code>结构,还原Obsidian中的原始样式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 01:40:57