diff --git a/.changeset/thin-houses-flash.md b/.changeset/thin-houses-flash.md
new file mode 100644
index 000000000..f9e4e236c
--- /dev/null
+++ b/.changeset/thin-houses-flash.md
@@ -0,0 +1,5 @@
+---
+"@rspress/theme-default": patch
+---
+
+fix: avoid flash of navbar images (logo and theme icon)
diff --git a/packages/theme-default/src/components/Nav/NavBarTitle.tsx b/packages/theme-default/src/components/Nav/NavBarTitle.tsx
index faeeb8ceb..fe5dff1f0 100644
--- a/packages/theme-default/src/components/Nav/NavBarTitle.tsx
+++ b/packages/theme-default/src/components/Nav/NavBarTitle.tsx
@@ -1,27 +1,44 @@
-import { useContext, useEffect, useState } from 'react';
-import {
- ThemeContext,
- normalizeImagePath,
- usePageData,
- withBase,
-} from '@rspress/runtime';
+import { useMemo } from 'react';
+import { normalizeImagePath, usePageData, withBase } from '@rspress/runtime';
import styles from './index.module.scss';
-import { getLogoUrl, useLocaleSiteData } from '../../logic';
+import { useLocaleSiteData } from '../../logic';
export const NavBarTitle = () => {
const { siteData } = usePageData();
const localeData = useLocaleSiteData();
const { logo: rawLogo, logoText } = siteData;
const title = localeData.title ?? siteData.title;
- const { theme } = useContext(ThemeContext);
- const [logo, setLogo] = useState(getLogoUrl(rawLogo, theme));
- const [logoVisible, setLogoVisible] = useState(false);
-
- useEffect(() => {
- setLogoVisible(true);
- const newLogoUrl = getLogoUrl(rawLogo, theme);
- setLogo(newLogoUrl);
- }, [theme, rawLogo]);
+ const logo = useMemo(() => {
+ if (!rawLogo) {
+ return null;
+ }
+ if (typeof rawLogo === 'string') {
+ return (
+
+ );
+ }
+ return (
+ <>
+
+
+ >
+ );
+ }, [rawLogo]);
return (
@@ -29,14 +46,7 @@ export const NavBarTitle = () => {
href={withBase(localeData.langRoutePrefix || '/')}
className="flex items-center w-full h-full text-base font-semibold transition-opacity duration-300 hover:opacity-60"
>
- {logo && logoVisible && (
-
- )}
+ {logo}
{logoText &&
{logoText}}
{!logo && !logoText &&
{title}}
diff --git a/packages/theme-default/src/components/SwitchAppearance/index.tsx b/packages/theme-default/src/components/SwitchAppearance/index.tsx
index de766d536..b3386873c 100644
--- a/packages/theme-default/src/components/SwitchAppearance/index.tsx
+++ b/packages/theme-default/src/components/SwitchAppearance/index.tsx
@@ -16,7 +16,6 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) {
const isDark = updateUserPreferenceFromStorage();
setTheme(isDark ? 'dark' : 'light');
};
- const [iconVisible, setIconVisible] = useState(false);
useEffect(() => {
if (isDarkMode()) {
@@ -25,7 +24,6 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) {
if (typeof window !== 'undefined') {
window.addEventListener('storage', updateAppearanceAndTheme);
}
- setIconVisible(true);
return () => {
if (typeof window !== 'undefined') {
window.removeEventListener('storage', updateAppearanceAndTheme);
@@ -43,14 +41,20 @@ export function SwitchAppearance({ onClick }: { onClick?: () => void }) {
className="md:mr-2 rspress-nav-appearance"
>
- {iconVisible && (
-
- )}
+
+
);
diff --git a/packages/theme-default/src/logic/utils.ts b/packages/theme-default/src/logic/utils.ts
index 7c052fd8b..09fa296ba 100644
--- a/packages/theme-default/src/logic/utils.ts
+++ b/packages/theme-default/src/logic/utils.ts
@@ -22,18 +22,6 @@ export function isActive(
);
}
-export function getLogoUrl(
- rawLogo: string | { dark: string; light: string },
- theme: 'dark' | 'light',
-) {
- // If logo is a string, use it directly
- if (typeof rawLogo === 'string') {
- return rawLogo;
- }
- // If logo is an object, use dark/light mode logo
- return theme === 'dark' ? rawLogo.dark : rawLogo.light;
-}
-
export function isMobileDevice() {
return window.innerWidth <= 1024;
}