Skip to content

Commit b3713df

Browse files
committed
fix: dynamically import chart.js to avoid SSR failure
Chart.js requires browser APIs and was failing during SSR when imported at module level. Move import inside onMount.
1 parent d261d00 commit b3713df

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Chart.js SSR Failure
2+
3+
**Keywords**: chart.js, blank page, nothing renders, empty page, white screen
4+
5+
**Symptom**: Page using Chart.js renders blank/nothing.
6+
7+
**Cause**: Chart.js requires browser APIs (`window`, `canvas`, etc.) and fails when imported at module level during SSR.
8+
9+
**Solution**: Dynamically import Chart.js inside `onMount`:
10+
11+
```svelte
12+
<script lang="ts">
13+
import { onDestroy, onMount } from "svelte";
14+
import type { Chart as ChartType } from "chart.js";
15+
16+
let chart: ChartType | null = null;
17+
18+
onDestroy(() => chart?.destroy());
19+
20+
onMount(async () => {
21+
const { Chart, LineController, ... } = await import("chart.js");
22+
Chart.register(LineController, ...);
23+
// create chart
24+
});
25+
</script>
26+
```

CLAUDE.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
{Main work}
66
{Run bun tidy / it muts return 0 warnings and errors}
77
{Update knowledge database and CLAUDE.md as needed}
8+
{Log troubleshooting to .claude/troubleshooting/ if applicable}
89
</workflow>
910

1011
# Knowledge Database
@@ -15,6 +16,16 @@ ALWAYS read relevant knowledges before you start working.
1516
ls ./docs/knowledges
1617
```
1718

19+
# Troubleshooting
20+
21+
When fixing non-obvious bugs, log the issue to `.claude/troubleshooting/` for future reference.
22+
23+
Each file should include: **Keywords** (symptom-focused for greppability), **Symptom**, **Cause**, **Solution**.
24+
25+
```sh
26+
ls .claude/troubleshooting
27+
```
28+
1829
# Available Tools
1930

2031
- core: Svelte v5 + Remote Functions + Async

src/lib/components/analytics/ViewTrendChart.svelte

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,6 @@
11
<script lang="ts">
2-
import { onMount } from "svelte";
3-
import {
4-
Chart,
5-
LineController,
6-
LineElement,
7-
PointElement,
8-
LinearScale,
9-
CategoryScale,
10-
Title,
11-
Tooltip,
12-
Legend,
13-
Filler,
14-
} from "chart.js";
15-
16-
Chart.register(
17-
LineController,
18-
LineElement,
19-
PointElement,
20-
LinearScale,
21-
CategoryScale,
22-
Title,
23-
Tooltip,
24-
Legend,
25-
Filler,
26-
);
2+
import { onDestroy, onMount } from "svelte";
3+
import type { Chart as ChartType } from "chart.js";
274
285
interface Props {
296
data: Array<{ date: string; count: number }>;
@@ -34,9 +11,36 @@
3411
const { data, title = "View Trend", color = "#00D372" }: Props = $props();
3512
3613
let canvas: HTMLCanvasElement;
37-
let chart: Chart | null = null;
14+
let chart: ChartType | null = null;
15+
16+
onDestroy(() => chart?.destroy());
17+
18+
onMount(async () => {
19+
const {
20+
Chart,
21+
LineController,
22+
LineElement,
23+
PointElement,
24+
LinearScale,
25+
CategoryScale,
26+
Title,
27+
Tooltip,
28+
Legend,
29+
Filler,
30+
} = await import("chart.js");
31+
32+
Chart.register(
33+
LineController,
34+
LineElement,
35+
PointElement,
36+
LinearScale,
37+
CategoryScale,
38+
Title,
39+
Tooltip,
40+
Legend,
41+
Filler,
42+
);
3843
39-
onMount(() => {
4044
const ctx = canvas.getContext("2d");
4145
if (!ctx) return;
4246
@@ -152,10 +156,6 @@
152156
},
153157
},
154158
});
155-
156-
return () => {
157-
chart?.destroy();
158-
};
159159
});
160160
</script>
161161

0 commit comments

Comments
 (0)