LogoMkSaaS文档

主题

学习如何自定义您的 MkSaaS 网站中的主题

本文档涵盖了您的 MkSaaS 网站中的主题系统,如何在内置主题之间切换,以及如何创建和自定义您自己的主题。

核心功能

MkSaaS 模板配备了内置主题系统,允许用户自定义网站的外观。主题系统包括:

  • 明暗模式支持
  • 多种颜色主题(默认、中性、蓝色、绿色、琥珀色)
  • 用户主题切换功能
  • 使用 cookie 的主题持久化

内置主题

模板包含几个预配置的主题,您可以开箱即用。

可用主题

默认情况下可用以下主题:

  • 默认:具有平衡色彩调色板的主要主题
  • 中性:具有中性色彩的灰度主题
  • 蓝色:以蓝色为主色调的主题
  • 绿色:以绿色为主色调的主题
  • 琥珀色:以琥珀色为主色调的主题

每个主题都会更改主色调和相关颜色,同时保持整体设计系统。

主题配置

主题系统在 website.tsx 配置文件中配置。

src/config/website.tsx
export const websiteConfig: WebsiteConfig = {
  metadata: {
    theme: {
      defaultTheme: 'default', // 选择:default、blue、green、amber、neutral
      enableSwitch: true,      // 启用/禁用主题切换
    },
    // ...其他配置
  },
  // ...其余配置
};

配置选项:

属性类型描述
defaultTheme'default' | 'blue' | 'green' | 'amber' | 'neutral'设置网站的默认颜色主题
enableSwitchboolean为真时,允许用户更改颜色主题

主题切换的工作原理

主题切换功能通过几个关键组件实现:

1. 主题提供者

src/components/layout/active-theme-provider.tsx 中的 ActiveThemeProvider 组件管理当前主题状态并使用 cookie 持久化:

src/components/layout/active-theme-provider.tsx
// ActiveThemeProvider 的关键功能
export function ActiveThemeProvider({
  children,
  initialTheme,
}: {
  children: ReactNode;
  initialTheme?: string;
}) {
  const [activeTheme, setActiveTheme] = useState<string>(
    () => initialTheme || DEFAULT_THEME
  );

  useEffect(() => {
    // 将主题保存到 cookie
    setThemeCookie(activeTheme);

    // 将主题类应用到 body
    Array.from(document.body.classList)
      .filter((className) => className.startsWith('theme-'))
      .forEach((className) => {
        document.body.classList.remove(className);
      });
    document.body.classList.add(`theme-${activeTheme}`);
  }, [activeTheme]);

  // ...组件的其余部分
}

2. 主题选择器组件

src/components/layout/theme-selector.tsx 中的 ThemeSelector 组件为用户提供在主题之间切换的 UI 组件:

src/components/layout/theme-selector.tsx
export function ThemeSelector() {
  if (!websiteConfig.metadata.theme?.enableSwitch) {
    return null;
  }

  const { activeTheme, setActiveTheme } = useThemeConfig();
  const t = useTranslations('Common.theme');

  // 主题选项
  const DEFAULT_THEMES = [
    {
      name: t('default'),
      value: 'default',
    },
    // ...其他主题
  ];

  // ...组件渲染
}

3. CSS 实现

主题在全局 CSS 文件(src/styles/globals.css)中使用 CSS 变量和 Tailwind CSS 定义:

src/styles/globals.css
/* 在 :root 中定义的基础主题变量 */
:root {
  --radius: 0.5rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.141 0.005 285.823);
  /* ...其他变量 */
}

/* 暗黑模式覆盖 */
.dark {
  --background: oklch(0.141 0.005 285.823);
  --foreground: oklch(0.985 0 0);
  /* ...其他变量 */
}

/* 主题特定覆盖 */
.theme-default {
  /* 默认主题 */
}

.theme-neutral {
  --primary: var(--color-neutral-600);
  --primary-foreground: var(--color-neutral-50);

  @variant dark {
    --primary: var(--color-neutral-500);
    --primary-foreground: var(--color-neutral-50);
  }
}

/* ...其他主题 */

创建自定义主题

您可以通过向全局 CSS 文件添加新主题定义来创建自己的自定义主题。

1. 添加新主题类

src/styles/globals.css 添加新主题类:

src/styles/globals.css
.theme-custom {
  --primary: var(--color-purple-600);
  --primary-foreground: var(--color-purple-50);

  @variant dark {
    --primary: var(--color-purple-500);
    --primary-foreground: var(--color-purple-50);
  }
}

2. 将主题添加到选择器

修改 src/components/layout/theme-selector.tsx 中的 ThemeSelector 组件以包含您的新主题:

src/components/layout/theme-selector.tsx
const DEFAULT_THEMES = [
  {
    name: t('default'),
    value: 'default',
  },
  // ...现有主题
  {
    name: t('custom'),
    value: 'custom',
  },
];

3. 添加翻译键

在您的翻译文件中为您的主题添加新的翻译键。

{
  "Common": {
    "theme": {
      "custom": "Custom Theme"
    }
  }
}
{
  "Common": {
    "theme": {
      "custom": "自定义主题"
    }
  }
}

高级自定义主题

对于更高级的主题自定义,您可以修改基础主题变量。

自定义基础主题

基础主题变量在 src/styles/globals.css:root 选择器中定义。您可以修改这些变量来更改所有主题的默认外观:

src/styles/globals.css
:root {
  --radius: 0.5rem;
  --background: oklch(1 0 0);
  --foreground: oklch(0.141 0.005 285.823);
  /* 根据需要修改其他变量 */
}

.dark {
  --background: oklch(0.141 0.005 285.823);
  --foreground: oklch(0.985 0 0);
  /* 根据需要修改暗黑模式变量 */
}

创建自定义调色板

您可以通过在主题类中覆盖所有颜色变量来创建完全自定义的调色板:

src/styles/globals.css
.theme-custom {
  --background: oklch(0.98 0.01 280);
  --foreground: oklch(0.2 0.01 280);
  --card: oklch(0.97 0.01 280);
  --card-foreground: oklch(0.2 0.01 280);
  /* 覆盖所有其他颜色变量 */
}

主题生成器

您可以使用以下主题生成器创建自己的自定义主题,然后将 CSS 变量复制到您的 globals.css 文件中,或运行如下命令来更改您的 globals.css 文件:

pnpm dlx shadcn@latest add https://tweakcn.com/r/themes/twitter.json

视频教程:

下图显示默认的主题现在变成自定义主题。

自定义主题

故障排除

主题没有正确应用

如果您的主题没有正确应用:

  1. 检查主题类是否在 globals.css 中正确定义
  2. 验证主题选择器是否在网站配置中启用
  3. 检查浏览器控制台是否有任何 JavaScript 错误
  4. 清除浏览器 cookie 并重新加载页面

页面加载时自定义主题闪烁

如果您在自定义主题加载前看到默认主题的闪烁:

  1. website.tsx 中将您的自定义主题设置为默认主题
  2. 在主题加载时使用加载状态或骨架 UI
  3. 考虑为初始主题实现服务器端渲染

对于服务器端渲染,修改您的布局组件以将来自 cookie 的初始主题传递给 ActiveThemeProvider

最佳实践

  • 颜色对比:确保文本颜色与背景颜色有足够的对比度以便于访问
  • 测试两种模式:始终在明暗两种模式下测试您的主题
  • 限制主题选项:提供少量精心设计的主题,而不是许多相似的选项
  • 主题一致性:在不同主题之间保持一致的样式,以避免 UI 意外

视频教程

下一步

现在您了解了如何在 MkSaaS 中使用主题,探索这些相关主题: