0

I am trying to render markdown posts fetched from a git repo in my Svelte 4 webapp/blog using mdsvex.

The markdown mostly renders correctly, but the ``` code blocks dont render corerctly.

The codeblocks seem to render wrapped in {@html ` blocks as if the text was sanitised before rendering.

I wrote the markdown in obsidian, I'd like to replicate the look at feel of it

//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>

source markdown:

## Usage  

To add a task: 

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

To view tasks: 

```bash
python tasktracker.py list 
```

Result:

Rendered markdown

1 Answer 1

0

The docs says:

The compile option will transform valid mdsvex code into valid svelte code[...]

Therefor you can't really use {@html ...} to render the result, since @html can only handle HTML code, and not Svelte code.

But, you should be able to use get around this specific problem by setting highlight.optimise to false:

You can now pass highlight.optimise: false to remove the @html optimisation.

mdsvex is a preprocessor/ compiler though. So to create a Svelte component you will also need to turn it into a real module that can be imported and rendered by the Svelte compiler. That isn't the responsibility of mdsvex.

https://github.com/pngwn/MDsveX/issues/697

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.