Replies: 1 comment
|
Hey, I think I can help break this down. Why your old approach broke Svelte 5 changed how This is documented in the Svelte 5 migration guide and confirmed in sveltejs/svelte#12333. Why your preprocessor gives 500 errors with no stack traces Most likely one of these:
Here's the correct structure: function myMarkdownPreprocessor() {
return {
name: 'my-markdown',
async markup({ content, filename }) {
if (!filename?.endsWith('.md')) return; // skip non-markdown
try {
const transformed = await transformMarkdown(content);
return { code: transformed }; // must be { code: string }
} catch (e) {
console.error(`Preprocessor error in ${filename}:`, e);
throw e; // re-throw so you actually see the error
}
}
};
}Also, preprocessor changes need a Vite dev server restart to take effect. The actual fix for your chart rendering The cleanest approach is to use mdsvex and put your charts in a Svelte component. In your <script>
import Chart from '$lib/Chart.svelte';
</script>
# My Blog Post
<Chart data={[1, 2, 3, 4]} />Then in <script>
import { onMount } from 'svelte';
let { data } = $props();
let canvasEl;
onMount(() => {
const chart = new Chart(canvasEl, {
type: 'bar',
data: { datasets: [{ data }] }
});
return () => chart.destroy();
});
</script>
<canvas bind:this={canvasEl}></canvas>This works because the If you don't want to use mdsvex, the other option is a hydration flag: <script>
import { onMount } from 'svelte';
let hydrated = $state(false);
onMount(() => { hydrated = true; });
</script>
{#if hydrated}
<canvas bind:this={canvasEl}></canvas>
{/if}Server renders nothing for the chart slot, client renders it after mount. Both agree on initial state so no mismatch. |
Uh oh!
There was an error while loading. Please reload this page.
I've been trying to dig around to figure out how preprocessors work. So far the most functional code I've written can only scrape the contents of the svelte files, but I've had no luck successfully modifying any content without generating 500 errors with 0 zero feedback, no stack traces whatsoever.
I figure it's worth an in-depth tutorial somewhere more prominent. Because being able to transform documents is now much more critical because of the new default handling of hydration errors.
Here's the concept, I have markdown files for blog posts. Part of those posts include code blocks (which include data for graphs! and other cool things) copy/pasted directly from profiling runs and other places. The data is otherwise completely arbitrary and otherwise realistically just text that just doesn't quite yet "look good". In an earlier version of sveltekit it was completely fine to process the markdown. Then turn those sections of text into
.jsonfiles and then render the charts by inserting<canvas>elements into the document client-side and letting something like chartjs handle the rest. All within code sitting under/src...With the more recent versions of sveltekit, what was once trivial to handle after server side rendering on the client EG: the
<canvas>element is now a hydration error. Which produces a rather annoying side effect of flashing the content you expect for a fraction of a second, and you're sat frustrated that you're now fighting sveltekit that was so helpful before.So now, to play nice it would be far easier to "pre" process everything. There is a comment floating around the documentation about this problem. Essentially saying to turn what once were server-side renderable into dynamic routes or something like that so that svelte doesn't yell about structural issues.
My suspicion is that I'm not returning what svelte kit expects from a preprocessor function and a utility script which is supposed to provide frontmatter data is failing with the 500 error. But I'd like to start fresh and see if anyone else can explain how this works from scratch.
All reactions