Skip to content

Commit d4e7c9c

Browse files
committed
fix: render single theme-appropriate image instead of showing both dark and light
SSR was rendering both dark and light img tags, relying on CSS class toggling to hide one. Before stylesheet load, both images were visible. Replace with a ThemeImage component that uses VitePress isDark reactive state to render only one img with the correct src.
1 parent 1e6bfc2 commit d4e7c9c

3 files changed

Lines changed: 24 additions & 5 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<script setup lang="ts">
2+
import { useData } from 'vitepress'
3+
4+
const { isDark } = useData()
5+
6+
defineProps<{
7+
dark: string
8+
light: string
9+
alt?: string
10+
}>()
11+
</script>
12+
13+
<template>
14+
<img
15+
:src="isDark ? dark : light"
16+
:alt="alt ?? ''"
17+
style="border-radius: 8px; border: 1px solid var(--vp-c-divider);"
18+
/>
19+
</template>

.vitepress/theme/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import './custom.css';
33
import posthog from 'posthog-js';
44
import { h } from 'vue';
55
import AnimatedHero from './components/AnimatedHero.vue';
6+
import ThemeImage from './components/ThemeImage.vue';
67

78
export default {
89
extends: DefaultTheme,
@@ -11,7 +12,8 @@ export default {
1112
'home-hero-before': () => h(AnimatedHero),
1213
});
1314
},
14-
enhanceApp({ router }) {
15+
enhanceApp({ app, router }) {
16+
app.component('ThemeImage', ThemeImage);
1517
if (typeof window !== 'undefined') {
1618
// Prevent font swap jank: hide body until Barlow is loaded
1719
document.fonts.ready.then(() => {

docs/guides/see-it.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,11 @@ Narrative-Driven Development is a model-based approach. The same specification r
1919

2020
**The Visual View** (for designers and product teams):
2121

22-
<img class="only-dark" src="/visual-canvas-dark.png" alt="User journey map showing the gym membership narrative as a visual timeline with moments, interfaces, and system actions" style="border-radius: 8px; border: 1px solid var(--vp-c-divider);">
23-
<img class="only-light" src="/visual-canvas-light.png" alt="User journey map showing the gym membership narrative as a visual timeline with moments, interfaces, and system actions" style="border-radius: 8px; border: 1px solid var(--vp-c-divider);">
22+
<ThemeImage dark="/visual-canvas-dark.png" light="/visual-canvas-light.png" alt="User journey map showing the gym membership narrative as a visual timeline with moments, interfaces, and system actions" />
2423

2524
**The Document View** (for PMs, QA, and stakeholders):
2625

27-
<img class="only-dark" src="/structured-doc-dark.png" alt="Structured document showing the gym membership narrative as readable specifications with business rules, acceptance criteria, and edge cases" style="border-radius: 8px; border: 1px solid var(--vp-c-divider);">
28-
<img class="only-light" src="/structured-doc-light.png" alt="Structured document showing the gym membership narrative as readable specifications with business rules, acceptance criteria, and edge cases" style="border-radius: 8px; border: 1px solid var(--vp-c-divider);">
26+
<ThemeImage dark="/structured-doc-dark.png" light="/structured-doc-light.png" alt="Structured document showing the gym membership narrative as readable specifications with business rules, acceptance criteria, and edge cases" />
2927

3028
**The Code View** (for developers):
3129

0 commit comments

Comments
 (0)