Skip to content

Commit b9ee6f9

Browse files
committed
fix(theme): resolve hydration mismatch in code block component
Add mounted state check to prevent theme mismatch during hydration Use resolvedTheme instead of applicationTheme for consistent theming Remove hardcoded background color in favor of CSS variables
1 parent 37f5be1 commit b9ee6f9

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

app/(site)/layout.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ export default function SiteLayout({
1313
}: Readonly<{
1414
children: React.ReactNode;
1515
}>) {
16-
const { resolvedTheme } = useTheme(); // Suppression de theme non utilisé
16+
const { resolvedTheme, theme } = useTheme(); // Suppression de theme non utilisé
1717
const [mounted, setMounted] = React.useState(false);
1818

19+
console.log(theme);
20+
21+
1922
React.useEffect(() => {
2023
setMounted(true);
2124
}, []);

components/ui/code-block.tsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,16 @@ export function CodeBlock({
4646
maxVisibleLines = 10,
4747
defaultExpanded = false,
4848
}: CodeBlockProps) {
49-
const { theme: applicationTheme } = useTheme();
49+
const { theme: applicationTheme, resolvedTheme } = useTheme();
5050
const [copied, setCopied] = React.useState(false);
5151
const [localActiveTab, setLocalActiveTab] = React.useState<string | undefined>(activeTab || (tabs && tabs.length > 0 ? tabs[0].value : undefined));
5252
const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);
53+
const [mounted, setMounted] = React.useState(false);
54+
55+
// Fix hydration issues with next-themes
56+
React.useEffect(() => {
57+
setMounted(true);
58+
}, []);
5359

5460
const handleCopy = () => {
5561
const textToCopy = tabs && localActiveTab
@@ -110,7 +116,7 @@ export function CodeBlock({
110116
case 'shell':
111117
return (
112118
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor">
113-
<path d="M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2m0 2v14h14V5H5m2 2h2v2H7V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7M7 10h2v2H7v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2M7 13h2v2H7v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2M7 16h2v2H7v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2" />
119+
<path d="M5 3h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2m0 2v14h14V5H5m2 2h2v2H7V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7m3 0h2v2h-2V7M7 10h2v2H7v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2M7 16h2v2H7v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2m3 0h2v2h-2v-2" />
114120
</svg>
115121
);
116122
case 'css':
@@ -212,7 +218,32 @@ export function CodeBlock({
212218
]
213219
};
214220

215-
const theme = applicationTheme === "dark" ? customDarkTheme : themes.github;
221+
const theme = resolvedTheme === "dark" ? customDarkTheme : themes.github;
222+
223+
// Don't render until mounted to avoid hydration mismatch
224+
if (!mounted) {
225+
return (
226+
<div className={cn("relative group rounded-md overflow-hidden border border-border", className)}>
227+
{showHeader && (
228+
<div className="flex items-center justify-between border-b border-border bg-muted/50 px-4 py-2">
229+
<div className="flex items-center gap-2">
230+
{headerPrefix}
231+
{getLanguageIcon(activeLanguage)}
232+
{title && <div className="text-sm font-medium">{title}</div>}
233+
</div>
234+
<div className="rounded-md p-1">
235+
<Copy className="h-4 w-4" />
236+
</div>
237+
</div>
238+
)}
239+
<div className="relative">
240+
<pre className="text-sm p-4 overflow-x-auto bg-muted">
241+
<code>{displayedCode.trim()}</code>
242+
</pre>
243+
</div>
244+
</div>
245+
);
246+
}
216247

217248
return (
218249
<div className={cn("relative group rounded-md overflow-hidden border border-border", className)}>
@@ -310,7 +341,8 @@ export function CodeBlock({
310341
)}
311342
style={{
312343
...style,
313-
backgroundColor: applicationTheme === "dark" ? "#1a1a1a" : style.backgroundColor,
344+
// Remove hardcoded background, let CSS variables handle it
345+
backgroundColor: undefined,
314346
}}
315347
>
316348
{tokens.map((line, i) => {

0 commit comments

Comments
 (0)